Adding multiple LDAP attributes in user DisplayName field

I want to have multiple LDAP attributes in my user’s display name so that whenever a user is being searched, it shows up the entire name such as:
Title FirstName LastName → Developer John Doe

In my case I have to use 4 additional LDAP attributes namely, Rank, Unit, Designation and PersonalNumber. I tried searching for solutions for it but can’t find one, maybe I need to modify some code which I require help in… Any assistance is greately appreciated.

I am using LDAP user and group backend application as addon.

Hi there.
I guess you have checked the Settings under Advanced / Directory Settings and found the two attribute mappigs User Display Name Field and 2nd User Display Name Field. Here you could set a second field in addition to display name. I would go for changing the data in the directory, if somehow possible. If you want to hack this into the code, you can start by checking out the handling of ldapUserDisplayName2 field in apps/user_ldap.

Yes, you are correct I needed some assistance to do that since I am not able to understand it well

Maybe, I can give you some assistance with this. First, I would suggest moving this conversation to Development forum, because it’s rather development than support issue. Second, I wonder if you can share some details about your nextcloud environment, like OS and version.
If you’re familiar with PHP start looking into apps/user_ldap/lib/User/User.php at function processAttributes where you find the values from LDAP being put together for Nextcloud. I can have a look myself in the next few days too.

Thank you very much.

I found that id of the settings page field for 2nd display name was ldap_user_display_name_2 so I tried changing these files to have a similar field for ldap_user_display_name_3 and setter methods accordingly

This added the required field in the UI on the Advanced / Directory Settings page but it does not display the 3rd attribute by picking up from the ldap server

Thanks for pointing this out. I am checking it

A side quest as well in the same:-
My case is that organization officers have rank unit, designation and a personal No. as attributes which are needed to distinguish users… So I set up a test user Naufil Asar in which attributes rank has value of ‘egRank’, unit = egUnit and so on

The expected result would be, so need to remove the parenthesis put in those 2nd displayName:
egRank Naufil Asar egUnit egDesignation egPersonalNo
Also I do not have authority to modify AD in the production environment, this is my test machine and I have only basic understanding of general programming so php syntax is intimidating for first time for me…


Thanks once again for your help

Okay. For moving the thread to Development I guess you need to edit your initial post and change the category. I haven’t done or tried either.
For the coding, you can have a look at Pull Request 36565 to get an better idea of what needs to be done for adding more LDAP attributes.

I’ll try to explain and clearify how it’s connected.

apps/user_ldap/templates/settings.php
PHP producing the HTML settings page.

apps/user_ldap/js/wizard/wizardTabAdvanced.js
JavaScript for handling the Advanced settings tab. Needs to define the Element, the configuration field, and a method to set the value.

apps/user_ldap/lib/Configuration.php
PHP configuration class for the LDAP/AD integration. Configuration array element and default value. Mapping HTML/JavaScript variable to configuration array element.

apps/user_ldap/lib/Connection.php
PHP class connecting the configuration array with the database.

apps/user_ldap/lib/User/Manager.php
PHP class handling the user. In function getAttributes it’s setup, what to read from LDAP/AD.

apps/user_ldap/lib/User/User.php
PHP class doing the work. In function processAttributes the user gets prepared and updated.

So far… I think the best approach could be changing ldap_user_display_name_2 from single value to multi line array. This could minimize the change needed and keep it clean and simple.

1 Like

Thank you for explaining, I will try changing to multiline as you said and check out if it works!

Sorry @march42 , I need some more technical help from you on this… I am not that good to be able to make the right changes required…

Hi again. I made a quick hack for you, so you can try out. It’s not nice yet more a proof of concept stage. Hope it helps.

Here is what I changed and how it works…

It’s using the configuration field ldapUserDisplayName2 as list of attributes, seperated with ++. So, you set the User Display Name Field to egRank and 2nd User Display Name Field to displayName++egUnit++egDesignation++egPersonalNo and all four fields are added, if found.

apps/user_ldap/lib/User/Manager.php in function getAttributes

  • I removed the fixed ldapUserDisplayName2 from the attributes array definition
  • I added a foreach loop to add every attribute listet in ldapUserDisplayName2 seperatly
    • explode("++",$this->access->getConnection()->ldapUserDisplayName2) converts the list to array
    • foreach (explode( ... ) as $attr2) loop through the array and process each attribute name as $attr2
    • array_push($attributes,$attr2); append each listet attribute name to the list of attributes

apps/user_ldap/lib/User/User.php in function processAttributes

  • if there is ++ found in the attribute name (strpos($attr,"++") !== false) we treat it as list of attributes.
  • foreach (...) again loops through the list
    • if attribute $attr2 was returned from the directory isset($ldapEntry[$attr2])
    • we append space (empty($displayName2) ?"" :" ") and the attribute value (string)$ldapEntry[$attr2][0] to $displayName2
    • (empty($displayName2) ?"" :" ") if empty use “” and otherwise " "
    • (string)$ldapEntry[$attr2][0] ensure value is a string

Following is a patch file, you can download at github.com

