2006-06-15 21:34:10 +02:00
|
|
|
/*
|
|
|
|
Copyright (C) 2004-2005 SKYRIX Software AG
|
2017-03-03 16:35:23 +01:00
|
|
|
Copyright (C) 2005-2017 Inverse inc.
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2010-06-30 18:53:23 +02:00
|
|
|
This file is part of SOGo
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2010-06-30 18:53:23 +02:00
|
|
|
SOGo is free software; you can redistribute it and/or modify it under
|
2006-06-15 21:34:10 +02:00
|
|
|
the terms of the GNU Lesser General Public License as published by the
|
|
|
|
Free Software Foundation; either version 2, or (at your option) any
|
|
|
|
later version.
|
|
|
|
|
2010-06-30 18:53:23 +02:00
|
|
|
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
2006-06-15 21:34:10 +02:00
|
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
|
|
License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
2014-09-03 20:19:46 +02:00
|
|
|
License along with SOGo; see the file COPYING. If not, write to the
|
2006-06-15 21:34:10 +02:00
|
|
|
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2010-07-16 21:35:25 +02:00
|
|
|
#import <Foundation/NSURL.h>
|
2014-09-05 21:12:05 +02:00
|
|
|
#import <Foundation/NSCalendarDate.h>
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-05-09 21:23:45 +02:00
|
|
|
#import <NGObjWeb/NSException+HTTP.h>
|
2008-07-16 06:17:46 +02:00
|
|
|
#import <NGObjWeb/SoPermissions.h>
|
|
|
|
#import <NGObjWeb/SoSecurityManager.h>
|
2020-07-22 21:03:01 +02:00
|
|
|
#import <NGObjWeb/WOContext+SoObjects.h>
|
2007-05-09 21:23:45 +02:00
|
|
|
#import <NGObjWeb/WORequest.h>
|
2008-03-07 23:09:33 +01:00
|
|
|
#import <NGObjWeb/WOResponse.h>
|
2007-05-09 21:23:45 +02:00
|
|
|
#import <NGExtensions/NSNull+misc.h>
|
|
|
|
|
2016-04-06 04:03:52 +02:00
|
|
|
#import <SOGo/CardElement+SOGo.h>
|
2010-10-26 21:23:08 +02:00
|
|
|
#import <SOGo/NSArray+Utilities.h>
|
2014-08-20 21:25:42 +02:00
|
|
|
#import <SOGo/NSDictionary+Utilities.h>
|
2010-10-26 21:23:08 +02:00
|
|
|
#import <SOGo/NSString+Utilities.h>
|
|
|
|
#import <SOGo/SOGoUser.h>
|
|
|
|
#import <SOGo/SOGoUserDefaults.h>
|
|
|
|
|
2014-09-03 20:19:46 +02:00
|
|
|
#import <Contacts/NGVCard+SOGo.h>
|
2008-07-16 06:17:46 +02:00
|
|
|
#import <Contacts/SOGoContactFolders.h>
|
2008-03-07 23:09:33 +01:00
|
|
|
#import <Contacts/SOGoContactGCSEntry.h>
|
|
|
|
#import <Contacts/SOGoContactGCSFolder.h>
|
2006-09-16 00:23:29 +02:00
|
|
|
|
|
|
|
#import "UIxContactEditor.h"
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2011-12-30 21:39:07 +01:00
|
|
|
static Class SOGoContactGCSEntryK = Nil;
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
@implementation UIxContactEditor
|
2006-09-16 00:23:29 +02:00
|
|
|
|
2011-12-30 21:39:07 +01:00
|
|
|
+ (void) initialize
|
|
|
|
{
|
|
|
|
SOGoContactGCSEntryK = [SOGoContactGCSEntry class];
|
|
|
|
}
|
|
|
|
|
2006-09-19 23:03:12 +02:00
|
|
|
- (id) init
|
|
|
|
{
|
|
|
|
if ((self = [super init]))
|
|
|
|
{
|
2011-12-30 21:39:07 +01:00
|
|
|
ldifRecord = nil;
|
2010-10-26 21:23:08 +02:00
|
|
|
addressBookItem = nil;
|
|
|
|
item = nil;
|
|
|
|
componentAddressBook = nil;
|
2006-09-19 23:03:12 +02:00
|
|
|
}
|
|
|
|
|
2006-09-16 00:23:29 +02:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2006-09-19 23:03:12 +02:00
|
|
|
- (void) dealloc
|
|
|
|
{
|
2011-12-30 21:39:07 +01:00
|
|
|
[ldifRecord release];
|
2010-10-26 21:23:08 +02:00
|
|
|
[addressBookItem release];
|
|
|
|
[item release];
|
|
|
|
[componentAddressBook release];
|
2006-09-16 00:23:29 +02:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* accessors */
|
|
|
|
|
2011-12-30 21:39:07 +01:00
|
|
|
- (NSMutableDictionary *) ldifRecord
|
|
|
|
{
|
|
|
|
NSDictionary *clientLDIFRecord;
|
|
|
|
NSString *queryValue;
|
|
|
|
|
|
|
|
if (!ldifRecord)
|
|
|
|
{
|
2012-03-21 16:50:07 +01:00
|
|
|
clientLDIFRecord = [[self clientObject] simplifiedLDIFRecord];
|
2011-12-30 21:39:07 +01:00
|
|
|
ldifRecord = [clientLDIFRecord mutableCopy];
|
|
|
|
queryValue = [self queryParameterForKey: @"contactEmail"];
|
|
|
|
if ([queryValue length] > 0)
|
|
|
|
[ldifRecord setObject: queryValue forKey: @"mail"];
|
|
|
|
queryValue = [self queryParameterForKey: @"contactFN"];
|
|
|
|
if ([queryValue length] > 0)
|
|
|
|
[ldifRecord setObject: queryValue forKey: @"displayname"];
|
|
|
|
}
|
|
|
|
|
|
|
|
return ldifRecord;
|
|
|
|
}
|
|
|
|
|
2008-07-16 06:17:46 +02:00
|
|
|
- (void) setAddressBookItem: (id) _item
|
|
|
|
{
|
|
|
|
ASSIGN (addressBookItem, _item);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) addressBookItem
|
|
|
|
{
|
|
|
|
return addressBookItem;
|
|
|
|
}
|
|
|
|
|
2007-03-22 20:02:45 +01:00
|
|
|
- (NSArray *) htmlMailFormatList
|
2006-09-16 00:23:29 +02:00
|
|
|
{
|
2007-03-22 20:02:45 +01:00
|
|
|
static NSArray *htmlMailFormatItems = nil;
|
|
|
|
|
|
|
|
if (!htmlMailFormatItems)
|
|
|
|
{
|
|
|
|
htmlMailFormatItems = [NSArray arrayWithObjects: @"FALSE", @"TRUE", nil];
|
|
|
|
[htmlMailFormatItems retain];
|
|
|
|
}
|
|
|
|
|
|
|
|
return htmlMailFormatItems;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) itemHtmlMailFormatText
|
|
|
|
{
|
|
|
|
return [self labelForKey:
|
|
|
|
[NSString stringWithFormat: @"htmlMailFormat_%@", item]];
|
2006-09-16 00:23:29 +02:00
|
|
|
}
|
|
|
|
|
2007-03-22 20:02:45 +01:00
|
|
|
- (void) setItem: (NSString *) newItem
|
2006-09-19 23:03:12 +02:00
|
|
|
{
|
2007-03-22 20:02:45 +01:00
|
|
|
item = newItem;
|
2006-09-16 00:23:29 +02:00
|
|
|
}
|
|
|
|
|
2007-03-22 20:02:45 +01:00
|
|
|
- (NSString *) item
|
2006-09-19 23:03:12 +02:00
|
|
|
{
|
2007-03-22 20:02:45 +01:00
|
|
|
return item;
|
2006-09-16 00:23:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* load/store content format */
|
|
|
|
|
|
|
|
/* helper */
|
|
|
|
|
2008-07-16 06:17:46 +02:00
|
|
|
- (BOOL) isNew
|
|
|
|
{
|
2011-12-30 21:39:07 +01:00
|
|
|
return ([[self clientObject] isNew]);
|
2008-07-16 06:17:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *) addressBooksList
|
|
|
|
{
|
|
|
|
NSEnumerator *folders;
|
|
|
|
NSMutableArray *addressBooksList;
|
|
|
|
SoSecurityManager *sm;
|
|
|
|
SOGoContactFolders *folderContainer;
|
2012-10-22 16:09:13 +02:00
|
|
|
id <SOGoContactFolder> folder, currentFolder;
|
2008-07-16 06:17:46 +02:00
|
|
|
|
2008-08-25 21:22:00 +02:00
|
|
|
addressBooksList = [NSMutableArray array];
|
2008-07-16 06:17:46 +02:00
|
|
|
sm = [SoSecurityManager sharedSecurityManager];
|
|
|
|
folderContainer = [[[self clientObject] container] container];
|
|
|
|
folders = [[folderContainer subFolders] objectEnumerator];
|
|
|
|
folder = [self componentAddressBook];
|
|
|
|
currentFolder = [folders nextObject];
|
|
|
|
|
|
|
|
while (currentFolder)
|
|
|
|
{
|
|
|
|
if ([currentFolder isEqual: folder] ||
|
2011-12-30 21:39:07 +01:00
|
|
|
![sm validatePermission: SoPerm_AddDocumentsImagesAndFiles
|
|
|
|
onObject: currentFolder
|
|
|
|
inContext: context])
|
2008-07-16 06:17:46 +02:00
|
|
|
[addressBooksList addObject: currentFolder];
|
|
|
|
currentFolder = [folders nextObject];
|
|
|
|
}
|
2011-12-30 21:39:07 +01:00
|
|
|
|
2008-07-16 06:17:46 +02:00
|
|
|
return addressBooksList;
|
|
|
|
}
|
|
|
|
|
2012-10-22 16:09:13 +02:00
|
|
|
- (id <SOGoContactFolder>) componentAddressBook
|
2008-07-16 06:17:46 +02:00
|
|
|
{
|
2012-10-22 16:09:13 +02:00
|
|
|
return [[self clientObject] container];
|
2008-07-16 06:17:46 +02:00
|
|
|
}
|
|
|
|
|
2012-10-22 16:09:13 +02:00
|
|
|
- (void) setComponentAddressBook: (id <SOGoContactFolder>) _componentAddressBook
|
2008-08-22 08:44:27 +02:00
|
|
|
{
|
|
|
|
ASSIGN (componentAddressBook, _componentAddressBook);
|
|
|
|
}
|
|
|
|
|
2008-07-16 06:17:46 +02:00
|
|
|
- (NSString *) addressBookDisplayName
|
|
|
|
{
|
2014-04-02 16:15:59 +02:00
|
|
|
return [addressBookItem displayName];
|
2008-07-16 06:17:46 +02:00
|
|
|
}
|
|
|
|
|
2006-09-16 00:23:29 +02:00
|
|
|
/* actions */
|
|
|
|
|
2014-06-19 21:51:57 +02:00
|
|
|
// - (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
|
|
|
|
// inContext: (WOContext*) context
|
|
|
|
// {
|
|
|
|
// NSString *actionName;
|
|
|
|
//
|
|
|
|
// actionName = [[request requestHandlerPath] lastPathComponent];
|
|
|
|
//
|
|
|
|
// return ([actionName hasPrefix: @"save"]);
|
|
|
|
// }
|
2006-09-16 00:23:29 +02:00
|
|
|
|
|
|
|
- (NSString *) viewActionName
|
|
|
|
{
|
|
|
|
/* this is overridden in the mail based contacts UI to redirect to tb.edit */
|
|
|
|
return @"";
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) editActionName
|
|
|
|
{
|
|
|
|
/* this is overridden in the mail based contacts UI to redirect to tb.edit */
|
2008-03-07 23:09:33 +01:00
|
|
|
return @"editAsContact";
|
2006-09-16 00:23:29 +02:00
|
|
|
}
|
|
|
|
|
2011-12-30 21:39:07 +01:00
|
|
|
- (BOOL) supportPhotos
|
2010-07-16 21:35:25 +02:00
|
|
|
{
|
2011-12-30 21:39:07 +01:00
|
|
|
return [[self clientObject] isKindOfClass: SOGoContactGCSEntryK];
|
2010-07-16 21:35:25 +02:00
|
|
|
}
|
|
|
|
|
2011-12-30 21:39:07 +01:00
|
|
|
- (BOOL) hasPhoto
|
2006-09-16 00:23:29 +02:00
|
|
|
{
|
2011-12-30 21:39:07 +01:00
|
|
|
return [[self clientObject] hasPhoto];
|
2006-09-16 00:23:29 +02:00
|
|
|
}
|
|
|
|
|
2011-12-30 21:39:07 +01:00
|
|
|
- (NSString *) photoURL
|
2006-09-16 00:23:29 +02:00
|
|
|
{
|
2011-12-30 21:39:07 +01:00
|
|
|
NSURL *soURL;
|
2007-03-22 20:02:45 +01:00
|
|
|
|
2011-12-30 21:39:07 +01:00
|
|
|
soURL = [[self clientObject] soURL];
|
2006-09-16 00:23:29 +02:00
|
|
|
|
2011-12-30 21:39:07 +01:00
|
|
|
return [NSString stringWithFormat: @"%@/photo", [soURL absoluteString]];
|
2006-09-16 00:23:29 +02:00
|
|
|
}
|
|
|
|
|
2014-09-03 20:19:46 +02:00
|
|
|
- (void) setAttributes: (NSDictionary *) attributes
|
|
|
|
{
|
2017-03-03 16:35:23 +01:00
|
|
|
NSMutableArray *orgs, *categories;
|
2017-05-30 15:12:13 +02:00
|
|
|
NSDictionary *customFields;
|
|
|
|
NSArray *elements, *values;
|
2014-09-05 21:12:05 +02:00
|
|
|
NSCalendarDate *date;
|
2017-05-30 15:12:13 +02:00
|
|
|
CardElement *element;
|
2014-09-03 20:19:46 +02:00
|
|
|
id o;
|
2017-05-30 15:12:13 +02:00
|
|
|
|
2016-02-05 22:39:33 +01:00
|
|
|
unsigned int i, year, month, day;
|
2014-09-03 20:19:46 +02:00
|
|
|
|
2015-07-27 18:47:40 +02:00
|
|
|
[card setNWithFamily: [attributes objectForKey: @"c_sn"]
|
|
|
|
given: [attributes objectForKey: @"c_givenname"]
|
2014-09-03 20:19:46 +02:00
|
|
|
additional: nil prefixes: nil suffixes: nil];
|
|
|
|
[card setNickname: [attributes objectForKey: @"nickname"]];
|
2015-07-27 18:47:40 +02:00
|
|
|
[card setFn: [attributes objectForKey: @"c_cn"]];
|
2014-09-03 20:19:46 +02:00
|
|
|
[card setTitle: [attributes objectForKey: @"title"]];
|
2015-11-27 17:27:38 +01:00
|
|
|
[card setRole: [attributes objectForKey: @"role"]];
|
2014-09-05 21:12:05 +02:00
|
|
|
|
2015-11-27 16:58:56 +01:00
|
|
|
if ([attributes objectForKey: @"c_screenname"])
|
|
|
|
[[card uniqueChildWithTag: @"x-aim"]
|
|
|
|
setSingleValue: [attributes objectForKey: @"c_screenname"]
|
|
|
|
forKey: @""];
|
|
|
|
|
2016-04-06 04:03:52 +02:00
|
|
|
o = [attributes objectForKey: @"birthday"];
|
|
|
|
if ([o isKindOfClass: [NSString class]] && [o length])
|
2014-09-05 21:12:05 +02:00
|
|
|
{
|
2016-04-06 04:03:52 +02:00
|
|
|
date = [card dateFromString: o inContext: context];
|
2014-09-05 21:12:05 +02:00
|
|
|
year = [date yearOfCommonEra];
|
|
|
|
month = [date monthOfYear];
|
|
|
|
day = [date dayOfMonth];
|
|
|
|
[card setBday: [NSString stringWithFormat: @"%.4d%.2d%.2d", year, month, day]];
|
|
|
|
}
|
2015-08-20 16:29:47 +02:00
|
|
|
else
|
|
|
|
[card setBday: nil];
|
2014-09-03 20:19:46 +02:00
|
|
|
|
|
|
|
if ([[attributes objectForKey: @"addresses"] isKindOfClass: [NSArray class]])
|
|
|
|
{
|
|
|
|
elements = [card childrenWithTag: @"adr"];
|
|
|
|
[card removeChildren: elements];
|
|
|
|
values = [attributes objectForKey: @"addresses"];
|
|
|
|
for (i = 0; i < [values count]; i++)
|
|
|
|
{
|
|
|
|
o = [values objectAtIndex: i];
|
|
|
|
if ([o isKindOfClass: [NSDictionary class]])
|
|
|
|
{
|
2017-09-07 22:30:22 +02:00
|
|
|
element = [CardElement elementWithTag: @"adr"];
|
|
|
|
[element addType: [o objectForKey: @"type"]];
|
2014-09-03 20:19:46 +02:00
|
|
|
[element setSingleValue: [o objectForKey: @"postoffice"]
|
|
|
|
atIndex: 0 forKey: @""];
|
|
|
|
[element setSingleValue: [o objectForKey: @"street2"]
|
|
|
|
atIndex: 1 forKey: @""];
|
|
|
|
[element setSingleValue: [o objectForKey: @"street"]
|
|
|
|
atIndex: 2 forKey: @""];
|
|
|
|
[element setSingleValue: [o objectForKey: @"locality"]
|
|
|
|
atIndex: 3 forKey: @""];
|
|
|
|
[element setSingleValue: [o objectForKey: @"region"]
|
|
|
|
atIndex: 4 forKey: @""];
|
|
|
|
[element setSingleValue: [o objectForKey: @"postalcode"]
|
|
|
|
atIndex: 5 forKey: @""];
|
|
|
|
[element setSingleValue: [o objectForKey: @"country"]
|
|
|
|
atIndex: 6 forKey: @""];
|
2017-09-07 22:30:22 +02:00
|
|
|
[card addChild: element];
|
2014-09-03 20:19:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-03 16:35:23 +01:00
|
|
|
if ([[attributes objectForKey: @"orgs"] isKindOfClass: [NSArray class]])
|
|
|
|
orgs = [NSMutableArray arrayWithArray: [attributes objectForKey: @"orgs"]];
|
2014-09-03 20:19:46 +02:00
|
|
|
else
|
2017-03-03 16:35:23 +01:00
|
|
|
orgs = [NSMutableArray array];
|
|
|
|
if ([[attributes objectForKey: @"org"] length])
|
|
|
|
[orgs insertObject: [attributes objectForKey: @"org"] atIndex: 0];
|
|
|
|
[card setOrganizations: orgs];
|
2014-09-03 20:19:46 +02:00
|
|
|
|
|
|
|
elements = [card childrenWithTag: @"tel"];
|
|
|
|
[card removeChildren: elements];
|
|
|
|
values = [attributes objectForKey: @"phones"];
|
|
|
|
if ([values isKindOfClass: [NSArray class]])
|
|
|
|
{
|
|
|
|
NSEnumerator *list = [values objectEnumerator];
|
|
|
|
id attrs;
|
|
|
|
while ((attrs = [list nextObject]))
|
|
|
|
{
|
|
|
|
if ([attrs isKindOfClass: [NSDictionary class]])
|
|
|
|
{
|
2015-08-18 22:21:47 +02:00
|
|
|
[card addElementWithTag: @"tel"
|
|
|
|
ofType: [attrs objectForKey: @"type"]
|
|
|
|
withValue: [attrs objectForKey: @"value"]];
|
2014-09-03 20:19:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ([[attributes objectForKey: @"emails"] isKindOfClass: [NSArray class]])
|
|
|
|
{
|
|
|
|
elements = [card childrenWithTag: @"email"];
|
|
|
|
[card removeChildren: elements];
|
|
|
|
values = [attributes objectForKey: @"emails"];
|
|
|
|
if (values)
|
|
|
|
{
|
|
|
|
NSEnumerator *list = [values objectEnumerator];
|
|
|
|
while ((o = [list nextObject]))
|
|
|
|
{
|
|
|
|
if ([o isKindOfClass: [NSDictionary class]])
|
|
|
|
{
|
2015-08-18 22:21:47 +02:00
|
|
|
[card addElementWithTag: @"email"
|
|
|
|
ofType: [o objectForKey: @"type"]
|
|
|
|
withValue: [o objectForKey: @"value"]];
|
2014-09-03 20:19:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
elements = [card childrenWithTag: @"url"];
|
|
|
|
[card removeChildren: elements];
|
|
|
|
values = [attributes objectForKey: @"urls"];
|
|
|
|
if ([values isKindOfClass: [NSArray class]])
|
|
|
|
{
|
|
|
|
NSEnumerator *list = [values objectEnumerator];
|
|
|
|
id attrs;
|
|
|
|
while ((attrs = [list nextObject]))
|
|
|
|
{
|
|
|
|
if ([attrs isKindOfClass: [NSDictionary class]])
|
|
|
|
{
|
2015-08-18 22:21:47 +02:00
|
|
|
[card addElementWithTag: @"url"
|
|
|
|
ofType: [attrs objectForKey: @"type"]
|
|
|
|
withValue: [attrs objectForKey: @"value"]];
|
2014-09-03 20:19:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-21 00:28:58 +02:00
|
|
|
[card setNotes: [attributes objectForKey: @"notes"]];
|
2014-09-03 20:19:46 +02:00
|
|
|
|
|
|
|
if ([[attributes objectForKey: @"categories"] isKindOfClass: [NSArray class]])
|
|
|
|
{
|
|
|
|
elements = [card childrenWithTag: @"categories"];
|
|
|
|
[card removeChildren: elements];
|
|
|
|
values = [attributes objectForKey: @"categories"];
|
|
|
|
categories = [NSMutableArray arrayWithCapacity: [values count]];
|
|
|
|
for (i = 0; i < [values count]; i++)
|
|
|
|
{
|
|
|
|
o = [values objectAtIndex: i];
|
|
|
|
if ([o isKindOfClass: [NSDictionary class]])
|
|
|
|
{
|
2014-09-17 21:45:31 +02:00
|
|
|
o = [o objectForKey: @"value"];
|
|
|
|
if (o && [o isKindOfClass: [NSString class]] && [(NSString *) o length] > 0)
|
|
|
|
{
|
|
|
|
[categories addObject: o];
|
|
|
|
}
|
2014-09-03 20:19:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
[card setCategories: categories];
|
|
|
|
}
|
|
|
|
|
2017-05-30 15:12:13 +02:00
|
|
|
customFields = [attributes objectForKey: @"customFields"];
|
|
|
|
if (customFields && [customFields isKindOfClass: [NSDictionary class]])
|
|
|
|
{
|
|
|
|
if ((o = [customFields objectForKey: @"1"]))
|
|
|
|
{
|
|
|
|
elements = [card childrenWithTag: @"custom1"];
|
|
|
|
[card removeChildren: elements];
|
|
|
|
[card addElementWithTag: @"custom1" ofType: nil withValue: o];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((o = [customFields objectForKey: @"2"]))
|
|
|
|
{
|
|
|
|
elements = [card childrenWithTag: @"custom2"];
|
|
|
|
[card removeChildren: elements];
|
|
|
|
[card addElementWithTag: @"custom2" ofType: nil withValue: o];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((o = [customFields objectForKey: @"3"]))
|
|
|
|
{
|
|
|
|
elements = [card childrenWithTag: @"custom3"];
|
|
|
|
[card removeChildren: elements];
|
2017-07-06 14:56:30 +02:00
|
|
|
[card addElementWithTag: @"custom3" ofType: nil withValue: o];
|
2017-05-30 15:12:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((o = [customFields objectForKey: @"4"]))
|
|
|
|
{
|
|
|
|
elements = [card childrenWithTag: @"custom4"];
|
|
|
|
[card removeChildren: elements];
|
2017-07-06 14:56:30 +02:00
|
|
|
[card addElementWithTag: @"custom4" ofType: nil withValue: o];
|
2017-05-30 15:12:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-03 20:19:46 +02:00
|
|
|
[card cleanupEmptyChildren];
|
|
|
|
}
|
|
|
|
|
2015-01-22 15:15:44 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @api {post} /so/:username/Contacts/:addressbookId/:cardId/save Save card
|
|
|
|
* @apiVersion 1.0.0
|
|
|
|
* @apiName PostData
|
|
|
|
* @apiGroup Contacts
|
|
|
|
* @apiExample {curl} Example usage:
|
2015-01-26 21:42:10 +01:00
|
|
|
* curl -i http://localhost/SOGo/so/sogo1/Contacts/personal/1BC8-52F53F80-1-38C52040.vcf/save
|
2015-01-22 15:15:44 +01:00
|
|
|
*
|
2015-01-26 21:42:10 +01:00
|
|
|
* @apiParam {String} id Card ID
|
|
|
|
* @apiParam {String} pid Address book ID (card's container)
|
2015-07-27 18:47:40 +02:00
|
|
|
* @apiParam {String} c_component Either vcard or vlist
|
|
|
|
* @apiParam {String} c_givenname Firstname
|
2015-01-26 21:42:10 +01:00
|
|
|
* @apiParam {String} nickname Nickname
|
2015-07-27 18:47:40 +02:00
|
|
|
* @apiParam {String} c_sn Lastname
|
|
|
|
* @apiParam {String} c_cn Fullname
|
2015-11-27 16:58:56 +01:00
|
|
|
* @apiParam {String} c_screenname Screen Name (X-AIM for now)
|
2015-01-26 21:42:10 +01:00
|
|
|
* @apiParam {String} tz Timezone
|
2017-03-03 16:35:23 +01:00
|
|
|
* @apiParam {String} org Main organization
|
|
|
|
* @apiParam {String[]} orgs Additional organizations
|
|
|
|
* @apiParam {String[]} notes Notes
|
2015-01-26 21:42:10 +01:00
|
|
|
* @apiParam {String[]} allCategories All available categories
|
|
|
|
* @apiParam {Object[]} categories Categories assigned to the card
|
|
|
|
* @apiParam {String} categories.value Category name
|
|
|
|
* @apiParam {Object[]} addresses Postal addresses
|
|
|
|
* @apiParam {String} addresses.type Type (e.g., home or work)
|
|
|
|
* @apiParam {String} addresses.postoffice Post office box
|
|
|
|
* @apiParam {String} addresses.street Street address
|
|
|
|
* @apiParam {String} addresses.street2 Extended address (e.g., apartment or suite number)
|
|
|
|
* @apiParam {String} addresses.locality Locality (e.g., city)
|
|
|
|
* @apiParam {String} addresses.region Region (e.g., state or province)
|
|
|
|
* @apiParam {String} addresses.postalcode Postal code
|
|
|
|
* @apiParam {String} addresses.country Country name
|
|
|
|
* @apiParam {Object[]} emails Email addresses
|
|
|
|
* @apiParam {String} emails.type Type (e.g., home or work)
|
|
|
|
* @apiParam {String} emails.value Email address
|
|
|
|
* @apiParam {Object[]} phones Phone numbers
|
|
|
|
* @apiParam {String} phones.type Type (e.g., mobile or work)
|
|
|
|
* @apiParam {String} phones.value Phone number
|
|
|
|
* @apiParam {Object[]} urls URLs
|
|
|
|
* @apiParam {String} urls.type Type (e.g., personal or work)
|
|
|
|
* @apiParam {String} urls.value URL
|
2021-10-04 16:02:33 +02:00
|
|
|
* @apiParam {Boolean} ignoreDuplicate Don't check for similar cards
|
2015-01-22 15:15:44 +01:00
|
|
|
*/
|
2006-10-12 18:42:59 +02:00
|
|
|
- (id <WOActionResults>) saveAction
|
2006-09-16 00:23:29 +02:00
|
|
|
{
|
2021-10-04 16:02:33 +02:00
|
|
|
BOOL forceSave;
|
|
|
|
NSArray *similarRecords;
|
|
|
|
NSDictionary *params;
|
2014-09-03 20:19:46 +02:00
|
|
|
SOGoContentObject <SOGoContactObject> *co;
|
2014-06-19 21:51:57 +02:00
|
|
|
WORequest *request;
|
2021-10-04 16:02:33 +02:00
|
|
|
id data;
|
|
|
|
unsigned int status;
|
2006-09-16 00:23:29 +02:00
|
|
|
|
2021-10-04 16:02:33 +02:00
|
|
|
status = 200;
|
|
|
|
similarRecords = [NSArray array];
|
2014-09-03 20:19:46 +02:00
|
|
|
co = [self clientObject];
|
|
|
|
card = [co vCard];
|
2014-06-19 21:51:57 +02:00
|
|
|
request = [context request];
|
|
|
|
params = [[request contentAsString] objectFromJSONString];
|
2021-10-04 16:02:33 +02:00
|
|
|
forceSave = [[params objectForKey: @"ignoreDuplicate"] boolValue];
|
2014-06-19 21:51:57 +02:00
|
|
|
|
2014-09-03 20:19:46 +02:00
|
|
|
[self setAttributes: params];
|
2011-12-30 21:39:07 +01:00
|
|
|
|
2021-10-04 16:02:33 +02:00
|
|
|
if (forceSave == NO)
|
|
|
|
{
|
|
|
|
// Check if a similar card already exists in the same addressbook
|
|
|
|
EOKeyValueQualifier *qualifier;
|
|
|
|
NSEnumerator *allKeys;
|
|
|
|
NSMutableArray *qualifiers;
|
|
|
|
NSMutableDictionary *checks;
|
|
|
|
NSString *key;
|
|
|
|
id o;
|
|
|
|
|
|
|
|
qualifiers = [NSMutableArray array];
|
|
|
|
checks = [NSMutableDictionary dictionary];
|
|
|
|
|
|
|
|
o = [card n];
|
|
|
|
if (o)
|
|
|
|
{
|
|
|
|
NSString *lastName = [o flattenedValueAtIndex: 0 forKey: @""];
|
|
|
|
NSString *firstName = [o flattenedValueAtIndex: 1 forKey: @""];
|
|
|
|
if ([lastName length] > 0)
|
|
|
|
[checks setObject: lastName forKey: @"c_sn"];
|
|
|
|
if ([firstName length] > 0)
|
|
|
|
[checks setObject: firstName forKey: @"c_givenname"];
|
|
|
|
}
|
|
|
|
o = [card fn];
|
|
|
|
if ([o length])
|
|
|
|
[checks setObject: o forKey: @"c_cn"];
|
|
|
|
o = [card preferredEMail];
|
|
|
|
if ([o length])
|
|
|
|
[checks setObject: o forKey: @"c_mail"];
|
|
|
|
o = [card preferredTel];
|
|
|
|
if ([o length])
|
|
|
|
[checks setObject: o forKey: @"c_telephonenumber"];
|
|
|
|
|
|
|
|
allKeys = [checks keyEnumerator];
|
|
|
|
while ((key = [allKeys nextObject]))
|
|
|
|
{
|
|
|
|
qualifier = [[EOKeyValueQualifier alloc]
|
|
|
|
initWithKey: key
|
|
|
|
operatorSelector: EOQualifierOperatorCaseInsensitiveLike
|
|
|
|
value: [checks objectForKey: key]];
|
|
|
|
[qualifier autorelease];
|
|
|
|
[qualifiers addObject: qualifier];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ([qualifiers count])
|
|
|
|
{
|
|
|
|
if (![self isNew])
|
|
|
|
{
|
|
|
|
// Exclude current contact
|
|
|
|
qualifier = [[EOKeyValueQualifier alloc]
|
|
|
|
initWithKey: @"c_name"
|
|
|
|
operatorSelector: EOQualifierOperatorNotEqual
|
|
|
|
value: [co nameInContainer]];
|
|
|
|
[qualifier autorelease];
|
|
|
|
[qualifiers addObject: qualifier];
|
|
|
|
}
|
|
|
|
qualifier = [[EOAndQualifier alloc] initWithQualifierArray: qualifiers];
|
|
|
|
similarRecords = [(SOGoContactGCSFolder *) [co container] lookupContactsWithQualifier: qualifier];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ([similarRecords count])
|
|
|
|
{
|
|
|
|
status = 409;
|
|
|
|
data = [similarRecords objectAtIndex: 0];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[co save];
|
|
|
|
|
|
|
|
// Return card UID and addressbook ID in a JSON payload
|
|
|
|
data = [NSDictionary dictionaryWithObjectsAndKeys:
|
|
|
|
[[co container] nameInContainer], @"pid",
|
|
|
|
[co nameInContainer], @"id",
|
|
|
|
nil];
|
|
|
|
}
|
2014-06-19 21:51:57 +02:00
|
|
|
|
2021-10-04 16:02:33 +02:00
|
|
|
return [self responseWithStatus: status andJSONRepresentation: data];
|
2006-09-16 00:23:29 +02:00
|
|
|
}
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
@end /* UIxContactEditor */
|
2008-06-20 06:11:41 +02:00
|
|
|
|