See ChangeLog

Monotone-Parent: 0400894ebb0d9305dae91e6efb9e8a62a36e6d5b
Monotone-Revision: 814be30289e980e05d1340e3dc8d3bad9155344d

Monotone-Author: ludovic@Sophos.ca
Monotone-Date: 2008-11-18T00:06:37
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Ludovic Marcotte
2008-11-18 00:06:37 +00:00
parent 85c9c6e402
commit 3539a06f83
24 changed files with 569 additions and 73 deletions

View File

@@ -1,3 +1,13 @@
2008-11-17 Ludovic Marcotte <lmarcotte@inverse.ca>
* Added back the appointment update notification
templates from RC8 and updated them.
* SoObjects/Appointments/SOGoAppointmentFolder.m
Greatly improved the speed of getetag calls
* SoObjects/SOGo/SOGoGCSFolder.m
We now allow multiple users subscribe/unsubscribe
requests during one DAV call.
2008-11-13 Ludovic Marcotte <lmarcotte@inverse.ca>
* SoObjects/Appointments/SOGoAppointmentObject.m

View File

@@ -32,6 +32,7 @@ Appointments_OBJC_FILES = \
SOGoAptMailInvitation.m \
SOGoAptMailDeletion.m \
SOGoAptMailICalReply.m \
SOGoAptMailUpdate.m \
Appointments_RESOURCE_FILES += \
Version \
@@ -45,21 +46,27 @@ Appointments_COMPONENTS += \
SOGoAptMailDutchInvitation.wo \
SOGoAptMailDutchICalReply.wo \
SOGoAptMailDutchDeletion.wo \
SOGoAptMailDutchUpdate.wo \
SOGoAptMailEnglishInvitation.wo \
SOGoAptMailEnglishICalReply.wo \
SOGoAptMailEnglishDeletion.wo \
SOGoAptMailEnglishUpdate.wo \
SOGoAptMailFrenchInvitation.wo \
SOGoAptMailFrenchICalReply.wo \
SOGoAptMailFrenchDeletion.wo \
SOGoAptMailFrenchUpdate.wo \
SOGoAptMailGermanInvitation.wo \
SOGoAptMailGermanICalReply.wo \
SOGoAptMailGermanDeletion.wo \
SOGoAptMailGermanUpdate.wo \
SOGoAptMailItalianInvitation.wo \
SOGoAptMailItalianICalReply.wo \
SOGoAptMailItalianDeletion.wo \
SOGoAptMailItalianUpdate.wo \
SOGoAptMailSpanishInvitation.wo \
SOGoAptMailSpanishICalReply.wo \
SOGoAptMailSpanishDeletion.wo \
SOGoAptMailSpanishUpdate.wo \
ADDITIONAL_INCLUDE_DIRS += -I../../SOPE/

View File

