Show First Name, Last initial, with period.

I need our users display names to show on our site as First Name, Last initial, with a period (e.g. John D.). I found this old support question which answers this, but it caused a few issues, and I need a few tweaks

When we use the code from the link above, it causes our website to run extremely slow:

add_action( 'admin_init', 'fix_display_name' );
function fix_display_name() {
	$users = get_users();
	foreach( $users as $user ){
		if( $user->first_name != '' && $user->last_name != '' ){
			$display_name = ucfirst($user->first_name ). ' ' . ucfirst(substr( $user->last_name, 0, 1 ) ). '.';
			wp_update_user(
				array(
				      'ID' => $user->ID,
				      'display_name' => $display_name
				      )
			);
		}
	}
}

I believe it may be because of "get_users", and since we have 150 users, I'm assuming this just keeps running and running.

What we need is:
1) For this code to do an initial big run, to change all existing users display names to be First Name, Last Initial with a period (e.g. John D.).

2) Once that's done, we need the display name to only update when
a) A user updates their profile and
b) A new user registers.

How can we tweak the code to achieve this? We also need to make sure it does not slow down the site as it previously did.

Any help would be greatly appreciated. Thank you.

  • Adam Czajczyk

    Hello Dan,

    I hope you're well and thank you for your question!

    You're most likely right about the reason for the code being slow. There's a loop that goes through all users and then makes changes. This means a lot of database queries. The code is also a simple code that's not asynchronous (or ajax-based) so it's not running in background.

    Taking two goals that you set:

    1) For this code to do an initial big run, to change all existing users display names to be First Name, Last Initial with a period (e.g. John D.).

    The best way to achieve this would be to create a simple WP plugin so you could trigger that "big run" manually with a button in your site's dashboard. The plugin would then have to call this (slightly altered) code via "wp-ajax". This way it shouldn't slow down your site and shouldn't also break with even larger amount of accounts. That's however a bit beyond the scope of this support forum as it's a custom development job. Therefore you may want to post a question on our "Jobs & Pros" job board (please note: no WPMU DEV staff involved!) here:

    https://premium.wpmudev.org/wordpress-development/

    2) Once that's done, we need the display name to only update when
    a) A user updates their profile and
    b) A new user registers.

    An additional code should help you here. I think something like this should do the trick:

    function wpmu_update_display_name($user_id) {
    	$user = get_userdata($user_id);
    	if( $user->first_name != '' && $user->last_name != '' ){
    		$display_name = ucfirst($user->first_name ). ' ' . ucfirst(substr( $user->last_name, 0, 1 ) ). '.';
    		wp_update_user(
    			array(
    		      'ID' => $user->ID,
    		      'display_name' => $display_name
    		      )
    		);
    	}
    }
    add_action('user_register', 'wpmu_update_display_name',10,1);
    add_action('profile_update', 'wpmu_update_display_name',10,1);

    Best regards,
    Adam

  • Adam Czajczyk

    Hello Dan!

    After some more research I came up with a bit different code. Tested on my own setup it seems to be working quite fine and it doesn't add up to site's resource consumption. Take a look below please:

    <?php
    function wpmu_initials_displaynames($user_login, $user) {
    
    	$firstname = ucfirst($user->first_name);
    	$initialname = ucfirst($user->last_name);
    	$initialname = substr(trim($initialname),0,1) . '.';
    	$displayname = $firstname . ' '. $initialname;	
    
         wp_update_user( array ('ID' => $user->ID, 'display_name' => $displayname));    
    
    }
    add_action('wp_login','wpmu_initials_displaynames',10,2);

    The code hooks to the user login action so it's fired every time a user logs in to the site. The nice side-effect is that even if a user changes his display name it will be restored to the "John D." format upon next login.

    Would this work for you?

    The lines operating on "first/last name" strings could be "combined" into a single line but I decided to keep it this way to maintain clarity of the code. To apply the code to your site please create an empty file with a .php extension and then:

    - copy and paste the code inside
    - upload the code to your server to "/wp-content/mu-plugins" folder

    In case there's no "mu-plugins" folder inside "/wp-content" folder, please create it.

    Best regards,
    Adam

    • Dan

      I tested this and it works great.

      The only issue I have is that when a user updates their first or last name, they will not see the change reflected in their display name until they log out and log back in (so they may think something went wrong).

      It is possible to also have this update their display name when they update their profile?

      I tried just adding add_action('profile_update', 'wpmu_initials_displaynames',10,2); below the action you added, but when I tried to update a users profile, the website just tried to refresh for about a minute, then gave me a 502 gateway error.

  • Adam Czajczyk

    Hello Dan,

    I'm happy that my code worked for you.

    As for update "on profile update". The "profile_update" filter is the one but the callback function for it takes different arguments than the one for "wp_login". That said, please try adding this entire code:

    function wpmu_initials_displaynames_update($user_id, $user) {
    
    	$firstname = ucfirst($user->first_name);
    	$initialname = ucfirst($user->last_name);
    	$initialname = substr(trim($initialname),0,1) . '.';
    	$displayname = $firstname . ' '. $initialname;
    
         wp_update_user( array ('ID' => $user->ID, 'display_name' => $displayname));    
    
    }
    add_action('profile_update', 'wpmu_initials_displaynames_update',10,2);

    Best regards,
    Adam

    • Dan

      I tried this and after a user tries to update their profile on the front end, it runs for about 1 minute, I receive a jquery error, but if I refresh the page after this I can see it did update the display name, so it almost works.

      We use a plugin called UserPro for our front end profile updates, which uses ajax. This does tie into the default WP user database though.

      I talked to their developer about what we're trying to do and they said that they have a hook for when a user updates their profile on the front end.
      do_action(‘userpro_profile_update’, $form, $user_id);

      I'm not sure how to put this into any of the existing functions you created though, since it's not an add_action.

  • Adam Czajczyk

    Hey Dan!

    I wasn't aware that you're using any "front-end profile" plugin. Although the "profile_update" is a WP core filter, I'd agree that it may be better to hook to plugin's hook.

    The "do_action()" means that at the point of code where it's placed the callback function will be triggered and you add that callback function with... "add_action()" :slight_smile: The "skeleton" code then could be like this:

    add_action('userpro_profile_update', 'my_user_profile_update',10,2);
    function my_user_profile_update($form, $user_id) {
    /*** here comes profile update code ***/
    }

    A brief explanation of the above:

    - userpro_profile_update - name of the hook called by "do_action()"
    - my_user_profile_update($form,$user_id) - your custom filter function
    - "10" - priority of the function (you can use multiple custom filters and this value specifies order of execution then)
    - "2" - number of parameters passed to your custom function

    This should let you re-use any of my code though you'll have to examine the data contained by "$form" variable which, I think, is the data sent by "profile update form".

    I hope that helps!
    Best regards,
    Adam

    • Dan

      Since I'm not a huge coder, here is the code I tried to use, adding the parameters from your existing code ($user, $user_login) to the function, then changing the number of parameters to 4:

      <?php
      
      add_action('userpro_profile_update', 'my_user_profile_update',10,4);
      
      function my_user_profile_update($user_login, $user, $form, $user_id) {
      
      	$firstname = ucfirst($user->first_name);
      	$initialname = ucfirst($user->last_name);
      	$initialname = substr(trim($initialname),0,1) . '.';
      	$displayname = $firstname . ' '. $initialname;	
      
           wp_update_user( array ('ID' => $user->ID, 'display_name' => $displayname));    
      
      }
      
      ?>

      This did not update the display name on the front end though when a user updated their profile, only the back end.

      I'm sure I'm doing something wrong but can't figure it out.

  • Adam Czajczyk

    Hello Dan!

    I'm sorry, I confused you. Mixing "directly" that hook with any of my codes won't work. You could adjust my code though to match data sent by UserPro plugin. The hook that its developer suggested seems legitimate but we also need to know exactly what data is being passed to it so we need to know what's "inside" the "$form" variable.

    Unfortunately, UserPro is a premium plugin and I do not have access to it so I'm not able to check this. I think however that you could get in touch with plugin developer again (it seems they're responding pretty fast) and ask them about the "$form" variable. Let me know please of their replay and I think I'll be able to help you with code modification.

    Best regards,
    Adam

    • Dan

      Although this does not make perfect sense to me, the developers response is below. Their example isn't exactly what we're doing, but you may have a better idea what they mean. Sorry for all the back and forth on this, just trying to get it figured out.

      Developer Response
      "There’s a hook that runs after profile is updated do_action(‘userpro_profile_update’, $form, $user_id);

      For example, to sync a different meta field by hooking into it, you can get any submitted field from $form and apply it to another user meta.. :slight_smile: You get it? It’s like that

      Example, I can get the first name submitted by $form[‘first_name’] and make update_user_meta(xxx, ‘billing_first_name’, $form[‘first_name’]

      That hook runs after PROFILE IS UPDATED always even when new user sign up."

      I did notice that when a user updates their first name or last name on the front end, it does change it in the front end and back end, it's just the display name that isn't changing. So maybe we need to update the display_name meta to the first name last initial when updating their profile on the front end?

      I also checked their code file for user-functions, and this is the code they have for a user updating their profile. At the very bottom is the do_action for userpro_profile_update:

      /* Update user profile data */
      	function userpro_update_user_profile($user_id, $form, $action=null) {
      		global $userpro;
      		$template = (isset($form['template'])) ? $form['template'] : 0;
      		$group = (isset($form['group'])) ? $form['group'] : 0;
      		if ($action == 'new_user' && !$userpro->user_exists($user_id) )
      			die();
      
      		if (!$userpro->user_exists($user_id))
      			die();
      
      		if ( $action == 'ajax_save' && $user_id != get_current_user_id() && !current_user_can('manage_options') &&  !userpro_get_edit_userrole() )
      			die();
      
      		if (!$template) die();
      
      		/* hooks before saving profile fields */
      		do_action('userpro_pre_profile_update', $form, $user_id);
      		$form = apply_filters('userpro_pre_profile_update_filters', $form, $user_id);
      
      		$fields = userpro_fields_group_by_template( $template, $group );
      		$allfields=get_option('userpro_fields_groups');
                      $editfields=$allfields['edit']['default'];
      		foreach($form as $key => $form_value) {
      			//$form_value = esc_attr($form_value);  // Commented to solve Array issue
      			/* hidden from public */
      			if (!isset($form["hide_$key"])) {
      				update_user_meta( $user_id, 'hide_'.$key, 0 );
      			} elseif (isset($form["hide_$key"])){
      				update_user_meta( $user_id, 'hide_'.$key, 1 );
      			}
      
      			/* UPDATE PRIMARY META */
      			if ( isset($key) && in_array($key, array('user_url', 'display_name', 'role', 'user_login', 'user_pass', 'user_pass_confirm', 'user_email')) ) {
      
      				/* Save passwords */
      				if ($key == 'user_pass') {
      					if (!empty($form_value)) {
      						wp_update_user( array ( 'ID' => $user_id, $key => $form_value ) ) ;
      					}
      				} else {
      					if($key=='role' && $form[$key]=='administrator' && !is_admin()){
      						continue;
      					}
      					else{
      						wp_update_user( array ( 'ID' => $user_id, $key => $form_value ) ) ;
      					}
      				}
      
      			}
      
      			/* delete unused uploads */
      			if ( ( isset($fields[$key]['type']) && $fields[$key]['type'] == 'picture' || isset($fields[$key]['type']) && $fields[$key]['type'] == 'file'  ) && isset($form_value) && !empty($form_value) && basename($form_value) != basename( userpro_profile_data( $key, $user_id ) ) ) {
      				$userpro->delete_file($user_id, $key);
      			}
      
      			if (isset($key) && !strstr($key, 'pass')){
      
      				$countrylist=get_option('userpro_fields');
      			     if(isset($countrylist['billing_country']['options']))
      			       $country=$countrylist['billing_country']['options'];
      				if($key=='billing_country' )
      				{
      
      					foreach($country as $country_code => $country_name)
      					{
      
      						if($country_name==$form_value)
      						{
      						 	$form_value = $country_code;
      
      							update_user_meta( $user_id, $key, $form_value );
      						}
      					}
      
      				}
      
      				if($key=='shipping_country' )
      				{
      					foreach($country as $country_code => $country_name)
      					{
      
      						if($country_name==$form_value)
      						{
      						 	$form_value = $country_code;
      
      				update_user_meta( $user_id, $key, $form_value );
      						}
      					}
      				}
      				else
      				{
      					update_user_meta( $user_id, $key, $form_value );
      				}	
      
      			} else {
      				delete_user_meta( $user_id, $key );
      			}
      
      			/* move user pics to his folder */
      			if ( ( isset($fields[$key]['type']) && $fields[$key]['type'] == 'picture' || isset($fields[$key]['type']) && $fields[$key]['type'] == 'file'  ) && isset($form_value) && !empty($form_value) ) {
      
      				$userpro->do_uploads_dir( $user_id );
      
      				if ( file_exists( $userpro->get_uploads_dir() . basename( userpro_profile_data( $key, $user_id ) ) ) ) {
      					rename( $userpro->get_uploads_dir() . basename( userpro_profile_data( $key, $user_id ) ),  $userpro->get_uploads_dir($user_id) . basename( userpro_profile_data( $key, $user_id ) ) );
      
      					update_user_meta($user_id, $key, $userpro->get_uploads_url($user_id) . basename( userpro_profile_data( $key, $user_id ) ) );
      				}
      
      			}
      
      			/* MailChimp Integration */
      			if ( ( isset($fields[$key]['type']) && $fields[$key]['type'] == 'mailchimp') ) {
      				if ($form[$key] == 'unsubscribed'){
      				if(userpro_get_option('aweber_api')!='' && userpro_get_option('aweber_listname')!='')
                                      $userpro->makeAweberSubscribeEntry($user_id);
      				if(userpro_get_option('Campaignmonitor_listname')!='' && userpro_get_option('Campaignmonitor_api')!='')
      				$userpro->makeCampaignmonitorEntry($user_id);
      				$userpro->mailchimp_subscribe( $user_id, $fields[$key]['list_id'] );
      				} elseif ($form[$key] == 'subscribed') {
      				$userpro->mailchimp_unsubscribe( $user_id, $fields[$key]['list_id'] );
      				}
      			}
      
      		}
      
      					foreach($editfields as $editfieldkey=>$editfieldvalue)
      					{
      						if(isset($editfieldvalue['type']))
      						if($editfieldvalue['type']=='checkbox-full' || $editfieldvalue['type']=='multiselect'  || $editfieldvalue['type']=='checkbox')
      						{
      							if (!array_key_exists($editfieldkey,$form))
      							{
      								delete_user_meta($user_id,$editfieldkey);
      
      							}
      
      						}
      
      					}	
      
      		/* do action while updating profile (use $form) */
      		do_action('userpro_profile_update', $form, $user_id);
      
      		/* after profile update no args */
      		do_action('userpro_after_profile_updated');
      
      	}

      Also, I checked their support page and a few users have asked similar questions related to the profile updating LINK

  • Milan

    Hello Dan ,

    Can you also try to use this snippet ?

    add_action( 'userpro_profile_update', 'wpmu_set_initials', '', 2 );
    function wpmu_set_initials( $form, $user_id ){
    
    	$firstname = ucfirst($form['first_name']);
    	$initialname = ucfirst($form['last_name']);
    	$initialname = substr(trim($initialname),0,1) . '.';
    	$displayname = $firstname . ' '. $initialname;
    
    	wp_update_user( array ('ID' => $user->ID, 'display_name' => $displayname));
    }

    Let us know how it goes. :slight_smile:
    Cheers,
    Milan

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.