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/SoSecurityManager.h>
28 #import <NGObjWeb/WOContext.h>
29 #import <NGObjWeb/WORequest.h>
30 #import <NGObjWeb/WOResponse.h>
32 #import <GDLContentStore/GCSFolder.h>
33 #import <GDLContentStore/GCSFolderManager.h>
35 #import <SoObjects/SOGo/LDAPUserManager.h>
36 #import <SoObjects/SOGo/SOGoPermissions.h>
37 #import <SoObjects/SOGo/SOGoUser.h>
38 #import <SoObjects/SOGo/NSArray+Utilities.h>
39 #import <SoObjects/SOGo/NSString+Utilities.h>
40 #import <SoObjects/Contacts/SOGoContactFolders.h>
41 #import <SoObjects/Contacts/SOGoContactFolder.h>
42 #import <SoObjects/Contacts/SOGoContactGCSFolder.h>
43 #import <SoObjects/Contacts/SOGoContactLDAPFolder.h>
45 #import "UIxContactFoldersView.h"
47 @implementation UIxContactFoldersView
49 - (id) _selectActionForApplication: (NSString *) actionName
51 SOGoContactFolders *folders;
52 NSString *url, *action;
55 folders = [self clientObject];
56 action = [NSString stringWithFormat: @"../personal/%@", actionName];
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) selectForMailerAction
79 return [self _selectActionForApplication: @"mailer-contacts"];
82 - (void) _fillResults: (NSMutableDictionary *) results
83 inFolder: (id <SOGoContactFolder>) folder
84 withSearchOn: (NSString *) contact
86 NSEnumerator *folderResults;
87 NSDictionary *currentContact;
90 folderResults = [[folder lookupContactsWithFilter: contact
92 ordering: NSOrderedAscending] objectEnumerator];
93 currentContact = [folderResults nextObject];
94 while (currentContact)
96 uid = [currentContact objectForKey: @"c_uid"];
97 if (uid && ![results objectForKey: uid])
98 [results setObject: currentContact forKey: uid];
99 currentContact = [folderResults nextObject];
103 - (NSString *) _emailForResult: (NSDictionary *) result
105 NSMutableString *email;
106 NSString *name, *mail;
108 email = [NSMutableString string];
109 name = [result objectForKey: @"displayName"];
111 name = [result objectForKey: @"cn"];
112 mail = [result objectForKey: @"mail"];
114 [email appendFormat: @"%@ <%@>", name, mail];
116 [email appendString: mail];
121 - (WOResponse *) _responseForResults: (NSArray *) results
123 WOResponse *response;
124 NSEnumerator *contacts;
126 NSDictionary *contact;
127 NSMutableArray *formattedContacts;
128 NSMutableDictionary *formattedContact;
130 response = [context response];
132 if ([results count] > 0)
134 [response setStatus: 200];
135 contacts = [results objectEnumerator];
136 contact = [contacts nextObject];
137 formattedContacts = [[NSMutableArray alloc] initWithCapacity: [results count]];
140 email = [contact objectForKey: @"c_email"];
143 formattedContact = [NSMutableDictionary dictionary];
144 [formattedContact setObject: [contact objectForKey: @"c_uid"]
146 [formattedContact setObject: [contact objectForKey: @"cn"]
148 [formattedContact setObject: email
150 [formattedContacts addObject: formattedContact];
152 contact = [contacts nextObject];
154 [response appendContentString: [formattedContacts jsonRepresentation]];
155 [formattedContacts release];
158 [response setStatus: 404];
163 - (id <WOActionResults>) contactSearchAction
166 id <WOActionResults> result;
169 contact = [self queryParameterForKey: @"search"];
170 if ([contact length] > 0)
172 um = [LDAPUserManager sharedUserManager];
174 = [self _responseForResults: [um fetchContactsMatching: contact]];
177 result = [NSException exceptionWithHTTPStatus: 400
178 reason: @"missing 'search' parameter"];
183 - (NSArray *) _subFoldersFromFolder: (SOGoParentFolder *) parentFolder
185 NSMutableArray *folders;
186 NSEnumerator *subfolders;
187 SOGoGCSFolder *currentFolder;
188 NSString *folderName;
189 NSMutableDictionary *currentDictionary;
190 SoSecurityManager *securityManager;
192 securityManager = [SoSecurityManager sharedSecurityManager];
194 // return (([securityManager validatePermission: SoPerm_AccessContentsInformation
195 // onObject: contactFolder
196 // inContext: context] == nil)
198 folders = [NSMutableArray new];
199 [folders autorelease];
201 subfolders = [[parentFolder subFolders] objectEnumerator];
202 while ((currentFolder = [subfolders nextObject]))
204 if (![securityManager validatePermission: SOGoPerm_AccessObject
205 onObject: currentFolder inContext: context])
207 folderName = [NSString stringWithFormat: @"/%@/%@",
208 [parentFolder nameInContainer],
209 [currentFolder nameInContainer]];
211 = [NSMutableDictionary dictionaryWithCapacity: 3];
212 [currentDictionary setObject: [currentFolder displayName]
213 forKey: @"displayName"];
214 [currentDictionary setObject: folderName forKey: @"name"];
215 [currentDictionary setObject: [currentFolder folderType]
217 [folders addObject: currentDictionary];
224 - (NSArray *) _foldersForUID: (NSString *) uid
225 ofType: (NSString *) folderType
227 NSObject *topFolder, *userFolder;
228 SOGoParentFolder *parentFolder;
229 NSMutableArray *folders;
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 if ([folderType length] == 0 || [folderType isEqualToString: @"calendar"])
240 parentFolder = [userFolder lookupName: @"Calendar"
241 inContext: context acquire: NO];
243 addObjectsFromArray: [self _subFoldersFromFolder: parentFolder]];
245 if ([folderType length] == 0 || [folderType isEqualToString: @"contact"])
247 parentFolder = [userFolder lookupName: @"Contacts"
248 inContext: context acquire: NO];
250 addObjectsFromArray: [self _subFoldersFromFolder: parentFolder]];
256 - (NSString *) _foldersStringForFolders: (NSEnumerator *) folders
258 NSMutableString *foldersString;
259 NSDictionary *currentFolder;
261 foldersString = [NSMutableString new];
262 [foldersString autorelease];
264 currentFolder = [folders nextObject];
265 while (currentFolder)
267 [foldersString appendFormat: @";%@:%@:%@",
268 [currentFolder objectForKey: @"displayName"],
269 [currentFolder objectForKey: @"name"],
270 [currentFolder objectForKey: @"type"]];
271 currentFolder = [folders nextObject];
274 return foldersString;
277 - (WOResponse *) _foldersResponseForResults: (NSArray *) results
278 withType: (NSString *) folderType
280 WOResponse *response;
281 NSString *uid, *foldersString;
282 NSMutableString *responseString;
283 NSDictionary *contact;
284 NSEnumerator *contacts;
287 response = [context response];
291 [response setStatus: 200];
292 [response setHeader: @"text/plain; charset=utf-8"
293 forKey: @"Content-Type"];
295 responseString = [NSMutableString new];
296 contacts = [results objectEnumerator];
297 while ((contact = [contacts nextObject]))
299 uid = [contact objectForKey: @"c_uid"];
300 folders = [self _foldersForUID: uid ofType: folderType];
302 = [self _foldersStringForFolders: [folders objectEnumerator]];
303 [responseString appendFormat: @"%@:%@:%@%@\n", uid,
304 [contact objectForKey: @"cn"],
305 [contact objectForKey: @"c_email"],
308 [response appendContentString: responseString];
309 [responseString release];
312 [response setStatus: 404];
317 - (id <WOActionResults>) foldersSearchAction
319 NSString *contact, *folderType;
320 id <WOActionResults> result;
323 um = [LDAPUserManager sharedUserManager];
324 contact = [self queryParameterForKey: @"search"];
325 if ([contact length] > 0)
327 folderType = [self queryParameterForKey: @"type"];
329 = [self _foldersResponseForResults: [um fetchContactsMatching: contact]
330 withType: folderType];
333 result = [NSException exceptionWithHTTPStatus: 400
334 reason: @"missing 'search' parameter"];
339 // - (SOGoContactGCSFolder *) contactFolderForUID: (NSString *) uid
341 // SOGoFolder *upperContainer;
342 // SOGoUserFolder *userFolder;
343 // SOGoContactFolders *contactFolders;
344 // SOGoContactGCSFolder *contactFolder;
345 // SoSecurityManager *securityManager;
347 // upperContainer = [[[self clientObject] container] container];
348 // userFolder = [SOGoUserFolder objectWithName: uid
349 // inContainer: upperContainer];
350 // contactFolders = [SOGoUserFolder lookupName: @"Contacts"
351 // inContext: context
353 // contactFolder = [contactFolders lookupName: @"personal"
354 // inContext: context
357 // securityManager = [SoSecurityManager sharedSecurityManager];
359 // return (([securityManager validatePermission: SoPerm_AccessContentsInformation
360 // onObject: contactFolder
361 // inContext: context] == nil)
362 // ? contactFolder : nil);