@@ -1005,19 +1005,19 @@ static Class sogoAppointmentFolderKlass = Nil;
}
- (void) _appendPropstat: (NSDictionary *) propstat
toResponse: (WOResponse *) r
toBuffer: (NSMutableString *) r
{
NSArray *properties;
unsigned int count, max;
[r appendContentString: @"<D:propstat><D:prop>"];
[r appendString: @"<D:propstat><D:prop>"];
properties = [propstat objectForKey: @"properties"];
max = [properties count];
for (count = 0; count < max; count++)
[r appendContentString: [properties objectAtIndex: count]];
[r appendContentString: @"</D:prop><D:status>"];
[r appendContentString: [propstat objectForKey: @"status"]];
[r appendContentString: @"</D:status></D:propstat>"];
[r appendString: [properties objectAtIndex: count]];
[r appendString: @"</D:prop><D:status>"];
[r appendString: [propstat objectForKey: @"status"]];
[r appendString: @"</D:status></D:propstat>"];
}
#warning we should use the EOFetchSpecification for that!!! (see doPROPFIND:)
@@ -1062,11 +1062,12 @@ static Class sogoAppointmentFolderKlass = Nil;
- (NSString **) _properties: (NSString **) properties
ofObject: (NSDictionary *) object
{
SOGoCalendarComponent *sogoObject;
NSString **currentProperty;
NSString **values, **currentValue;
SOGoObject *sogoObject;
SoSecurityManager *mgr;
SEL methodSel;
Class c;
#warning things may crash here...
values = calloc (100, sizeof (NSMutableString *));
@@ -1075,7 +1076,11 @@ static Class sogoAppointmentFolderKlass = Nil;
#warning this check should be done directly in the query... we should fix this sometime
mgr = [SoSecurityManager sharedSecurityManager];
sogoObject = [self _createChildComponentWithRecord: object];
//c = [self objectClassForComponentName: [object objectForKey: @"c_component"]];
sogoObject = [SOGoCalendarComponent objectWithRecord: object inContainer: self];
[sogoObject setComponentTag: [object objectForKey: @"c_component"]];
//sogoObject = [self _createChildComponentWithRecord: object];
if (activeUserIsOwner
|| [[self ownerInContext: context]
@@ -1167,35 +1172,35 @@ static Class sogoAppointmentFolderKlass = Nil;
- (void) appendObject: (NSDictionary *) object
properties: (NSString **) properties
withBaseURL: (NSString *) baseURL
toComplexResponse: (WOResponse *) r
toBuffer: (NSMutableString *) r
{
NSArray *propstats;
unsigned int count, max;
[r appendContentString: @"<D:response><D:href>"];
[r appendContentString: baseURL];
[r appendFormat: @"<D:response><D:href>"];
[r appendString: baseURL];
// if (![baseURL hasSuffix: @"/"])
// [r appendContentString: @"/"];
[r appendContentString: [object objectForKey: @"c_name"]];
[r appendContentString: @"</D:href>"];
[r appendString: [object objectForKey: @"c_name"]];
[r appendString: @"</D:href>"];
// NSLog (@"(appendPropstats...): %@", [NSDate date]);
propstats = [self _propstats: properties ofObject: object];
max = [propstats count];
for (count = 0; count < max; count++)
[self _appendPropstat: [propstats objectAtIndex: count]
toResponse: r];
toBuffer: r];
// NSLog (@"/(appendPropstats...): %@", [NSDate date]);
[r appendContentString: @"</D:response>"];
[r appendString: @"</D:response>"];
}
- (void) appendMissingObjectRef: (NSString *) href
toComplexResponse: (WOResponse *) r
toBuffer: (NSMutableString *) r
{
[r appendContentString: @"<D:response><D:href>"];
[r appendContentString: href];
[r appendContentString: @"</D:href><D:status>HTTP/1.1 404 Not Found</D:status></D:response>"];
[r appendString: @"<D:response><D:href>"];
[r appendString: href];
[r appendString: @"</D:href><D:status>HTTP/1.1 404 Not Found</D:status></D:response>"];
}
- (void) _appendTimeRange: (id <DOMElement>) timeRangeElement
@@ -1452,33 +1457,48 @@ static Class sogoAppointmentFolderKlass = Nil;
matchingFilters: (NSArray *) filters
toResponse: (WOResponse *) response
{
NSArray *apts;
NSArray *apts, *fields;
NSDictionary *currentFilter;
NSEnumerator *filterList;
NSString *additionalFilters, *baseURL;
NSMutableString *buffer;
unsigned int count, max;
baseURL = [[self davURL] absoluteString];
// We check if we need to fetch all fields. If the DAV client
// has only asked for {DAV:}getetag with no other properties,
// we do not load the c_content and other fields from the
// database as this can be pretty costly.
if ([*properties caseInsensitiveCompare: @"{DAV:}getetag"] == NSOrderedSame &&
!*(properties+1))
fields =[NSArray arrayWithObjects: @"c_name", @"c_version",
@"c_component", nil];
else
fields = reportQueryFields;
filterList = [filters objectEnumerator];
while ((currentFilter = [filterList nextObject]))
{
additionalFilters = [self _composeAdditionalFilters: currentFilter];
// NSLog(@"query");
apts = [self bareFetchFields: reportQueryFields
NSLog(@"query");
apts = [self bareFetchFields: fields
from: [currentFilter objectForKey: @"start"]
to: [currentFilter objectForKey: @"end"]
title: [currentFilter objectForKey: @"title"]
component: [currentFilter objectForKey: @"name"]
additionalFilters: additionalFilters];
// NSLog(@"adding properties");
NSLog(@"adding properties");
max = [apts count];
buffer = [[NSMutableString alloc] initWithCapacity: max*512];
for (count = 0; count < max; count++)
[self appendObject: [apts objectAtIndex: count]
properties: properties
withBaseURL: baseURL
toComplexResponse: response];
// NSLog(@"done");
toBuffer: buffer];
NSLog(@"done");
[response appendContentString: buffer];
[buffer release];
}
}
@@ -1640,6 +1660,7 @@ static Class sogoAppointmentFolderKlass = Nil;
NSDictionary *currentComponent, *components;
NSString *currentURL, *baseURL;
NSMutableArray *urls;
NSMutableString *buffer;
unsigned int count, max;
baseURL = [[self davURL] absoluteString];
@@ -1656,6 +1677,7 @@ static Class sogoAppointmentFolderKlass = Nil;
components = [self _fetchComponentsMatchingURLs: urls];
max = [urls count];
// NSLog (@"adding properties with url");
buffer = [[NSMutableString alloc] initWithCapacity: max*512];
for (count = 0; count < max; count++)
{
currentComponent
@@ -1664,11 +1686,13 @@ static Class sogoAppointmentFolderKlass = Nil;
[self appendObject: currentComponent
properties: properties
withBaseURL: baseURL
toComplexResponse: response];
toBuffer: buffer];
else
[self appendMissingObjectRef: currentURL
toComplexResponse: response];
toBuffer: buffer];
}
[response appendContentString: buffer];
[buffer release];
// NSLog (@"/adding properties with url");
[urls release];

