1 /* SOGoCalendarComponent.m - this file is part of SOGo
3 * Copyright (C) 2006 Inverse groupe conseil
5 * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
7 * This file is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This file is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #import <Foundation/NSString.h>
25 #import <NGCards/iCalCalendar.h>
26 #import <NGCards/iCalPerson.h>
27 #import <NGCards/iCalRepeatableEntityObject.h>
28 #import <NGMime/NGMime.h>
29 #import <NGMail/NGMail.h>
30 #import <NGMail/NGSendMail.h>
32 #import <SOGo/AgenorUserManager.h>
33 #import <SOGo/SOGoPermissions.h>
34 #import <SOGo/SOGoUser.h>
38 #import "SOGoAptMailNotification.h"
39 #import "SOGoCalendarComponent.h"
41 static NSString *mailTemplateDefaultLanguage = nil;
42 static BOOL sendEMailNotifications = NO;
44 @implementation SOGoCalendarComponent
49 static BOOL didInit = NO;
55 ud = [NSUserDefaults standardUserDefaults];
56 mailTemplateDefaultLanguage = [[ud stringForKey:@"SOGoDefaultLanguage"]
58 if (!mailTemplateDefaultLanguage)
59 mailTemplateDefaultLanguage = @"French";
61 sendEMailNotifications
62 = [ud boolForKey: @"SOGoAppointmentSendEMailNotifications"];
68 if ((self = [super init]))
86 - (NSString *) davContentType
88 return @"text/calendar";
91 - (NSString *) componentTag
93 [self subclassResponsibility: _cmd];
98 - (void) _filterPrivateComponent: (iCalEntityObject *) component
100 [component setSummary: @""];
101 [component setComment: @""];
102 [component setUserComment: @""];
103 [component setLocation: @""];
104 [component setCategories: @""];
105 [component setUrl: @""];
106 [component removeAllAttendees];
107 [component removeAllAlarms];
110 - (NSString *) contentAsString
112 NSString *tmpContent, *email;
113 iCalCalendar *tmpCalendar;
114 iCalRepeatableEntityObject *tmpComponent;
119 tmpContent = [super contentAsString];
120 calContent = tmpContent;
121 if ([tmpContent length] > 0)
123 tmpCalendar = [iCalCalendar parseSingleFromSource: tmpContent];
124 tmpComponent = (iCalRepeatableEntityObject *) [tmpCalendar firstChildWithTag: [self componentTag]];
125 if (![tmpComponent isPublic])
127 context = [[WOApplication application] context];
128 email = [[context activeUser] email];
129 if (!([tmpComponent isOrganizer: email]
130 || [tmpComponent isParticipant: email]))
132 // content = tmpContent;
133 [self _filterPrivateComponent: tmpComponent];
134 calContent = [tmpCalendar versitString];
145 - (NSException *) saveContentString: (NSString *) contentString
146 baseVersion: (unsigned int) baseVersion
150 result = [super saveContentString: contentString
151 baseVersion: baseVersion];
152 if (!result && calContent)
154 [calContent release];
161 - (iCalCalendar *) calendar
163 NSString *iCalString;
167 iCalString = [self contentAsString];
170 calendar = [iCalCalendar parseSingleFromSource: iCalString];
178 - (iCalRepeatableEntityObject *) component
180 return (iCalRepeatableEntityObject *)
182 firstChildWithTag: [self componentTag]];
187 - (NSException *) primarySaveContentString: (NSString *) _iCalString
189 return [super saveContentString: _iCalString];
192 - (NSException *) primaryDelete
194 return [super delete];
197 - (NSException *) deleteWithBaseSequence: (int) a
199 [self subclassResponsibility: _cmd];
204 - (NSException *) delete
206 return [self deleteWithBaseSequence:0];
209 /* EMail Notifications */
210 - (NSString *) homePageURLForPerson: (iCalPerson *) _person
215 NSArray *traversalObjects;
217 /* generate URL from traversal stack */
218 ctx = [[WOApplication application] context];
219 traversalObjects = [ctx objectTraversalStack];
220 if ([traversalObjects count] > 0)
221 baseURL = [[traversalObjects objectAtIndex:0] baseURLInContext:ctx];
224 baseURL = @"http://localhost/";
225 [self warnWithFormat:@"Unable to create baseURL from context!"];
227 uid = [[AgenorUserManager sharedUserManager]
228 getUIDForEmail: [_person rfc822Email]];
231 ? [NSString stringWithFormat:@"%@%@", baseURL, uid]
235 - (BOOL) sendEMailNotifications
237 return sendEMailNotifications;
240 - (void) sendEMailUsingTemplateNamed: (NSString *) _pageName
241 forOldObject: (iCalRepeatableEntityObject *) _oldObject
242 andNewObject: (iCalRepeatableEntityObject *) _newObject
243 toAttendees: (NSArray *) _attendees
246 iCalPerson *organizer;
247 NSString *cn, *sender, *iCalString;
248 NGSendMail *sendmail;
251 iCalPerson *attendee;
253 SOGoAptMailNotification *p;
254 NSString *subject, *text, *header;
255 NGMutableHashMap *headerMap;
257 NGMimeBodyPart *bodyPart;
258 NGMimeMultipartBody *body;
260 if ([_attendees count])
264 organizer = [_newObject organizer];
265 cn = [organizer cnWithoutQuotes];
267 sender = [NSString stringWithFormat:@"%@ <%@>",
269 [organizer rfc822Email]];
271 sender = [organizer rfc822Email];
273 /* generate iCalString once */
274 iCalString = [[_newObject parent] versitString];
276 /* get sendmail object */
277 sendmail = [NGSendMail sharedSendMail];
279 /* get WOApplication instance */
280 app = [WOApplication application];
282 /* generate dynamic message content */
284 count = [_attendees count];
285 for (i = 0; i < count; i++)
287 attendee = [_attendees objectAtIndex:i];
289 /* construct recipient */
292 recipient = [NSString stringWithFormat: @"%@ <%@>",
294 [attendee rfc822Email]];
296 recipient = [attendee rfc822Email];
298 /* create page name */
299 // TODO: select user's default language?
300 pageName = [NSString stringWithFormat: @"SOGoAptMail%@%@",
301 mailTemplateDefaultLanguage,
303 /* construct message content */
304 p = [app pageWithName: pageName inContext: [WOContext context]];
305 [p setNewApt: _newObject];
306 [p setOldApt: _oldObject];
307 [p setHomePageURL: [self homePageURLForPerson: attendee]];
308 [p setViewTZ: [self userTimeZone: cn]];
309 subject = [p getSubject];
312 /* construct message */
313 headerMap = [NGMutableHashMap hashMapWithCapacity: 5];
315 /* NOTE: multipart/alternative seems like the correct choice but
316 * unfortunately Thunderbird doesn't offer the rich content alternative
317 * at all. Mail.app shows the rich content alternative _only_
318 * so we'll stick with multipart/mixed for the time being.
320 [headerMap setObject: @"multipart/mixed" forKey: @"content-type"];
321 [headerMap setObject: sender forKey: @"From"];
322 [headerMap setObject: recipient forKey: @"To"];
323 [headerMap setObject: [NSCalendarDate date] forKey: @"date"];
324 [headerMap setObject: subject forKey: @"Subject"];
325 msg = [NGMimeMessage messageWithHeader: headerMap];
328 body = [[NGMimeMultipartBody alloc] initWithPart: msg];
331 headerMap = [NGMutableHashMap hashMapWithCapacity: 1];
332 [headerMap setObject: @"text/plain; charset=utf-8"
333 forKey: @"content-type"];
334 bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap];
335 [bodyPart setBody: [text dataUsingEncoding: NSUTF8StringEncoding]];
337 /* attach text part to multipart body */
338 [body addBodyPart: bodyPart];
341 header = [NSString stringWithFormat: @"text/calendar; method=%@;"
343 [(iCalCalendar *) [_newObject parent] method]];
344 headerMap = [NGMutableHashMap hashMapWithCapacity: 1];
345 [headerMap setObject:header forKey: @"content-type"];
346 bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap];
347 [bodyPart setBody: [iCalString dataUsingEncoding: NSUTF8StringEncoding]];
349 /* attach calendar part to multipart body */
350 [body addBodyPart: bodyPart];
352 /* attach multipart body to message */
356 /* send the damn thing */
357 [sendmail sendMimePart: msg
358 toRecipients: [NSArray arrayWithObject: [attendee rfc822Email]]
359 sender: [organizer rfc822Email]];
364 - (NSArray *) rolesOfUser: (NSString *) login
365 inContext: (WOContext *) context
367 AgenorUserManager *um;
368 iCalRepeatableEntityObject *component;
369 NSMutableArray *sogoRoles;
373 sogoRoles = [NSMutableArray new];
374 [sogoRoles autorelease];
376 um = [AgenorUserManager sharedUserManager];
377 email = [um getEmailForUID: login];
379 component = [self component];
382 if ([component isOrganizer: email])
383 [sogoRoles addObject: SOGoRole_Organizer];
384 else if ([component isParticipant: email])
385 [sogoRoles addObject: SOGoRole_Participant];
386 else if ([[container ownerInContext: nil] isEqualToString: login])
387 [sogoRoles addObject: SoRole_Owner];
391 user = [[SOGoUser alloc] initWithLogin: login roles: nil];
392 [sogoRoles addObjectsFromArray: [user rolesForObject: container
393 inContext: context]];