/* UIxContactFoldersView.m - this file is part of SOGo * * Copyright (C) 2006 Inverse groupe conseil * * Author: Wolfgang Sourdeau * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This file 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #import #import #import #import #import #import #import #import #import #import #import #import #import #import #import "common.h" #import "UIxContactFoldersView.h" @implementation UIxContactFoldersView - (id) _selectActionForApplication: (NSString *) actionName { SOGoContactFolders *folders; NSString *url, *action; WORequest *request; folders = [self clientObject]; action = [NSString stringWithFormat: @"../%@/%@", [folders defaultSourceName], actionName]; request = [[self context] request]; url = [[request uri] composeURLWithAction: action parameters: [self queryParameters] andHash: NO]; return [self redirectToLocation: url]; } - (id) defaultAction { return [self _selectActionForApplication: @"view"]; } - (id) newAction { return [self _selectActionForApplication: @"new"]; } - (id ) newAbAction { id response; NSString *name; name = [self queryParameterForKey: @"name"]; if ([name length] > 0) response = [[self clientObject] newFolderWithName: name]; else response = [NSException exceptionWithHTTPStatus: 400 reason: @"The name is missing"]; return response; } - (id) selectForMailerAction { return [self _selectActionForApplication: @"mailer-contacts"]; } - (void) _fillResults: (NSMutableDictionary *) results inFolder: (id ) folder withSearchOn: (NSString *) contact { NSEnumerator *folderResults; NSDictionary *currentContact; NSString *uid; folderResults = [[folder lookupContactsWithFilter: contact sortBy: @"cn" ordering: NSOrderedAscending] objectEnumerator]; currentContact = [folderResults nextObject]; while (currentContact) { uid = [currentContact objectForKey: @"c_uid"]; if (uid && ![results objectForKey: uid]) [results setObject: currentContact forKey: uid]; currentContact = [folderResults nextObject]; } } - (NSString *) _emailForResult: (NSDictionary *) result { NSMutableString *email; NSString *name, *mail; email = [NSMutableString string]; name = [result objectForKey: @"displayName"]; if (![name length]) name = [result objectForKey: @"cn"]; mail = [result objectForKey: @"mail"]; if ([name length]) [email appendFormat: @"%@ <%@>", name, mail]; else [email appendString: mail]; return email; } - (WOResponse *) _responseForResults: (NSArray *) results { WOResponse *response; NSEnumerator *contacts; NSString *responseString; NSDictionary *contact; response = [context response]; if ([results count] > 0) { contacts = [results objectEnumerator]; contact = [contacts nextObject]; if (contact) { responseString = [NSString stringWithFormat: @"%@:%@:%@", [contact objectForKey: @"c_uid"], [contact objectForKey: @"cn"], [contact objectForKey: @"c_email"]]; [response setStatus: 200]; // [response setHeader: @"text/plain; charset=iso-8859-1" // forKey: @"Content-Type"]; [response appendContentString: responseString]; // contact = [contacts nextObject]; } } else [response setStatus: 404]; return response; } - (id ) contactSearchAction { NSString *contact; id result; LDAPUserManager *um; contact = [self queryParameterForKey: @"search"]; if ([contact length] > 0) { um = [LDAPUserManager sharedUserManager]; result = [self _responseForResults: [um fetchContactsMatching: contact]]; } else result = [NSException exceptionWithHTTPStatus: 400 reason: @"missing 'search' parameter"]; return result; } - (NSArray *) _gcsFoldersFromFolder: (SOGoContactFolders *) contactFolders { NSMutableArray *gcsFolders; NSEnumerator *contactSubfolders; SOGoContactGCSFolder *currentContactFolder; NSString *folderName, *displayName; NSMutableDictionary *currentDictionary; gcsFolders = [NSMutableArray new]; [gcsFolders autorelease]; contactSubfolders = [[contactFolders contactFolders] objectEnumerator]; currentContactFolder = [contactSubfolders nextObject]; while (currentContactFolder) { if ([currentContactFolder isKindOfClass: [SOGoContactGCSFolder class]]) { folderName = [NSString stringWithFormat: @"/Contacts/%@", [currentContactFolder nameInContainer]]; currentDictionary = [NSMutableDictionary new]; [currentDictionary autorelease]; displayName = [[currentContactFolder ocsFolder] folderName]; [currentDictionary setObject: displayName forKey: @"displayName"]; [currentDictionary setObject: folderName forKey: @"name"]; [currentDictionary setObject: @"contact" forKey: @"type"]; [gcsFolders addObject: currentDictionary]; } currentContactFolder = [contactSubfolders nextObject]; } return gcsFolders; } - (NSArray *) _foldersForUID: (NSString *) uid ofType: (NSString *) folderType { NSObject *topFolder, *userFolder; SOGoContactFolders *contactFolders; NSMutableArray *folders; NSMutableDictionary *currentDictionary; folders = [NSMutableArray new]; [folders autorelease]; topFolder = [[[self clientObject] container] container]; userFolder = [topFolder lookupName: uid inContext: context acquire: NO]; /* FIXME: should be moved in the SOGo* classes. Maybe by having a SOGoFolderManager. */ #warning this might need adjustments whenever we permit multiple calendar folders per-user if ([folderType length] == 0 || [folderType isEqualToString: @"calendar"]) { currentDictionary = [NSMutableDictionary new]; [currentDictionary autorelease]; [currentDictionary setObject: [self labelForKey: @"Calendar"] forKey: @"displayName"]; [currentDictionary setObject: @"/Calendar" forKey: @"name"]; [currentDictionary setObject: @"calendar" forKey: @"type"]; [folders addObject: currentDictionary]; } if ([folderType length] == 0 || [folderType isEqualToString: @"contact"]) { contactFolders = [userFolder lookupName: @"Contacts" inContext: context acquire: NO]; [folders addObjectsFromArray: [self _gcsFoldersFromFolder: contactFolders]]; } return folders; } - (NSString *) _foldersStringForFolders: (NSEnumerator *) folders { NSMutableString *foldersString; NSDictionary *currentFolder; foldersString = [NSMutableString new]; [foldersString autorelease]; currentFolder = [folders nextObject]; while (currentFolder) { [foldersString appendFormat: @";%@:%@:%@", [currentFolder objectForKey: @"displayName"], [currentFolder objectForKey: @"name"], [currentFolder objectForKey: @"type"]]; currentFolder = [folders nextObject]; } return foldersString; } - (WOResponse *) _foldersResponseForResults: (NSArray *) results withType: (NSString *) folderType { WOResponse *response; NSString *uid, *foldersString; NSMutableString *responseString; NSDictionary *contact; NSEnumerator *contacts; NSArray *folders; response = [context response]; if ([results count]) { [response setStatus: 200]; [response setHeader: @"text/plain; charset=utf-8" forKey: @"Content-Type"]; responseString = [NSMutableString new]; contacts = [results objectEnumerator]; contact = [contacts nextObject]; while (contact) { uid = [contact objectForKey: @"c_uid"]; folders = [self _foldersForUID: uid ofType: folderType]; foldersString = [self _foldersStringForFolders: [folders objectEnumerator]]; [responseString appendFormat: @"%@:%@:%@%@\n", uid, [contact objectForKey: @"cn"], [contact objectForKey: @"c_email"], foldersString]; contact = [contacts nextObject]; } [response appendContentString: responseString]; [responseString release]; } else [response setStatus: 404]; return response; } - (id ) foldersSearchAction { NSString *contact, *folderType; id result; LDAPUserManager *um; um = [LDAPUserManager sharedUserManager]; contact = [self queryParameterForKey: @"search"]; if ([contact length] > 0) { folderType = [self queryParameterForKey: @"type"]; result = [self _foldersResponseForResults: [um fetchContactsMatching: contact] withType: folderType]; } else result = [NSException exceptionWithHTTPStatus: 400 reason: @"missing 'search' parameter"]; return result; } - (SOGoContactGCSFolder *) contactFolderForUID: (NSString *) uid { SOGoFolder *upperContainer; SOGoUserFolder *userFolder; SOGoContactFolders *contactFolders; SOGoContactGCSFolder *contactFolder; SoSecurityManager *securityManager; upperContainer = [[[self clientObject] container] container]; userFolder = [SOGoUserFolder objectWithName: uid inContainer: upperContainer]; contactFolders = [SOGoContactFolders objectWithName: @"Contacts" inContainer: userFolder]; contactFolder = [SOGoContactGCSFolder objectWithName: @"personal" inContainer: contactFolders]; [contactFolder setOCSPath: [NSString stringWithFormat: @"/Users/%@/Contacts/personal", uid]]; [contactFolder setOwner: uid]; securityManager = [SoSecurityManager sharedSecurityManager]; return (([securityManager validatePermission: SoPerm_AccessContentsInformation onObject: contactFolder inContext: context] == nil) ? contactFolder : nil); } @end