View File

@@ -269,8 +269,9 @@
forUID: currentUID];
}
[self sendEMailUsingTemplateNamed: @"Invitation"
[self sendEMailUsingTemplateNamed: @"Update"
forObject: [newEvent itipEntryWithMethod: @"request"]
previousObject: oldEvent
toAttendees: updateAttendees];
}
@@ -304,6 +305,7 @@
[self _handleRemovedUsers: attendees];
[self sendEMailUsingTemplateNamed: @"Deletion"
forObject: [newEvent itipEntryWithMethod: @"cancel"]
previousObject: oldEvent
toAttendees: attendees];
}
@@ -324,6 +326,7 @@
[self _handleAddedUsers: attendees fromEvent: newEvent];
[self sendEMailUsingTemplateNamed: @"Invitation"
forObject: [newEvent itipEntryWithMethod: @"request"]
previousObject: oldEvent
toAttendees: attendees];
}
}
@@ -349,6 +352,7 @@
[self _handleAddedUsers: attendees fromEvent: newEvent];
[self sendEMailUsingTemplateNamed: @"Invitation"
forObject: [newEvent itipEntryWithMethod: @"request"]
previousObject: oldEvent
toAttendees: attendees];
}
@@ -438,8 +442,8 @@
statusChange: (NSString *) newStatus
inEvent: (iCalEvent *) event
{
NSString *newContent, *currentStatus, *currentUser, *organizerUID;
SOGoUser *ownerUser;
NSString *newContent, *currentStatus, *organizerUID;
SOGoUser *ownerUser, *currentUser;
NSException *ex;
ex = nil;
@@ -571,6 +575,7 @@
#warning fix this when sendEmailUsing blabla has been cleaned up
[self sendEMailUsingTemplateNamed: @"Invitation"
forObject: event
previousObject: nil
toAttendees: [NSArray arrayWithObject: person]];
[person release];
[elements
@@ -604,6 +609,7 @@
#warning fix this when sendEmailUsing blabla has been cleaned up
[self sendEMailUsingTemplateNamed: @"Deletion"
forObject: event
previousObject: nil
toAttendees: [NSArray arrayWithObject: person]];
[person release];
[elements
@@ -805,6 +811,7 @@
[self _handleRemovedUsers: attendees];
[self sendEMailUsingTemplateNamed: @"Deletion"
forObject: [occurence itipEntryWithMethod: @"cancel"]
previousObject: nil
toAttendees: attendees];
}
}

View File

@@ -0,0 +1,5 @@
<#IsSubject>The appointment for the <#OldAptStartDate /> at <#OldAptStartTime /> has changed</#IsSubject>
<#IsBody>
This appointment, previously set for <#OldAptStartDate /> at <#OldAptStartTime /> (<#OldAptLocation />) is now scheduled for <#NewAptStartDate /> at <#NewAptStartTime /> (<#NewAptLocation />).
Please make a decision for these new settings.
</#IsBody>

View File

@@ -0,0 +1,47 @@
OldAptStartDate: WOString {
value = oldStartDate;
dateformat = "%d/%m/%y";
escapeHTML = NO;
}
OldAptStartTime: WOString {
value = oldStartDate;
dateformat = "%H:%M";
escapeHTML = NO;
}
NewAptStartDate: WOString {
value = newStartDate;
dateformat = "%d/%m/%y";
escapeHTML = NO;
}
NewAptStartTime: WOString {
value = newStartDate;
dateformat = "%H:%M";
escapeHTML = NO;
}
Organizer: WOString {
value = organizerName;
escapeHTML = NO;
}
OldAptLocation: WOString {
value = previousApt.location;
escapeHTML = NO;
}
NewAptLocation: WOString {
value = apt.location;
escapeHTML = NO;
}
IsSubject: WOConditional {
condition = isSubject;
}
IsBody: WOConditional {
condition = isSubject;
negate = YES;
}

View File

@@ -0,0 +1,5 @@
<#IsSubject>The appointment for the <#OldAptStartDate /> at <#OldAptStartTime /> has changed</#IsSubject>
<#IsBody>
This appointment, previously set for <#OldAptStartDate /> at <#OldAptStartTime /> (<#OldAptLocation />) is now scheduled for <#NewAptStartDate /> at <#NewAptStartTime /> (<#NewAptLocation />).
Please make a decision for these new settings.
</#IsBody>

View File

@@ -0,0 +1,47 @@
OldAptStartDate: WOString {
value = oldStartDate;
dateformat = "%d/%m/%y";
escapeHTML = NO;
}
OldAptStartTime: WOString {
value = oldStartDate;
dateformat = "%H:%M";
escapeHTML = NO;
}
NewAptStartDate: WOString {
value = newStartDate;
dateformat = "%d/%m/%y";
escapeHTML = NO;
}
NewAptStartTime: WOString {
value = newStartDate;
dateformat = "%H:%M";
escapeHTML = NO;
}
Organizer: WOString {
value = organizerName;
escapeHTML = NO;
}
OldAptLocation: WOString {
value = previousApt.location;
escapeHTML = NO;
}
NewAptLocation: WOString {
value = apt.location;
escapeHTML = NO;
}
IsSubject: WOConditional {
condition = isSubject;
}
IsBody: WOConditional {
condition = isSubject;
negate = YES;
}

View File

@@ -0,0 +1,5 @@
<#IsSubject>Le rendez-vous du <#OldAptStartDate /> à <#OldAptStartTime /> est modifié</#IsSubject>
<#IsBody>
La réunion qui devait se dérouler le <#OldAptStartDate /> à <#OldAptStartTime /> (<#OldAptLocation />) est maintenant prévue le <#NewAptStartDate /> à <#NewAptStartTime /> (<#NewAptLocation />).
Vous êtes invité à accepter ou refuser de participer à la réunion pour cette nouvelle date.
</#IsBody>

View File

@@ -0,0 +1,47 @@
OldAptStartDate: WOString {
value = oldStartDate;
dateformat = "%d/%m/%y";
escapeHTML = NO;
}
OldAptStartTime: WOString {
value = oldStartDate;
dateformat = "%H:%M";
escapeHTML = NO;
}
NewAptStartDate: WOString {
value = newStartDate;
dateformat = "%d/%m/%y";
escapeHTML = NO;
}
NewAptStartTime: WOString {
value = newStartDate;
dateformat = "%H:%M";
escapeHTML = NO;
}
Organizer: WOString {
value = organizerName;
escapeHTML = NO;
}
OldAptLocation: WOString {
value = previousApt.location;
escapeHTML = NO;
}
NewAptLocation: WOString {
value = apt.location;
escapeHTML = NO;
}
IsSubject: WOConditional {
condition = isSubject;
}
IsBody: WOConditional {
condition = isSubject;
negate = YES;
}

View File

@@ -0,0 +1,5 @@
<#IsSubject>The appointment for the <#OldAptStartDate /> at <#OldAptStartTime /> has changed</#IsSubject>
<#IsBody>
This appointment, previously set for <#OldAptStartDate /> at <#OldAptStartTime /> (<#OldAptLocation />) is now scheduled for <#NewAptStartDate /> at <#NewAptStartTime /> (<#NewAptLocation />).
Please make a decision for these new settings.
</#IsBody>

View File

@@ -0,0 +1,47 @@
OldAptStartDate: WOString {
value = oldStartDate;
dateformat = "%d/%m/%y";
escapeHTML = NO;
}
OldAptStartTime: WOString {
value = oldStartDate;
dateformat = "%H:%M";
escapeHTML = NO;
}
NewAptStartDate: WOString {
value = newStartDate;
dateformat = "%d/%m/%y";
escapeHTML = NO;
}
NewAptStartTime: WOString {
value = newStartDate;
dateformat = "%H:%M";
escapeHTML = NO;
}
Organizer: WOString {
value = organizerName;
escapeHTML = NO;
}
OldAptLocation: WOString {
value = previousApt.location;
escapeHTML = NO;
}
NewAptLocation: WOString {
value = apt.location;
escapeHTML = NO;
}
IsSubject: WOConditional {
condition = isSubject;
}
IsBody: WOConditional {
condition = isSubject;
negate = YES;
}

View File

@@ -0,0 +1,8 @@
<#IsSubject>L'appuntamento fissato in data <#OldAptStartDate /> alle ore <#OldAptStartTime /> &egrave; stato modificato </#IsSubject>
<#IsBody>
Questo appuntamento, fissato precedentemete in data <#OldAptStartDate /> (<#OldAptLocation />)
alle ore <#OldAptStartTime /> &egrave; ora programmato il <#NewAptStartDate
/> alle ore <#NewAptStartTime
/> (<#NewAptLocation />)
Per confermare o disdire.
</#IsBody>

View File

@@ -0,0 +1,47 @@
OldAptStartDate: WOString {
value = oldStartDate;
dateformat = "%d/%m/%y";
escapeHTML = NO;
}
OldAptStartTime: WOString {
value = oldStartDate;
dateformat = "%H:%M";
escapeHTML = NO;
}
NewAptStartDate: WOString {
value = newStartDate;
dateformat = "%d/%m/%y";
escapeHTML = NO;
}
NewAptStartTime: WOString {
value = newStartDate;
dateformat = "%H:%M";
escapeHTML = NO;
}
Organizer: WOString {
value = organizerName;
escapeHTML = NO;
}
OldAptLocation: WOString {
value = previousApt.location;
escapeHTML = NO;
}
NewAptLocation: WOString {
value = apt.location;
escapeHTML = NO;
}
IsSubject: WOConditional {
condition = isSubject;
}
IsBody: WOConditional {
condition = isSubject;
negate = YES;
}

View File

@@ -34,7 +34,8 @@
*/
@interface SOGoAptMailNotification : SoComponent
{
iCalEntityObject* apt;
iCalEntityObject *apt;
iCalEntityObject *previousApt;
NSString *homePageURL;
NSTimeZone *viewTZ;
NSCalendarDate *oldStartDate;
@@ -44,9 +45,16 @@
}
- (iCalEntityObject *) apt;
- (void) setApt: (iCalEntityObject *) newApt;
- (void) setApt: (iCalEntityObject *) theApt;
/* Content Generation */
- (iCalEntityObject *) previousApt;
- (void) setPreviousApt: (iCalEntityObject *) theApt;
- (void) setOrganizerName: (NSString *) theString;
- (NSString *) organizerName;
- (BOOL) hasSentBy;
- (NSString *) sentBy;
- (NSString *) getSubject;
- (NSString *) getBody;

View File

@@ -68,7 +68,11 @@ static NSTimeZone *UTC = nil;
- (void) dealloc
{
[apt release];
[previousApt release];
[organizerName release];
[viewTZ release];
[oldStartDate release];
[newStartDate release];
[super dealloc];
}
@@ -77,11 +81,50 @@ static NSTimeZone *UTC = nil;
return apt;
}
- (void) setApt: (iCalEntityObject *) newApt
- (void) setApt: (iCalEntityObject *) theApt
{
ASSIGN (apt, newApt);
ASSIGN(apt, theApt);
}
- (iCalEntityObject *) previousApt
{
return previousApt;
}
- (void) setPreviousApt: (iCalEntityObject *) theApt
{
ASSIGN(previousApt, theApt);
}
- (NSTimeZone *) viewTZ
{
if (self->viewTZ) return self->viewTZ;
return UTC;
}
- (void) setViewTZ: (NSTimeZone *) _viewTZ
{
ASSIGN(self->viewTZ, _viewTZ);
}
- (NSCalendarDate *) oldStartDate
{
if (!self->oldStartDate)
{
ASSIGN(self->oldStartDate, [[self previousApt] startDate]);
[self->oldStartDate setTimeZone: [self viewTZ]];
}
return self->oldStartDate;
}
- (NSCalendarDate *) newStartDate
{
if (!self->newStartDate)
{
ASSIGN(self->newStartDate, [[self apt] startDate]);
[self->newStartDate setTimeZone:[self viewTZ]];
}
return self->newStartDate;
}
- (BOOL) isSubject
{

View File

@@ -0,0 +1,5 @@
<#IsSubject>The appointment for the <#OldAptStartDate /> at <#OldAptStartTime /> has changed</#IsSubject>
<#IsBody>
This appointment, previously set for <#OldAptStartDate /> at <#OldAptStartTime /> (<#OldAptLocation />) is now scheduled for <#NewAptStartDate /> at <#NewAptStartTime /> (<#NewAptLocation />).
Please make a decision for these new settings.
</#IsBody>

View File

@@ -0,0 +1,47 @@
OldAptStartDate: WOString {
value = oldStartDate;
dateformat = "%d/%m/%y";
escapeHTML = NO;
}
OldAptStartTime: WOString {
value = oldStartDate;
dateformat = "%H:%M";
escapeHTML = NO;
}
NewAptStartDate: WOString {
value = newStartDate;
dateformat = "%d/%m/%y";
escapeHTML = NO;
}
NewAptStartTime: WOString {
value = newStartDate;
dateformat = "%H:%M";
escapeHTML = NO;
}
Organizer: WOString {
value = organizerName;
escapeHTML = NO;
}
OldAptLocation: WOString {
value = previousApt.location;
escapeHTML = NO;
}
NewAptLocation: WOString {
value = apt.location;
escapeHTML = NO;
}
IsSubject: WOConditional {
condition = isSubject;
}
IsBody: WOConditional {
condition = isSubject;
negate = YES;
}

View File

@@ -0,0 +1,57 @@
/*
Copyright (C) 2000-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
OGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
OGo 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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#include "SOGoAptMailNotification.h"
@interface SOGoAptMailEnglishUpdate : SOGoAptMailNotification
{
}
@end
@implementation SOGoAptMailEnglishUpdate
@end
@interface SOGoAptMailFrenchUpdate : SOGoAptMailNotification
{
}
@end
@implementation SOGoAptMailFrenchUpdate
@end
@interface SOGoAptMailGermanUpdate : SOGoAptMailNotification
{
}
@end
@implementation SOGoAptMailGermanUpdate
@end
@interface SOGoAptMailItalianUpdate : SOGoAptMailNotification
{
}
@end
@implementation SOGoAptMailItalianUpdate
@end

View File

@@ -42,9 +42,11 @@
iCalCalendar *fullCalendar;
iCalCalendar *safeCalendar;
iCalCalendar *originalCalendar;
NSString *componentTag;
}
- (NSString *) componentTag;
- (void) setComponentTag: (NSString *) theTag;
- (iCalCalendar *) calendar: (BOOL) create
secure: (BOOL) secure;
@@ -61,6 +63,7 @@
- (BOOL) sendEMailNotifications;
- (void) sendEMailUsingTemplateNamed: (NSString *) pageName
forObject: (iCalRepeatableEntityObject *) object
previousObject: (iCalRepeatableEntityObject *) previousObject
toAttendees: (NSArray *) attendees;
- (void) sendIMIPReplyForEvent: (iCalRepeatableEntityObject *) event
from: (SOGoUser *) from

View File

@@ -83,6 +83,7 @@ static BOOL sendEMailNotifications = NO;
fullCalendar = nil;
safeCalendar = nil;
originalCalendar = nil;
componentTag = nil;
}
return self;
@@ -93,6 +94,7 @@ static BOOL sendEMailNotifications = NO;
[fullCalendar release];
[safeCalendar release];
[originalCalendar release];
[componentTag release];
[super dealloc];
}
@@ -103,9 +105,15 @@ static BOOL sendEMailNotifications = NO;
- (NSString *) componentTag
{
[self subclassResponsibility: _cmd];
if (!componentTag)
[self subclassResponsibility: _cmd];
return nil;
return componentTag;
}
- (void) setComponentTag: (NSString *) theTag
{
ASSIGN(componentTag, theTag);
}
- (void) _filterComponent: (iCalEntityObject *) component
@@ -326,10 +334,9 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID)
- (iCalCalendar *) calendar: (BOOL) create secure: (BOOL) secure
{
NSString *componentTag;
iCalRepeatableEntityObject *newComponent;
iCalCalendar **calendar, *returnedCopy;
NSString *iCalString;
NSString *iCalString, *tag;
if (secure)
calendar = &safeCalendar;
@@ -356,9 +363,9 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID)
ASSIGN (*calendar, [iCalCalendar groupWithTag: @"vcalendar"]);
[*calendar setVersion: @"2.0"];
[*calendar setProdID: @"-//Inverse inc.//SOGo 0.9//EN"];
componentTag = [[self componentTag] uppercaseString];
newComponent = [[*calendar classForTag: componentTag]
groupWithTag: componentTag];
tag = [[self componentTag] uppercaseString];
newComponent = [[*calendar classForTag: tag]
groupWithTag: tag];
[newComponent setUid: [self globallyUniqueObjectId]];
[*calendar addChild: newComponent];
}
@@ -453,6 +460,7 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID)
- (void) sendEMailUsingTemplateNamed: (NSString *) newPageName
forObject: (iCalRepeatableEntityObject *) object
previousObject: (iCalRepeatableEntityObject *) previousObject
toAttendees: (NSArray *) attendees
{
NSString *pageName;
@@ -467,7 +475,7 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID)
NGMimeMessage *msg;
NGMimeBodyPart *bodyPart;
NGMimeMultipartBody *body;
SOGoUser *ownerUser, *currentUser;
SOGoUser *ownerUser;
if (sendEMailNotifications
&& [object isStillRelevant])
@@ -511,6 +519,7 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID)
/* construct message content */
p = [app pageWithName: pageName inContext: context];
[p setApt: object];
[p setPreviousApt: previousObject];
if ([[object organizer] cn] && [[[object organizer] cn] length])
{

View File

@@ -84,7 +84,7 @@
- (void) renameTo: (NSString *) newName;
- (WOResponse *) subscribe: (BOOL) reallyDo
inTheNameOf: (NSString *) delegatedUser
inTheNamesOf: (NSArray *) delegatedUsers
fromMailInvitation: (BOOL) isMailInvitation
inContext: (WOContext *) localContext;

View File

@@ -660,59 +660,72 @@ static NSArray *childRecordFields = nil;
}
- (WOResponse *) subscribe: (BOOL) reallyDo
inTheNameOf: (NSString *) delegatedUser
inTheNamesOf: (NSArray *) delegatedUsers
fromMailInvitation: (BOOL) isMailInvitation
inContext: (WOContext *) localContext
{
WOResponse *response;
SOGoUser *currentUser, *subscriptionUser;
BOOL validRequest;
SOGoUser *currentUser;
response = [localContext response];
currentUser = [localContext activeUser];
if ([delegatedUser length])
if (delegatedUsers && [delegatedUsers count])
{
validRequest = ([currentUser isSuperUser]);
subscriptionUser = [SOGoUser userWithLogin: delegatedUser roles: nil];
}
else
{
validRequest = YES;
subscriptionUser = currentUser;
}
if (![currentUser isSuperUser])
{
[response setStatus: 403];
[response appendContentString:
@"You cannot subscribe another user to any folder"
@" unless you are a super-user."];
}
else
{
SOGoUser *subscriptionUser;
int i;
if (validRequest)
[self _subscribeUser: subscriptionUser
reallyDo: reallyDo
fromMailInvitation: isMailInvitation
inResponse: response];
for (i = 0; i < [delegatedUsers count]; i++)
{
subscriptionUser = [SOGoUser userWithLogin: [delegatedUsers objectAtIndex: i]
roles: nil];
[self _subscribeUser: subscriptionUser
reallyDo: reallyDo
fromMailInvitation: isMailInvitation
inResponse: response];
}
}
}
else
{
[response setStatus: 403];
[response appendContentString:
@"You cannot subscribe another user to any folder"
@" unless you are a super-user."];
[self _subscribeUser: currentUser
reallyDo: reallyDo
fromMailInvitation: isMailInvitation
inResponse: response];
}
return response;
}
- (NSString *) _parseDAVDelegatedUser: (WOContext *) queryContext
- (NSArray *) _parseDAVDelegatedUser: (WOContext *) queryContext
{
id <DOMDocument> document;
id <DOMNamedNodeMap> attrs;
id o;
document = [[queryContext request] contentAsDOMDocument];
attrs = [[document documentElement] attributes];
return [[attrs namedItem: @"user"] nodeValue];
o = [attrs namedItem: @"users"];
if (o) return [[o nodeValue] componentsSeparatedByString: @","];
return nil;
}
- (id <WOActionResults>) davSubscribe: (WOContext *) queryContext
{
return [self subscribe: YES
inTheNameOf: [self _parseDAVDelegatedUser: queryContext]
inTheNamesOf: [self _parseDAVDelegatedUser: queryContext]
fromMailInvitation: NO
inContext: queryContext];
}
@@ -720,7 +733,7 @@ static NSArray *childRecordFields = nil;
- (id <WOActionResults>) davUnsubscribe: (WOContext *) queryContext
{
return [self subscribe: NO
inTheNameOf: [self _parseDAVDelegatedUser: queryContext]
inTheNamesOf: [self _parseDAVDelegatedUser: queryContext]
fromMailInvitation: NO
inContext: queryContext];
}

View File

@@ -81,7 +81,7 @@
[self _setupContext];
return [clientObject subscribe: YES
inTheNameOf: nil
inTheNamesOf: nil
fromMailInvitation: isMailInvitation
inContext: context];
}
@@ -91,7 +91,7 @@
[self _setupContext];
return [clientObject subscribe: NO
inTheNameOf: nil
inTheNamesOf: nil
fromMailInvitation: isMailInvitation
inContext: context];
}