]> err.no Git - scalable-opengroupware.org/blob - UI/Contacts/UIxContactFoldersView.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1073 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / UI / Contacts / UIxContactFoldersView.m
1 /* UIxContactFoldersView.m - this file is part of SOGo
2  *
3  * Copyright (C) 2006 Inverse groupe conseil
4  *
5  * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
6  *
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)
10  * any later version.
11  *
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.
16  *
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.
21  */
22
23 #import <Foundation/NSString.h>
24
25 #import <NGObjWeb/NSException+HTTP.h>
26 #import <NGObjWeb/SoObject.h>
27 #import <NGObjWeb/WOResponse.h>
28 #import <NGObjWeb/WOContext.h>
29
30 #import <GDLContentStore/GCSFolder.h>
31 #import <GDLContentStore/GCSFolderManager.h>
32
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>
40
41 #import "common.h"
42
43 #import "UIxContactFoldersView.h"
44
45 @implementation UIxContactFoldersView
46
47 - (id) _selectActionForApplication: (NSString *) actionName
48 {
49   SOGoContactFolders *folders;
50   NSString *url, *action;
51   WORequest *request;
52
53   folders = [self clientObject];
54   action = [NSString stringWithFormat: @"../%@/%@",
55                      [folders defaultSourceName],
56                      actionName];
57
58   request = [[self context] request];
59
60   url = [[request uri] composeURLWithAction: action
61                        parameters: [self queryParameters]
62                        andHash: NO];
63
64   return [self redirectToLocation: url];
65 }
66
67 - (id) defaultAction
68 {
69   return [self _selectActionForApplication: @"view"];
70 }
71
72 - (id) newAction
73 {
74   return [self _selectActionForApplication: @"new"];
75 }
76
77 - (id <WOActionResults>) newAbAction
78 {
79   id <WOActionResults> response;
80   NSString *name;
81
82   name = [self queryParameterForKey: @"name"];
83   if ([name length] > 0)
84     response = [[self clientObject] newFolderWithName: name];
85   else
86     response = [NSException exceptionWithHTTPStatus: 400
87                             reason: @"The name is missing"];
88   
89   return response;
90 }
91
92 - (id) selectForMailerAction
93 {
94   return [self _selectActionForApplication: @"mailer-contacts"];
95 }
96
97 - (void) _fillResults: (NSMutableDictionary *) results
98              inFolder: (id <SOGoContactFolder>) folder
99          withSearchOn: (NSString *) contact
100 {
101   NSEnumerator *folderResults;
102   NSDictionary *currentContact;
103   NSString *uid;
104
105   folderResults = [[folder lookupContactsWithFilter: contact
106                            sortBy: @"cn"
107                            ordering: NSOrderedAscending] objectEnumerator];
108   currentContact = [folderResults nextObject];
109   while (currentContact)
110     {
111       uid = [currentContact objectForKey: @"c_uid"];
112       if (uid && ![results objectForKey: uid])
113         [results setObject: currentContact
114                  forKey: uid];
115       currentContact = [folderResults nextObject];
116     }
117 }
118
119 - (NSString *) _emailForResult: (NSDictionary *) result
120 {
121   NSMutableString *email;
122   NSString *name, *mail;
123
124   email = [NSMutableString string];
125   name = [result objectForKey: @"displayName"];
126   if (![name length])
127     name = [result objectForKey: @"cn"];
128   mail = [result objectForKey: @"mail"];
129   if ([name length])
130     [email appendFormat: @"%@ <%@>", name, mail];
131   else
132     [email appendString: mail];
133
134   return email;
135 }
136
137 - (WOResponse *) _responseForResults: (NSArray *) results
138 {
139   WOResponse *response;
140   NSEnumerator *contacts;
141   NSString *responseString;
142   NSDictionary *contact;
143
144   response = [context response];
145
146   if ([results count] > 0)
147     {
148       contacts = [results objectEnumerator];
149       contact = [contacts nextObject];
150       while (contact)
151         {
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];
161         }
162     }
163   else
164     [response setStatus: 404];
165
166   return response;
167 }
168
169 - (id <WOActionResults>) contactSearchAction
170 {
171   NSString *contact;
172   id <WOActionResults> result;
173   LDAPUserManager *um;
174   
175   contact = [self queryParameterForKey: @"search"];
176   if ([contact length] > 0)
177     {
178       um = [LDAPUserManager sharedUserManager];
179       result
180         = [self _responseForResults: [um fetchContactsMatching: contact]];
181     }
182   else
183     result = [NSException exceptionWithHTTPStatus: 400
184                           reason: @"missing 'search' parameter"];
185   
186   return result;
187 }
188
189 - (NSArray *) _gcsFoldersFromFolder: (SOGoContactFolders *) contactFolders
190 {
191   NSMutableArray *gcsFolders;
192   NSEnumerator *contactSubfolders;
193   SOGoContactGCSFolder *currentContactFolder;
194   NSString *folderName, *displayName;
195   NSMutableDictionary *currentDictionary;
196
197   gcsFolders = [NSMutableArray new];
198   [gcsFolders autorelease];
199
200   contactSubfolders = [[contactFolders contactFolders] objectEnumerator];
201   currentContactFolder = [contactSubfolders nextObject];
202   while (currentContactFolder)
203     {
204       if ([currentContactFolder
205             isKindOfClass: [SOGoContactGCSFolder class]])
206         {
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];
216         }
217       currentContactFolder = [contactSubfolders nextObject];
218     }
219
220   return gcsFolders;
221 }
222
223 - (NSArray *) _foldersForUID: (NSString *) uid
224                       ofType: (NSString *) folderType
225 {
226   NSObject *topFolder, *userFolder;
227   SOGoContactFolders *contactFolders;
228   NSMutableArray *folders;
229   NSMutableDictionary *currentDictionary;
230
231   folders = [NSMutableArray new];
232   [folders autorelease];
233
234   topFolder = [[[self clientObject] container] container];
235   userFolder = [topFolder lookupName: uid inContext: context acquire: NO];
236
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"])
240     {
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];
248     }
249   if ([folderType length] == 0 || [folderType isEqualToString: @"contact"])
250     {
251       contactFolders = [userFolder lookupName: @"Contacts"
252                                    inContext: context acquire: NO];
253       [folders
254         addObjectsFromArray: [self _gcsFoldersFromFolder: contactFolders]];
255     }
256
257   return folders;
258 }
259
260 - (NSString *) _foldersStringForFolders: (NSEnumerator *) folders
261 {
262   NSMutableString *foldersString;
263   NSDictionary *currentFolder;
264
265   foldersString = [NSMutableString new];
266   [foldersString autorelease];
267
268   currentFolder = [folders nextObject];
269   while (currentFolder)
270     {
271       [foldersString appendFormat: @";%@:%@:%@",
272                      [currentFolder objectForKey: @"displayName"],
273                      [currentFolder objectForKey: @"name"],
274                      [currentFolder objectForKey: @"type"]];
275       currentFolder = [folders nextObject];
276     }
277
278   return foldersString;
279 }
280
281 - (WOResponse *) _foldersResponseForResults: (NSArray *) results
282                                    withType: (NSString *) folderType
283 {
284   WOResponse *response;
285   NSString *uid, *foldersString;
286   NSMutableString *responseString;
287   NSDictionary *contact;
288   NSEnumerator *contacts;
289   NSArray *folders;
290
291   response = [context response];
292
293   if ([results count])
294     {
295       [response setStatus: 200];
296       [response setHeader: @"text/plain; charset=utf-8"
297                 forKey: @"Content-Type"];
298
299       responseString = [NSMutableString new];
300       contacts = [results objectEnumerator];
301       contact = [contacts nextObject];
302       while (contact)
303         {
304           uid = [contact objectForKey: @"c_uid"];
305           folders = [self _foldersForUID: uid ofType: folderType];
306           foldersString
307             = [self _foldersStringForFolders: [folders objectEnumerator]];
308           [responseString appendFormat: @"%@:%@:%@%@\n", uid,
309                           [contact objectForKey: @"cn"],
310                           [contact objectForKey: @"c_email"],
311                           foldersString];
312           contact = [contacts nextObject];
313         }
314       [response appendContentString: responseString];
315       [responseString release];
316     }
317   else
318     [response setStatus: 404];
319
320   return response;
321 }
322
323 - (id <WOActionResults>) foldersSearchAction
324 {
325   NSString *contact, *folderType;
326   id <WOActionResults> result;
327   LDAPUserManager *um;
328
329   um = [LDAPUserManager sharedUserManager];
330   contact = [self queryParameterForKey: @"search"];
331   if ([contact length] > 0)
332     {
333       folderType = [self queryParameterForKey: @"type"];
334       result
335         = [self _foldersResponseForResults: [um fetchContactsMatching: contact]
336                 withType: folderType];
337     }
338   else
339     result = [NSException exceptionWithHTTPStatus: 400
340                           reason: @"missing 'search' parameter"];
341
342   return result;
343 }
344
345 - (SOGoContactGCSFolder *) contactFolderForUID: (NSString *) uid
346 {
347   SOGoFolder *upperContainer;
348   SOGoUserFolder *userFolder;
349   SOGoContactFolders *contactFolders;
350   SOGoContactGCSFolder *contactFolder;
351   SoSecurityManager *securityManager;
352
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];
360   [contactFolder
361     setOCSPath: [NSString stringWithFormat: @"/Users/%@/Contacts/personal", uid]];
362   [contactFolder setOwner: uid];
363
364   securityManager = [SoSecurityManager sharedSecurityManager];
365
366   return (([securityManager validatePermission: SoPerm_AccessContentsInformation
367                             onObject: contactFolder
368                             inContext: context] == nil)
369           ? contactFolder : nil);
370 }
371
372 @end