diff --git a/SoObjects/Contacts/NGVCard+SOGo.h b/SoObjects/Contacts/NGVCard+SOGo.h index a52319ea9..512037888 100644 --- a/SoObjects/Contacts/NGVCard+SOGo.h +++ b/SoObjects/Contacts/NGVCard+SOGo.h @@ -34,9 +34,6 @@ - (void) updateFromLDIFRecord: (NSDictionary *) ldifRecord; - (NSMutableDictionary *) asLDIFRecord; -- (void) setAttributes: (NSDictionary *) attributes; -//- (NSDictionary *) attributes; - - (NSString *) workCompany; - (NSString *) fullName; - (NSArray *) secondaryEmails; diff --git a/SoObjects/Contacts/NGVCard+SOGo.m b/SoObjects/Contacts/NGVCard+SOGo.m index f03c76064..83e646c06 100644 --- a/SoObjects/Contacts/NGVCard+SOGo.m +++ b/SoObjects/Contacts/NGVCard+SOGo.m @@ -642,237 +642,6 @@ convention: return ldifRecord; } -- (void) setAttributes: (NSDictionary *) attributes -{ - NSInteger year, yearOfToday, month, day; - CardElement *element; - NSCalendarDate *now; - NSArray *elements, *values; - NSMutableArray *addresses, *units, *categories; - NSString *ou; - id o; - unsigned int i; - - NSLog(@"setAttributes: %@", attributes); - - [self setNWithFamily: [attributes objectForKey: @"sn"] - given: [attributes objectForKey: @"givenname"] - additional: nil prefixes: nil suffixes: nil]; - [self setNickname: [attributes objectForKey: @"nickname"]]; - [self setFn: [attributes objectForKey: @"fn"]]; - [self setTitle: [attributes objectForKey: @"title"]]; - - // element = [self elementWithTag: @"adr" ofType: @"home"]; - // [element setSingleValue: [ldifRecord objectForKey: @"mozillahomestreet2"] - // atIndex: 1 forKey: @""]; - // [element setSingleValue: [ldifRecord objectForKey: @"mozillahomestreet"] - // atIndex: 2 forKey: @""]; - // [element setSingleValue: [ldifRecord objectForKey: @"mozillahomelocalityname"] - // atIndex: 3 forKey: @""]; - // [element setSingleValue: [ldifRecord objectForKey: @"mozillahomestate"] - // atIndex: 4 forKey: @""]; - // [element setSingleValue: [ldifRecord objectForKey: @"mozillahomepostalcode"] - // atIndex: 5 forKey: @""]; - // [element setSingleValue: [ldifRecord objectForKey: @"mozillahomecountryname"] - // atIndex: 6 forKey: @""]; - - // element = [self elementWithTag: @"adr" ofType: @"work"]; - // [element setSingleValue: [ldifRecord objectForKey: @"mozillaworkstreet2"] - // atIndex: 1 forKey: @""]; - // [element setSingleValue: [ldifRecord objectForKey: @"street"] - // atIndex: 2 forKey: @""]; - // [element setSingleValue: [ldifRecord objectForKey: @"l"] - // atIndex: 3 forKey: @""]; - // [element setSingleValue: [ldifRecord objectForKey: @"st"] - // atIndex: 4 forKey: @""]; - // [element setSingleValue: [ldifRecord objectForKey: @"postalcode"] - // atIndex: 5 forKey: @""]; - // [element setSingleValue: [ldifRecord objectForKey: @"c"] - // atIndex: 6 forKey: @""]; - if ([[attributes objectForKey: @"addresses"] isKindOfClass: [NSArray class]]) - { - elements = [self childrenWithTag: @"adr"]; - [self removeChildren: elements]; - values = [attributes objectForKey: @"addresses"]; - addresses = [NSMutableArray arrayWithCapacity: [values count]]; - for (i = 0; i < [values count]; i++) - { - o = [values objectAtIndex: i]; - if ([o isKindOfClass: [NSDictionary class]]) - { - element = [self elementWithTag: @"adr" ofType: [o objectForKey: @"type"]]; - [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: @""]; - } - } - } - - // ou = [ldifRecord objectForKey: @"ou"]; - // if (ou) - // units = [NSArray arrayWithObject: ou]; - // else - // units = nil; - // [self setOrg: [ldifRecord objectForKey: @"o"] - // units: units]; - if ([[attributes objectForKey: @"orgUnits"] isKindOfClass: [NSArray class]]) - { - elements = [self childrenWithTag: @"org"]; - [self removeChildren: elements]; - values = [attributes objectForKey: @"orgUnits"]; - units = [NSMutableArray arrayWithCapacity: [values count]]; - for (i = 0; i < [values count]; i++) - { - o = [values objectAtIndex: i]; - if ([o isKindOfClass: [NSDictionary class]]) - { - [units addObject: [o objectForKey: @"value"]]; - } - } - } - else - { - units = nil; - } - [self setOrg: [attributes objectForKey: @"org"] - units: units]; - - // [self _setPhoneValues: ldifRecord]; - - elements = [self childrenWithTag: @"tel"]; - [self 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]]) - { - element = [self elementWithTag: @"tel" ofType: [attrs objectForKey: @"type"]]; - [element setSingleValue: [attrs objectForKey: @"value"] forKey: @""]; - } - } - } - - // [self _setEmails: ldifRecord]; - if ([[attributes objectForKey: @"emails"] isKindOfClass: [NSArray class]]) - { - elements = [self childrenWithTag: @"email"]; - [self removeChildren: elements]; - values = [attributes objectForKey: @"emails"]; - if (values) - { - NSEnumerator *list = [values objectEnumerator]; - //NSDictionary *attrs; - while ((o = [list nextObject])) - { - if ([o isKindOfClass: [NSDictionary class]]) - { - element = [self elementWithTag: @"email" ofType: [o objectForKey: @"type"]]; - [element setSingleValue: [o objectForKey: @"value"] forKey: @""]; - } - } - } - } - - // [[self elementWithTag: @"url" ofType: @"home"] - // setSingleValue: [ldifRecord objectForKey: @"mozillahomeurl"] forKey: @""]; - // [[self elementWithTag: @"url" ofType: @"work"] - // setSingleValue: [ldifRecord objectForKey: @"mozillaworkurl"] forKey: @""]; - - elements = [self childrenWithTag: @"url"]; - [self 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]]) - { - element = [self elementWithTag: @"url" ofType: [attrs objectForKey: @"type"]]; - [element setSingleValue: [attrs objectForKey: @"value"] forKey: @""]; - } - } - } - - // [[self uniqueChildWithTag: @"x-aim"] - // setSingleValue: [ldifRecord objectForKey: @"nsaimid"] - // forKey: @""]; - - // now = [NSCalendarDate date]; - // year = [[ldifRecord objectForKey: @"birthyear"] intValue]; - // if (year < 100) - // { - // yearOfToday = [now yearOfCommonEra]; - // if (year == 0) - // year = yearOfToday; - // else if (yearOfToday < (year + 2000)) - // year += 1900; - // else - // year += 2000; - // } - // month = [[ldifRecord objectForKey: @"birthmonth"] intValue]; - // day = [[ldifRecord objectForKey: @"birthday"] intValue]; - - // if (year && month && day) - // [self setBday: [NSString stringWithFormat: @"%.4d-%.2d-%.2d", - // year, month, day]]; - // else - // [self setBday: @""]; - - // /* hack to carry SOGoLDAPContactInfo to vcards */ - // [[self uniqueChildWithTag: @"x-sogo-contactinfo"] - // setSingleValue: [ldifRecord objectForKey: @"c_info"] - // forKey: @""]; - - [self setNote: [attributes objectForKey: @"note"]]; - - // o = [ldifRecord objectForKey: @"vcardcategories"]; - - if ([[attributes objectForKey: @"categories"] isKindOfClass: [NSArray class]]) - { - elements = [self childrenWithTag: @"categories"]; - [self 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]]) - { - [categories addObject: [o objectForKey: @"value"]]; - } - } - [self setCategories: categories]; - } - - // We can either have an array (from SOGo's web gui) or a - // string (from a LDIF import) as the value here. - // if ([o isKindOfClass: [NSArray class]]) - // [self setCategories: o]; - // else - // [self setCategories: [o componentsSeparatedByString: @","]]; - - [self cleanupEmptyChildren]; - - NSLog(@"%@", [self versitString]); -} - - (NSString *) workCompany { CardElement *org; diff --git a/SoObjects/Contacts/SOGoContactGCSEntry.m b/SoObjects/Contacts/SOGoContactGCSEntry.m index 4af28fecd..4b5d5bd21 100644 --- a/SoObjects/Contacts/SOGoContactGCSEntry.m +++ b/SoObjects/Contacts/SOGoContactGCSEntry.m @@ -84,11 +84,6 @@ return [self ldifRecord]; } -- (void) setAttributes: (NSDictionary *) newAttributes -{ - [[self vCard] setAttributes: newAttributes]; -} - - (BOOL) hasPhoto { return ([[self vCard] firstChildWithTag: @"photo"] != nil); diff --git a/SoObjects/Contacts/SOGoContactGCSFolder.m b/SoObjects/Contacts/SOGoContactGCSFolder.m index c6ac91242..54cb7efc2 100644 --- a/SoObjects/Contacts/SOGoContactGCSFolder.m +++ b/SoObjects/Contacts/SOGoContactGCSFolder.m @@ -222,45 +222,53 @@ static NSArray *folderListingFields = nil; data = [contactRecord objectForKey: @"c_component"]; if ([data length]) [contactRecord setObject: data forKey: @"tag"]; - [contactRecord removeObjectForKey: @"c_component"]; // c_categories => categories data = [contactRecord objectForKey: @"c_categories"]; if ([data length]) [contactRecord setObject: data forKey: @"categories"]; - [contactRecord removeObjectForKey: @"c_categories"]; // c_name => id data = [contactRecord objectForKey: @"c_name"]; if ([data length]) [contactRecord setObject: data forKey: @"id"]; - [contactRecord removeObjectForKey: @"c_name"]; // c_cn => fn data = [contactRecord objectForKey: @"c_cn"]; if ([data length]) [contactRecord setObject: data forKey: @"fn"]; - [contactRecord removeObjectForKey: @"c_cn"]; + else + { + data = [contactRecord keysWithFormat: @"%{c_givenname} %{c_sn}"]; + if ([data length] > 1) + { + [contactRecord setObject: data forKey: @"c_cn"]; + } + else + { + data = [contactRecord objectForKey: @"c_o"]; + [contactRecord setObject: data forKey: @"c_cn"]; + } + } // c_givenname => givenname data = [contactRecord objectForKey: @"c_givenname"]; if ([data length]) [contactRecord setObject: data forKey: @"givenname"]; - [contactRecord removeObjectForKey: @"c_givenname"]; // c_sn => sn data = [contactRecord objectForKey: @"c_sn"]; if ([data length]) [contactRecord setObject: data forKey: @"sn"]; - [contactRecord removeObjectForKey: @"c_sn"]; // c_screenname => X-AIM + if (![contactRecord objectForKey: @"c_screenname"]) + [contactRecord setObject: @"" forKey: @"c_screenname"]; // c_o => org data = [contactRecord objectForKey: @"c_o"]; if ([data length]) [contactRecord setObject: data forKey: @"org"]; - [contactRecord removeObjectForKey: @"c_o"]; // c_mail => emails[] data = [contactRecord objectForKey: @"c_mail"]; @@ -270,7 +278,8 @@ static NSArray *folderListingFields = nil; email = [NSDictionary dictionaryWithObjectsAndKeys: @"pref", @"type", data, @"value", nil]; [contactRecord setObject: [NSArray arrayWithObject: email] forKey: @"emails"]; } - [contactRecord removeObjectForKey: @"c_mail"]; + else + [contactRecord setObject: @"" forKey: @"c_mail"]; // c_telephonenumber => phones data = [contactRecord objectForKey: @"c_telephonenumber"]; @@ -280,7 +289,8 @@ static NSArray *folderListingFields = nil; phonenumber = [NSDictionary dictionaryWithObjectsAndKeys: @"pref", @"type", data, @"value", nil]; [contactRecord setObject: [NSArray arrayWithObject: phonenumber] forKey: @"phones"]; } - [contactRecord removeObjectForKey: @"c_telephonenumber"]; + else + [contactRecord setObject: @"" forKey: @"c_telephonenumber"]; } - (NSArray *) _flattenedRecords: (NSArray *) records diff --git a/SoObjects/Contacts/SOGoContactObject.h b/SoObjects/Contacts/SOGoContactObject.h index 3f5b30c8c..b765593f2 100644 --- a/SoObjects/Contacts/SOGoContactObject.h +++ b/SoObjects/Contacts/SOGoContactObject.h @@ -37,10 +37,7 @@ - (NSDictionary *) ldifRecord; - (NSDictionary *) simplifiedLDIFRecord; -- (void) setAttributes: (NSDictionary *) newAttributes; - - (NSException *) save; -- (NSException *) delete; @end diff --git a/SoObjects/Contacts/SOGoContactSourceFolder.m b/SoObjects/Contacts/SOGoContactSourceFolder.m index e385d9c09..2a85a6edb 100644 --- a/SoObjects/Contacts/SOGoContactSourceFolder.m +++ b/SoObjects/Contacts/SOGoContactSourceFolder.m @@ -217,6 +217,11 @@ return [source removeContactEntryWithID: [ldifEntry nameInContainer]]; } +/** + * Normalize keys of dictionary representing a contact. + * @param oldRecord a dictionary with pairs from the source folder (LDAP or SQL) + * @see [SOGoContactGCSFolder _fixupContactRecord] + */ - (NSDictionary *) _flattenedRecord: (NSDictionary *) oldRecord { NSMutableDictionary *newRecord; @@ -226,26 +231,45 @@ newRecord = [NSMutableDictionary dictionaryWithCapacity: 8]; [newRecord setObject: [oldRecord objectForKey: @"c_uid"] forKey: @"c_uid"]; + + // c_name => id [newRecord setObject: [oldRecord objectForKey: @"c_name"] forKey: @"c_name"]; + [newRecord setObject: [oldRecord objectForKey: @"c_name"] + forKey: @"id"]; + // displayname || c_cn => fn data = [oldRecord objectForKey: @"displayname"]; if (!data) data = [oldRecord objectForKey: @"c_cn"]; - if (!data) + if (data) + [newRecord setObject: data forKey: @"fn"]; + else data = @""; [newRecord setObject: data forKey: @"c_cn"]; + // mail => emails[] data = [oldRecord objectForKey: @"mail"]; - if (!data) - data = @""; - else if ([data isKindOfClass: [NSArray class]]) + if (data) { - if ([data count] > 0) - data = [data objectAtIndex: 0]; + if ([data isKindOfClass: [NSArray class]]) + { + if ([data count] > 0) + data = [data objectAtIndex: 0]; + else + data = nil; + } + if (data) + { + NSDictionary *email; + email = [NSDictionary dictionaryWithObjectsAndKeys: @"pref", @"type", data, @"value", nil]; + [newRecord setObject: [NSArray arrayWithObject: email] forKey: @"emails"]; + } else data = @""; } + else + data = @""; [newRecord setObject: data forKey: @"c_mail"]; data = [oldRecord objectForKey: @"nsaimid"]; @@ -255,17 +279,27 @@ data = @""; [newRecord setObject: data forKey: @"c_screenname"]; + // o => org data = [oldRecord objectForKey: @"o"]; - if (!data) + if (data) + [newRecord setObject: data forKey: @"org"]; + else data = @""; [newRecord setObject: data forKey: @"c_o"]; + // telephonenumber || cellphone || homephone => phones[] data = [oldRecord objectForKey: @"telephonenumber"]; if (![data length]) data = [oldRecord objectForKey: @"cellphone"]; if (![data length]) data = [oldRecord objectForKey: @"homephone"]; - if (![data length]) + if (data) + { + NSDictionary *phonenumber; + phonenumber = [NSDictionary dictionaryWithObjectsAndKeys: @"pref", @"type", data, @"value", nil]; + [newRecord setObject: [NSArray arrayWithObject: phonenumber] forKey: @"phones"]; + } + else data = @""; else if ([data isKindOfClass: [NSArray class]]) { @@ -282,17 +316,21 @@ if (data) { [newRecord setObject: data forKey: @"isGroup"]; - [newRecord setObject: @"vlist" forKey: @"c_component"]; + [newRecord setObject: @"vlist" forKey: @"tag"]; } #warning TODO: create a custom icon for resources else { - [newRecord setObject: @"vcard" forKey: @"c_component"]; + [newRecord setObject: @"vcard" forKey: @"tag"]; } + // c_info => note data = [oldRecord objectForKey: @"c_info"]; if ([data length] > 0) - [newRecord setObject: data forKey: @"contactInfo"]; + { + [newRecord setObject: data forKey: @"note"]; + [newRecord setObject: data forKey: @"contactInfo"]; + } recordSource = [oldRecord objectForKey: @"source"]; if ([recordSource conformsToProtocol: @protocol (SOGoDNSource)] && diff --git a/UI/Contacts/UIxContactEditor.h b/UI/Contacts/UIxContactEditor.h index 3f322dfb7..742767ef6 100644 --- a/UI/Contacts/UIxContactEditor.h +++ b/UI/Contacts/UIxContactEditor.h @@ -1,20 +1,21 @@ /* Copyright (C) 2004-2005 SKYRIX Software AG + Copyright (C) 2006-2014 Inverse inc. - This file is part of OpenGroupware.org. + This file is part of SOGo - OGo is free software; you can redistribute it and/or modify it under + SOGo is free software; you can redistribute it and/or modify it under 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. - OGo is distributed in the hope that it will be useful, but WITHOUT ANY + SOGo 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the + License along with SOGo; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -32,6 +33,7 @@ @interface UIxContactEditor : UIxComponent { id addressBookItem; + NGVCard *card; NSString *item; NSMutableDictionary *ldifRecord; /* contains the values for editing */ id componentAddressBook; diff --git a/UI/Contacts/UIxContactEditor.m b/UI/Contacts/UIxContactEditor.m index babc4144a..5f6224d91 100644 --- a/UI/Contacts/UIxContactEditor.m +++ b/UI/Contacts/UIxContactEditor.m @@ -15,7 +15,7 @@ License for more details. You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the + License along with SOGo; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -42,6 +42,7 @@ #import #import +#import #import #import #import @@ -113,12 +114,6 @@ static Class SOGoContactGCSEntryK = Nil; return addressBookItem; } -- (NSString *) saveURL -{ - return [NSString stringWithFormat: @"%@/saveAsContact", - [[self clientObject] baseURL]]; -} - - (NSArray *) htmlMailFormatList { static NSArray *htmlMailFormatItems = nil; @@ -346,24 +341,167 @@ static Class SOGoContactGCSEntryK = Nil; return [NSString stringWithFormat: @"%@/photo", [soURL absoluteString]]; } +- (void) setAttributes: (NSDictionary *) attributes +{ + CardElement *element; + NSArray *elements, *values; + NSMutableArray *units, *categories; + id o; + unsigned int i; + + [card setNWithFamily: [attributes objectForKey: @"sn"] + given: [attributes objectForKey: @"givenname"] + additional: nil prefixes: nil suffixes: nil]; + [card setNickname: [attributes objectForKey: @"nickname"]]; + [card setFn: [attributes objectForKey: @"fn"]]; + [card setTitle: [attributes objectForKey: @"title"]]; + [card setBday: [attributes objectForKey: @"birthday"]]; + + 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]]) + { + element = [card elementWithTag: @"adr" ofType: [o objectForKey: @"type"]]; + [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: @""]; + } + } + } + + if ([[attributes objectForKey: @"orgUnits"] isKindOfClass: [NSArray class]]) + { + elements = [card childrenWithTag: @"org"]; + [card removeChildren: elements]; + values = [attributes objectForKey: @"orgUnits"]; + units = [NSMutableArray arrayWithCapacity: [values count]]; + for (i = 0; i < [values count]; i++) + { + o = [values objectAtIndex: i]; + if ([o isKindOfClass: [NSDictionary class]]) + { + [units addObject: [o objectForKey: @"value"]]; + } + } + } + else + { + units = nil; + } + [card setOrg: [attributes objectForKey: @"org"] + units: units]; + + 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]]) + { + element = [card elementWithTag: @"tel" ofType: [attrs objectForKey: @"type"]]; + [element setSingleValue: [attrs objectForKey: @"value"] forKey: @""]; + } + } + } + + 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]]) + { + element = [card elementWithTag: @"email" ofType: [o objectForKey: @"type"]]; + [element setSingleValue: [o objectForKey: @"value"] forKey: @""]; + } + } + } + } + + 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]]) + { + element = [card elementWithTag: @"url" ofType: [attrs objectForKey: @"type"]]; + [element setSingleValue: [attrs objectForKey: @"value"] forKey: @""]; + } + } + } + + [card setNote: [attributes objectForKey: @"note"]]; + + 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]]) + { + [categories addObject: [o objectForKey: @"value"]]; + } + } + [card setCategories: categories]; + } + + [card cleanupEmptyChildren]; +} + - (id ) saveAction { - SOGoContentObject *contact; + SOGoContentObject *co; WORequest *request; WOResponse *response; NSDictionary *params, *data; - contact = [self clientObject]; + co = [self clientObject]; + card = [co vCard]; request = [context request]; params = [[request contentAsString] objectFromJSONString]; - [contact setAttributes: params]; - [contact save]; + [self setAttributes: params]; + [co save]; // Return card UID and addressbook ID in a JSON payload data = [NSDictionary dictionaryWithObjectsAndKeys: - [[contact container] nameInContainer], @"pid", - [contact nameInContainer], @"id", + [[co container] nameInContainer], @"pid", + [co nameInContainer], @"id", nil]; response = [self responseWithStatus: 200 andString: [data jsonRepresentation]]; diff --git a/UI/Contacts/UIxListEditor.h b/UI/Contacts/UIxListEditor.h index a48a565c4..5e90faa42 100644 --- a/UI/Contacts/UIxListEditor.h +++ b/UI/Contacts/UIxListEditor.h @@ -30,7 +30,6 @@ { NGVList *list; SOGoContactGCSList *co; - id reference; } - (BOOL) cardReferences: (NSArray *) references contain: (NSString *) ref; diff --git a/UI/Contacts/UIxListEditor.m b/UI/Contacts/UIxListEditor.m index ea4920b15..d43e31fbd 100644 --- a/UI/Contacts/UIxListEditor.m +++ b/UI/Contacts/UIxListEditor.m @@ -29,6 +29,7 @@ #import #import +#import #import #import @@ -54,36 +55,6 @@ return self; } -- (NSString *) listName -{ - return [list fn]; -} - -- (void) setListName: (NSString *) newName -{ - [list setFn: newName]; -} - -- (NSString *) nickname -{ - return [list nickname]; -} - -- (void) setNickname: (NSString *) newName -{ - [list setNickname: newName]; -} - -- (NSString *) description -{ - return [list description]; -} - -- (void) setDescription: (NSString *) newDescription -{ - [list setDescription: newDescription]; -} - - (NSArray *) references { NSArray *references; @@ -123,7 +94,7 @@ int i, count; NGVCardReference *cardReference; SOGoContactGCSFolder *folder; - + references = [value componentsSeparatedByString: @","]; if ([references count]) { @@ -142,11 +113,11 @@ // Add new cards count = [references count]; - + for (i = 0; i < count; i++) { currentReference = [references objectAtIndex: i]; - if (![self cardReferences: [list cardReferences] + if (![self cardReferences: [list cardReferences] contain: currentReference]) { // Search contact by vCard UID @@ -157,7 +128,7 @@ [cardReference setFn: [values objectForKey: @"c_cn"]]; [cardReference setEmail: [values objectForKey: @"c_mail"]]; [cardReference setReference: currentReference]; - + [list addCardReference: cardReference]; } else @@ -168,7 +139,7 @@ NGVCard *newCard; CardElement *newWorkMail; SOGoContactGCSEntry *newContact; - + contactInfo = [currentReference componentsSeparatedByString: @"|"]; if ([contactInfo count] > 1) { @@ -196,38 +167,131 @@ [cardReference setFn: fn]; [cardReference setEmail: workMail]; [cardReference setReference: newUID]; - + [list addCardReference: cardReference]; } } } } - } + } +} + +- (void) setReferences: (NSArray *) references +{ + NSDictionary *values; + NSArray *initialReferences; + NSDictionary *currentReference; + NSString *uid, *workMail, *fn, *newUID; + int i, count; + NGVCardReference *cardReference; + SOGoContactGCSFolder *folder; + + folder = [co container]; + + // Remove from the list the cards that were deleted + initialReferences = [list cardReferences]; + count = [initialReferences count]; + for (i = 0; i < count; i++) + { + cardReference = [initialReferences objectAtIndex: i]; + if (![references containsObject: [cardReference reference]]) + [list deleteCardReference: cardReference]; + } + + // TODO: update existing cards? + + // Add new cards + count = [references count]; + + for (i = 0; i < count; i++) + { + if ([[references objectAtIndex: i] isKindOfClass: [NSDictionary class]]) + { + currentReference = [references objectAtIndex: i]; + uid = [currentReference objectForKey: @"reference"]; + if (![self cardReferences: [list cardReferences] + contain: uid]) + { + // Search contact by vCard UID + values = [folder lookupContactWithName: uid]; + if (values) + { + cardReference = [NGVCardReference elementWithTag: @"card"]; + [cardReference setFn: [values objectForKey: @"c_cn"]]; + [cardReference setEmail: [values objectForKey: @"c_mail"]]; + [cardReference setReference: uid]; + + [list addCardReference: cardReference]; + } + else + { + // Invalid UID or no UID + NGVCard *newCard; + CardElement *newWorkMail; + SOGoContactGCSEntry *newContact; + + workMail = [currentReference objectForKey: @"email"]; + fn = [currentReference objectForKey: @"fn"]; + + // Create a new vCard + newUID = [NSString stringWithFormat: @"%@.vcf", [co globallyUniqueObjectId]]; + newCard = [NGVCard cardWithUid: newUID]; + newWorkMail = [CardElement new]; + [newWorkMail autorelease]; + [newWorkMail setTag: @"email"]; + [newWorkMail addType: @"work"]; + [newCard addChild: newWorkMail]; + [newWorkMail setSingleValue: workMail forKey: @""]; + [newCard setFn: fn]; + + // Add vCard to current folder + newContact = [SOGoContactGCSEntry objectWithName: newUID + inContainer: folder]; + [newContact saveContentString: [newCard versitString]]; + + // Create card reference for the list + cardReference = [NGVCardReference elementWithTag: @"card"]; + [cardReference setFn: fn]; + [cardReference setEmail: workMail]; + [cardReference setReference: newUID]; + + [list addCardReference: cardReference]; + } + } + } + } } - (BOOL) cardReferences: (NSArray *) references - contain: (NSString *) ref + contain: (NSString *) reference { int i, count; BOOL rc = NO; - count = [references count]; - for (i = 0; i < count; i++) + if (reference) { - if ([ref isEqualToString: [[references objectAtIndex: i] reference]]) + count = [references count]; + for (i = 0; i < count; i++) { - rc = YES; - break; + if ([reference isEqualToString: [[references objectAtIndex: i] reference]]) + { + rc = YES; + break; + } } } return rc; } -- (NSString *) saveURL +/** + * + */ +- (void) setAttributes: (NSDictionary *) attributes { - return [NSString stringWithFormat: @"%@/saveAsList", - [co baseURLInContext: context]]; + [list setNickname: [attributes objectForKey: @"nickname"]]; + [list setFn: [attributes objectForKey: @"fn"]]; + [list setDescription: [attributes objectForKey: @"description"]]; } - (BOOL) canCreateOrModify @@ -236,71 +300,36 @@ && [super canCreateOrModify]); } -- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request - inContext: (WOContext*) context -{ - NSString *actionName; - BOOL rc; - - co = [self clientObject]; - actionName = [[request requestHandlerPath] lastPathComponent]; - if ([co isKindOfClass: [SOGoContactGCSList class]] - && [actionName hasPrefix: @"save"]) - { - list = [co vList]; - [list retain]; - rc = YES; - } - else - rc = NO; - - return rc; -} - -#warning Could this be part of a common parent with UIxAppointment/UIxTaskEditor/UIxListEditor ? -- (id) newAction -{ - NSString *objectId, *method, *uri; - id result; - - co = [self clientObject]; - objectId = [co globallyUniqueObjectId]; - if ([objectId length] > 0) - { - method = [NSString stringWithFormat:@"%@/%@.vlf/editAsList", - [co soURL], objectId]; - uri = [self completeHrefForMethod: method]; - result = [self redirectToLocation: uri]; - } - else - result = [NSException exceptionWithHTTPStatus: 500 /* Internal Error */ - reason: @"could not create a unique ID"]; - - return result; -} - - (id ) saveAction { - id result; - NSString *jsRefreshMethod; + WORequest *request; + WOResponse *response; + NSDictionary *params, *data; + id o; - if (co) - { - [co save]; - if ([[[[self context] request] formValueForKey: @"nojs"] intValue]) - result = [self redirectToLocation: [self modulePath]]; - else - { - jsRefreshMethod = [NSString stringWithFormat: @"refreshContacts('%@')", - [co nameInContainer]]; - result = [self jsCloseWithRefreshMethod: jsRefreshMethod]; - } - } - else - result = [NSException exceptionWithHTTPStatus: 400 /* Bad Request */ - reason: @"method cannot be invoked on " - @"the specified object"]; - return result; + co = [self clientObject]; + list = [co vList]; + [list retain]; + + request = [context request]; + params = [[request contentAsString] objectFromJSONString]; + + o = [params objectForKey: @"refs"]; + if (![o isKindOfClass: [NSArray class]]) + o = nil; + [self setReferences: (NSArray *) o]; + [self setAttributes: params]; + [co save]; + + // Return list UID and addressbook ID in a JSON payload + data = [NSDictionary dictionaryWithObjectsAndKeys: + [[co container] nameInContainer], @"pid", + [co nameInContainer], @"id", + nil]; + response = [self responseWithStatus: 200 + andString: [data jsonRepresentation]]; + + return response; } @end