diff --git a/apps/user_ldap/lib/User/Manager.php b/apps/user_ldap/lib/User/Manager.php
index 04c67a537b8..130a2271351 100644
--- a/apps/user_ldap/lib/User/Manager.php
+++ b/apps/user_ldap/lib/User/Manager.php
@@ -163,6 +163,10 @@ class Manager {
                        $this->access->getConnection()->ldapAttributeHeadline,
                        $this->access->getConnection()->ldapAttributeBiography,
                ];
+               // parse attribute list and add each
+               foreach (explode("++",$this->access->getConnection()->ldapUserDisplayName2) as $attr2) {
+                       array_push($attributes,$attr2);
+               }

                $homeRule = (string)$this->access->getConnection()->homeFolderNamingRule;
                if (strpos($homeRule, 'attr:') === 0) {
diff --git a/apps/user_ldap/lib/User/User.php b/apps/user_ldap/lib/User/User.php
index f85e4206eff..d5f273c0447 100644
--- a/apps/user_ldap/lib/User/User.php
+++ b/apps/user_ldap/lib/User/User.php
@@ -184,8 +184,15 @@ class User {
                        $displayName = (string)$ldapEntry[$attr][0];
                }
                $attr = strtolower($this->connection->ldapUserDisplayName2);
-               if (isset($ldapEntry[$attr])) {
+               if (isset($ldapEntry[$attr])) { // attribute found
                        $displayName2 = (string)$ldapEntry[$attr][0];
+               } elseif (strpos($attr,"++") !== false) {
+                       // list of attributes
+                       foreach (explode("++",$attr) as $attr2) {
+                               if (isset($ldapEntry[$attr2])) {
+                                       $displayName2 .= (empty($displayName2) ?"" :" ") . ((string)$ldapEntry[$attr2][0]);
+                               }
+                       }
                }
                if ($displayName !== '') {
                        $this->composeAndStoreDisplayName($displayName, $displayName2);

EDIT: I needed to fix the $displayName2 concatenation
EDIT2: DisplayName2 is added in paranthesis, so maybe you should set 2nd User Display Name Field to Rank++Unit++Designation++PersonalNo.

Hi @march42 , Thanks for helping

This solution is easier and more logical than what I had been trying, but even after implementing this, the DisplayName2 field is never shown, that is:



So, only the rank field is being shown… I tried debugging and print statements but none worked, so I tried throwing an Exception in Manager.php which showed that getAttribute function receives all the data as expected but exceptions in User.php don’t show up anywhere so I am not sure why this is happening


Hmmm. I will have a closer look later, when i`m at my laptop.

Sorry, if this sounds dumb, its not intented to. Do you know, processAttributes is only called on few events? And it sounds like it didnt fire any of those events for the given user. You can use the occ script to update, which I prefer, for showing the attributes on command output. Even quickndirty debugging with echo/print would show in the output.
php occ ldap:check-user --update <user uid>
The user uid is shown under the users displayname in the list. For egRank it`s starting with D58E…
If you place the output or exception in processAttributes you can better check, i think.

lib/User/User.php

settings LDAP integration
Screenshot (45)

php occ ldap:check-user --update <user uid>

php occ user:setting <user uid>
Screenshot (46)

No, It sounds perfectly logical… I tried generating exception in the composeAndStoreDisplayName() which is called inside it and it logged the exception normally

I’m surprised it does fetch everything for following setting

Is it possible that the displayName is being clipped from ui because it’s getting too long?

and I am very grateful to you for helping me out… I had been very desperate for help

I don’t think so and I have no glue. I would think this is an cache issue, because the data should’nt be updated while cached. At least if you have Memcache configured. If this is an test instance, without real traffic, you could check by setting Cache TTL to 60 seconds (i think it’s in settings, advanced, connection settings). So it would at least update after 1 minute.
AND my bet would be however, that there’s another function setting the Display Name. So it would get changed by processAttribute and rechanged by the other function. I can check this, when I have access to my developing machine.

EDIT: After a quick search I found at least function getDisplayName in lib/User_LDAP.php building the DisplayName and calling composeAndStoreDisplayName.

You’re welcome.

You were right, processAttributes() was never being called

After modifying this function as follows, I got the results I had expected:


Thank you very much @march42

Edit: There is another problem now… I tried creating 500 random users and it kept logging php error:


It is exactly happening from the change I made:

Can you suggest any improvements in this?

1 Like

Hi. Let me have a look and try to figure it out.

  • readAttribute returns an array of values or false
  • the error tells access array offset on bool - this means the return was false because there was no value to return

I would rather do it like this…

	$addThis = $this->access->readAttribute(
		$this->access->username2dn($uid),
		$attr2);
	if (isset($addThis[0])) {
		$displayName2 .= (empty($displayName2) ?"" :" ") . ((string)$addThis[0]);
	}
  1. Buffering the return from readAttribute - otherwise the function would get called twice.
  2. checking, if first value of array $addThis [0] is set and if it’s an array
  3. append the returned value to $displayName2

EDIT: shit, I used the wrong variable name… $additionalAttribute should have been $attr2 in the call to getAttribute, so I corrected it.

Done. Thanks a bunch!