diff --git a/Documentation/SOGoInstallationGuide.asciidoc b/Documentation/SOGoInstallationGuide.asciidoc index 0bc255cb2..72955fe1b 100644 --- a/Documentation/SOGoInstallationGuide.asciidoc +++ b/Documentation/SOGoInstallationGuide.asciidoc @@ -826,6 +826,11 @@ specified as an array of dictionaries. |D |SOGoCreateIdentitiesDisabled |Disable identity creation for users in preferences. If `YES`, users won't be able to add new identities and will allow to change only full name, signature and default identity. Default value is `NO`. Note : If this settings is set to `YES`, it will not be possible to crete auxiliary mail accounts. +|S |SOGoGlobalAddressBookFirstEntries +|Display first entries in Global Address Book. Default value is `NO`. If source is LDAP, the LDAP overlay `sssvlv` must be enabled on the system for server side sorting. + +|S |SOGoGlobalAddressBookFirstEntriesCount +|Number of entries displayed when `SOGoGlobalAddressBookFirstEntries` is enabled. Default value is `100`. |======================================================================= diff --git a/SoObjects/Contacts/SOGoContactSourceFolder.m b/SoObjects/Contacts/SOGoContactSourceFolder.m index 9d74edb90..7bf6b1f7c 100644 --- a/SoObjects/Contacts/SOGoContactSourceFolder.m +++ b/SoObjects/Contacts/SOGoContactSourceFolder.m @@ -434,26 +434,43 @@ { NSArray *records, *result; EOSortOrdering *ordering; + BOOL processed; result = nil; + processed = NO; - if ([filter length] > 0 || ![source listRequiresDot]) + [source setListRequiresDot: NO]; + if ( ![source listRequiresDot]) { - records = [source fetchContactsMatching: filter + if ([filter length] > 0) { + records = [source fetchContactsMatching: filter withCriteria: criteria inDomain: domain]; - [childRecords setObjects: records - forKeys: [records objectsForKey: @"c_name" - notFoundMarker: nil]]; - records = [self _flattenedRecords: records]; - ordering - = [EOSortOrdering sortOrderingWithKey: sortKey - selector: ((sortOrdering == NSOrderedDescending) - ? EOCompareCaseInsensitiveDescending - : EOCompareCaseInsensitiveAscending)]; - result - = [records sortedArrayUsingKeyOrderArray: - [NSArray arrayWithObject: ordering]]; + processed = YES; + } else if ([[SOGoSystemDefaults sharedSystemDefaults] globalAddressBookFirstEntriesEnabled]) { + records = [source fetchContactsMatching: filter + withCriteria: criteria + inDomain: domain + limit: [[SOGoSystemDefaults sharedSystemDefaults] globalAddressBookFirstEntriesCount]]; + processed = YES; + } + + if (processed) { + [childRecords setObjects: records + forKeys: [records objectsForKey: @"c_name" + notFoundMarker: nil]]; + records = [self _flattenedRecords: records]; + ordering + = [EOSortOrdering sortOrderingWithKey: sortKey + selector: ((sortOrdering == NSOrderedDescending) + ? EOCompareCaseInsensitiveDescending + : EOCompareCaseInsensitiveAscending)]; + result + = [records sortedArrayUsingKeyOrderArray: + [NSArray arrayWithObject: ordering]]; + } + + } return result; diff --git a/SoObjects/SOGo/LDAPSource.m b/SoObjects/SOGo/LDAPSource.m index a307b6232..87c1bc95d 100644 --- a/SoObjects/SOGo/LDAPSource.m +++ b/SoObjects/SOGo/LDAPSource.m @@ -1384,6 +1384,21 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses - (NSArray *) fetchContactsMatching: (NSString *) match withCriteria: (NSArray *) criteria inDomain: (NSString *) theDomain +{ + if ([match length] > 0) { + return [self fetchContactsMatching: (NSString *) match + withCriteria: (NSArray *) criteria + inDomain: (NSString *) theDomain + limit: -1]; + } else { + return [NSMutableArray array]; + } +} + +- (NSArray *) fetchContactsMatching: (NSString *) match + withCriteria: (NSArray *) criteria + inDomain: (NSString *) theDomain + limit: (int) limit { NSAutoreleasePool *pool; NGLdapConnection *ldapConnection; @@ -1392,26 +1407,58 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses NSMutableArray *contacts; EOQualifier *qualifier; unsigned int i; + NSString *sortAttribute; + BOOL sortReverse; contacts = [NSMutableArray array]; - if ([match length] > 0 || !_listRequiresDot) + if (!_listRequiresDot) { ldapConnection = [self _ldapConnection]; qualifier = [self _qualifierForFilter: match onCriteria: criteria]; - if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame) - entries = [ldapConnection baseSearchAtBaseDN: _baseDN - qualifier: qualifier - attributes: _lookupFields]; - else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame) - entries = [ldapConnection flatSearchAtBaseDN: _baseDN - qualifier: qualifier - attributes: _lookupFields]; - else /* we do it like before */ - entries = [ldapConnection deepSearchAtBaseDN: _baseDN - qualifier: qualifier - attributes: _lookupFields]; + if (limit > 0) { + [ldapConnection setQuerySizeLimit: limit]; + } + + if (limit > 0) { + // Sort results + sortAttribute = @"cn"; + sortReverse = NO; + if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame) + entries = [ldapConnection baseSearchAtBaseDN: _baseDN + qualifier: qualifier + attributes: _lookupFields + sortAttribute: sortAttribute + sortReverse: sortReverse]; + else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame) + entries = [ldapConnection flatSearchAtBaseDN: _baseDN + qualifier: qualifier + attributes: _lookupFields + sortAttribute: sortAttribute + sortReverse: sortReverse]; + else /* we do it like before */ + entries = [ldapConnection deepSearchAtBaseDN: _baseDN + qualifier: qualifier + attributes: _lookupFields + sortAttribute: sortAttribute + sortReverse: sortReverse]; + } else { + // No sort results + if ([_scope caseInsensitiveCompare: @"BASE"] == NSOrderedSame) + entries = [ldapConnection baseSearchAtBaseDN: _baseDN + qualifier: qualifier + attributes: _lookupFields]; + else if ([_scope caseInsensitiveCompare: @"ONE"] == NSOrderedSame) + entries = [ldapConnection flatSearchAtBaseDN: _baseDN + qualifier: qualifier + attributes: _lookupFields]; + else /* we do it like before */ + entries = [ldapConnection deepSearchAtBaseDN: _baseDN + qualifier: qualifier + attributes: _lookupFields]; + } + i = 0; pool = [NSAutoreleasePool new]; diff --git a/SoObjects/SOGo/SOGoSource.h b/SoObjects/SOGo/SOGoSource.h index f07b068d9..a9510956c 100644 --- a/SoObjects/SOGo/SOGoSource.h +++ b/SoObjects/SOGo/SOGoSource.h @@ -75,6 +75,11 @@ - (NSArray *) fetchContactsMatching: (NSString *) filter withCriteria: (NSArray *) criteria inDomain: (NSString *) domain; +- (NSArray *)fetchContactsMatching:(NSString *)filter + withCriteria:(NSArray *)criteria + inDomain:(NSString *)domain + limit:(int)limit; + - (NSArray *) lookupContactsWithQualifier: (EOQualifier *) qualifier andSortOrdering: (EOSortOrdering *) ordering inDomain: (NSString *) domain; diff --git a/SoObjects/SOGo/SOGoSystemDefaults.h b/SoObjects/SOGo/SOGoSystemDefaults.h index 4ba556b76..328a18571 100644 --- a/SoObjects/SOGo/SOGoSystemDefaults.h +++ b/SoObjects/SOGo/SOGoSystemDefaults.h @@ -133,6 +133,9 @@ NSComparisonResult languageSort(id el1, id el2, void *context); - (NSArray *) disableSharingAnyAuthUser; - (NSArray *) disableExport; +- (BOOL) enableGlobalAddressBookFirstEntries; +- (int) globalAddressBookFirstEntriesCount; + @end #endif /* SOGOSYSTEMDEFAULTS_H */ diff --git a/SoObjects/SOGo/SOGoSystemDefaults.m b/SoObjects/SOGo/SOGoSystemDefaults.m index 2b54f74af..b3511ba74 100644 --- a/SoObjects/SOGo/SOGoSystemDefaults.m +++ b/SoObjects/SOGo/SOGoSystemDefaults.m @@ -845,4 +845,23 @@ NSComparisonResult languageSort(id el1, id el2, void *context) return disableExport; } +- (BOOL) globalAddressBookFirstEntriesEnabled +{ + return [self boolForKey: @"SOGoGlobalAddressBookFirstEntries"]; +} + +- (int) globalAddressBookFirstEntriesCount +{ + int v; + + v = [self integerForKey: @"SOGoGlobalAddressBookFirstEntriesCount"]; + + if (!v) + v = 100; + + return v; +} + + + @end diff --git a/SoObjects/SOGo/SQLSource.m b/SoObjects/SOGo/SQLSource.m index 8217fc5ab..5927b0c66 100644 --- a/SoObjects/SOGo/SQLSource.m +++ b/SoObjects/SOGo/SQLSource.m @@ -924,6 +924,22 @@ - (NSArray *) fetchContactsMatching: (NSString *) filter withCriteria: (NSArray *) criteria inDomain: (NSString *) domain + +{ + if ([filter length] > 0) { + return [self fetchContactsMatching: (NSString *) filter + withCriteria: (NSArray *) criteria + inDomain: (NSString *) domain + limit: -1]; + } else { + return [NSMutableArray array]; + } +} + +- (NSArray *)fetchContactsMatching: (NSString *)filter + withCriteria: (NSArray *)criteria + inDomain: (NSString *)domain + limit: (int)limit { EOAdaptorChannel *channel; NSEnumerator *criteriaList; @@ -935,7 +951,7 @@ results = [NSMutableArray array]; - if ([filter length] > 0 || !_listRequiresDot) + if (!_listRequiresDot) { cm = [GCSChannelManager defaultChannelManager]; channel = [cm acquireOpenChannelForURL: _viewURL]; @@ -994,6 +1010,8 @@ [sql appendFormat: @" AND %@ IS NULL", _domainField]; } + if (limit > 0) + [sql appendFormat: @" ORDER BY c_cn ASC LIMIT %i", limit]; ex = [channel evaluateExpressionX: sql]; if (!ex) { diff --git a/UI/Templates/ContactsUI/UIxContactFoldersView.wox b/UI/Templates/ContactsUI/UIxContactFoldersView.wox index 55df4c221..350590835 100644 --- a/UI/Templates/ContactsUI/UIxContactFoldersView.wox +++ b/UI/Templates/ContactsUI/UIxContactFoldersView.wox @@ -221,7 +221,8 @@
+ md-colors="::{background: 'default-background-300'}" + ng-if="app.service.$remotes.length > 0">