1 /* UIxContactFoldersView.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 <NGObjWeb/NSException+HTTP.h>
26 #import <NGObjWeb/SoObject.h>
27 #import <NGObjWeb/WOResponse.h>
28 #import <NGObjWeb/WOContext.h>
30 #import <GDLContentStore/GCSFolder.h>
31 #import <GDLContentStore/GCSFolderManager.h>
33 #import <SoObjects/SOGo/LDAPUserManager.h>
34 #import <SoObjects/SOGo/SOGoUser.h>
35 #import <SoObjects/SOGo/NSString+Utilities.h>
36 #import <SoObjects/Contacts/SOGoContactFolders.h>
37 #import <SoObjects/Contacts/SOGoContactFolder.h>
38 #import <SoObjects/Contacts/SOGoContactGCSFolder.h>
39 #import <SoObjects/Contacts/SOGoContactLDAPFolder.h>
43 #import "UIxContactFoldersView.h"
45 @implementation UIxContactFoldersView
47 - (id) _selectActionForApplication: (NSString *) actionName
49 SOGoContactFolders *folders;
50 NSString *url, *action;
53 folders = [self clientObject];
54 action = [NSString stringWithFormat: @"../%@/%@",
55 [folders defaultSourceName],
58 request = [[self context] request];
60 url = [[request uri] composeURLWithAction: action
61 parameters: [self queryParameters]
64 return [self redirectToLocation: url];
69 return [self _selectActionForApplication: @"view"];
74 return [self _selectActionForApplication: @"new"];
77 - (id <WOActionResults>) newAbAction
79 id <WOActionResults> response;
82 name = [self queryParameterForKey: @"name"];
83 if ([name length] > 0)
84 response = [[self clientObject] newFolderWithName: name];
86 response = [NSException exceptionWithHTTPStatus: 400
87 reason: @"The name is missing"];
92 - (id) selectForMailerAction
94 return [self _selectActionForApplication: @"mailer-contacts"];
97 - (void) _fillResults: (NSMutableDictionary *) results
98 inFolder: (id <SOGoContactFolder>) folder
99 withSearchOn: (NSString *) contact
101 NSEnumerator *folderResults;
102 NSDictionary *currentContact;
105 folderResults = [[folder lookupContactsWithFilter: contact
107 ordering: NSOrderedAscending] objectEnumerator];
108 currentContact = [folderResults nextObject];
109 while (currentContact)
111 uid = [currentContact objectForKey: @"c_uid"];
112 if (uid && ![results objectForKey: uid])
113 [results setObject: currentContact
115 currentContact = [folderResults nextObject];
119 - (NSString *) _emailForResult: (NSDictionary *) result
121 NSMutableString *email;
122 NSString *name, *mail;
124 email = [NSMutableString string];
125 name = [result objectForKey: @"displayName"];
127 name = [result objectForKey: @"cn"];
128 mail = [result objectForKey: @"mail"];
130 [email appendFormat: @"%@ <%@>", name, mail];
132 [email appendString: mail];
137 - (WOResponse *) _responseForResults: (NSArray *) results
139 WOResponse *response;
140 NSEnumerator *contacts;
141 NSString *responseString;
142 NSDictionary *contact;
144 response = [context response];
146 if ([results count] > 0)
148 contacts = [results objectEnumerator];
149 contact = [contacts nextObject];
152 responseString = [NSString stringWithFormat: @"%@:%@:%@",
153 [contact objectForKey: @"c_uid"],
154 [contact objectForKey: @"cn"],
155 [contact objectForKey: @"c_email"]];
156 [response setStatus: 200];
157 // [response setHeader: @"text/plain; charset=iso-8859-1"
158 // forKey: @"Content-Type"];
159 [response appendContentString: responseString];
160 contact = [contacts nextObject];
164 [response setStatus: 404];
169 - (id <WOActionResults>) contactSearchAction
172 id <WOActionResults> result;
175 contact = [self queryParameterForKey: @"search"];
176 if ([contact length] > 0)
178 um = [LDAPUserManager sharedUserManager];
180 = [self _responseForResults: [um fetchContactsMatching: contact]];
183 result = [NSException exceptionWithHTTPStatus: 400
184 reason: @"missing 'search' parameter"];
189 - (NSArray *) _gcsFoldersFromFolder: (SOGoContactFolders *) contactFolders
191 NSMutableArray *gcsFolders;
192 NSEnumerator *contactSubfolders;
193 SOGoContactGCSFolder *currentContactFolder;
194 NSString *folderName, *displayName;
195 NSMutableDictionary *currentDictionary;
197 gcsFolders = [NSMutableArray new];
198 [gcsFolders autorelease];
200 contactSubfolders = [[contactFolders contactFolders] objectEnumerator];
201 currentContactFolder = [contactSubfolders nextObject];
202 while (currentContactFolder)
204 if ([currentContactFolder
205 isKindOfClass: [SOGoContactGCSFolder class]])
207 folderName = [NSString stringWithFormat: @"/Contacts/%@",
208 [currentContactFolder nameInContainer]];
209 currentDictionary = [NSMutableDictionary new];
210 [currentDictionary autorelease];
211 displayName = [[currentContactFolder ocsFolder] folderName];
212 [currentDictionary setObject: displayName forKey: @"displayName"];
213 [currentDictionary setObject: folderName forKey: @"name"];
214 [currentDictionary setObject: @"contact" forKey: @"type"];
215 [gcsFolders addObject: currentDictionary];
217 currentContactFolder = [contactSubfolders nextObject];
223 - (NSArray *) _foldersForUID: (NSString *) uid
224 ofType: (NSString *) folderType
226 NSObject *topFolder, *userFolder;
227 SOGoContactFolders *contactFolders;
228 NSMutableArray *folders;
229 NSMutableDictionary *currentDictionary;
231 folders = [NSMutableArray new];
232 [folders autorelease];
234 topFolder = [[[self clientObject] container] container];
235 userFolder = [topFolder lookupName: uid inContext: context acquire: NO];
237 /* FIXME: should be moved in the SOGo* classes. Maybe by having a SOGoFolderManager. */
238 #warning this might need adjustments whenever we permit multiple calendar folders per-user
239 if ([folderType length] == 0 || [folderType isEqualToString: @"calendar"])
241 currentDictionary = [NSMutableDictionary new];
242 [currentDictionary autorelease];
243 [currentDictionary setObject: [self labelForKey: @"Calendar"]
244 forKey: @"displayName"];
245 [currentDictionary setObject: @"/Calendar" forKey: @"name"];
246 [currentDictionary setObject: @"calendar" forKey: @"type"];
247 [folders addObject: currentDictionary];
249 if ([folderType length] == 0 || [folderType isEqualToString: @"contact"])
251 contactFolders = [userFolder lookupName: @"Contacts"
252 inContext: context acquire: NO];
254 addObjectsFromArray: [self _gcsFoldersFromFolder: contactFolders]];
260 - (NSString *) _foldersStringForFolders: (NSEnumerator *) folders
262 NSMutableString *foldersString;
263 NSDictionary *currentFolder;
265 foldersString = [NSMutableString new];
266 [foldersString autorelease];
268 currentFolder = [folders nextObject];
269 while (currentFolder)
271 [foldersString appendFormat: @";%@:%@:%@",
272 [currentFolder objectForKey: @"displayName"],
273 [currentFolder objectForKey: @"name"],
274 [currentFolder objectForKey: @"type"]];
275 currentFolder = [folders nextObject];
278 return foldersString;
281 - (WOResponse *) _foldersResponseForResults: (NSArray *) results
282 withType: (NSString *) folderType
284 WOResponse *response;
285 NSString *uid, *foldersString;
286 NSMutableString *responseString;
287 NSDictionary *contact;
288 NSEnumerator *contacts;
291 response = [context response];
295 [response setStatus: 200];
296 [response setHeader: @"text/plain; charset=utf-8"
297 forKey: @"Content-Type"];
299 responseString = [NSMutableString new];
300 contacts = [results objectEnumerator];
301 contact = [contacts nextObject];
304 uid = [contact objectForKey: @"c_uid"];
305 folders = [self _foldersForUID: uid ofType: folderType];
307 = [self _foldersStringForFolders: [folders objectEnumerator]];
308 [responseString appendFormat: @"%@:%@:%@%@\n", uid,
309 [contact objectForKey: @"cn"],
310 [contact objectForKey: @"c_email"],
312 contact = [contacts nextObject];
314 [response appendContentString: responseString];
315 [responseString release];
318 [response setStatus: 404];
323 - (id <WOActionResults>) foldersSearchAction
325 NSString *contact, *folderType;
326 id <WOActionResults> result;
329 um = [LDAPUserManager sharedUserManager];
330 contact = [self queryParameterForKey: @"search"];
331 if ([contact length] > 0)
333 folderType = [self queryParameterForKey: @"type"];
335 = [self _foldersResponseForResults: [um fetchContactsMatching: contact]
336 withType: folderType];
339 result = [NSException exceptionWithHTTPStatus: 400
340 reason: @"missing 'search' parameter"];
345 - (SOGoContactGCSFolder *) contactFolderForUID: (NSString *) uid
347 SOGoFolder *upperContainer;
348 SOGoUserFolder *userFolder;
349 SOGoContactFolders *contactFolders;
350 SOGoContactGCSFolder *contactFolder;
351 SoSecurityManager *securityManager;
353 upperContainer = [[[self clientObject] container] container];
354 userFolder = [SOGoUserFolder objectWithName: uid
355 inContainer: upperContainer];
356 contactFolders = [SOGoContactFolders objectWithName: @"Contacts"
357 inContainer: userFolder];
358 contactFolder = [SOGoContactGCSFolder objectWithName: @"personal"
359 inContainer: contactFolders];
361 setOCSPath: [NSString stringWithFormat: @"/Users/%@/Contacts/personal", uid]];
362 [contactFolder setOwner: uid];
364 securityManager = [SoSecurityManager sharedSecurityManager];
366 return (([securityManager validatePermission: SoPerm_AccessContentsInformation
367 onObject: contactFolder
368 inContext: context] == nil)
369 ? contactFolder : nil);