7.x system.api.php hook_username_alter(&$name, $account)

Alter the username that is displayed for a user.

Called by format_username() to allow modules to alter the username that's displayed. Can be used to ensure user privacy in situations where $account->name is too revealing.

Parameters

$name: The string that format_username() will return.

$account: The account object passed to format_username().

See also

format_username()

Related topics

1 invocation of hook_username_alter()
format_username in includes/common.inc
Format a username.

File

modules/system/system.api.php, line 4384
Hooks provided by Drupal core and the System module.

Code

function hook_username_alter(&$name, $account) {
  // Display the user's uid instead of name.
  if (isset($account->uid)) {
    $name = t('User !uid', array('!uid' => $account->uid));
  }
}

Comments

nathangervais’s picture

I was unable to get this hook to fire until I placed it in my template.php file.

Do not treat this like a module hook function.

matt2000’s picture

Then you were doing something else wrong. This works fine in modules. It just happens that alter hooks can ALSO be used in themes.

mxh’s picture

<?php
function yourmoduleORtheme_username_alter(&$name, $account) {
/* load the full user object, since $account not always provide all informations */  
$user = user_load($account->uid);
/* 
field_extract_value(): function provided by field_extract module (thanks adaddinsane!)
 */
  if (!empty($user->field_firstname) && !empty($user->field_surname)) {
    $name = field_extract_value('user', $user, 'field_firstname') . ' ' . field_extract_value('user', $user, 'field_surname');
  }
}
?>
mpdonadio’s picture

Just note that field_extract_value() isn't in core. It's provided by http://drupal.org/project/1158878

tjhart87’s picture

Within your created module file:

/**
* Implementation of hook_username_alter().
*/
function module_username_alter(&$name, $account) {
// Get the user profile
$profile = profile2_load_by_user($account, 'profile_name');
if ($profile) {
$firstname = field_get_items('profile2', $profile, 'field_first_name');
if ($firstname) {
$name = $firstname[0]['value'];
}
}
}

matt2000’s picture

Note that this hook is fired anytime a formatted user name is required. One example that caught me by surprise was via user_token(), which can cause the altered version of the username to be used things like PathAuto aliases. Don't assume this is for human-readable output only!

Rob230’s picture

Yes, you need to be careful with this. I used it to show [first name] [last name] on my site, but it gets called on [user:name] tokens as well, which appear in the welcome emails, so people were being told the wrong username to log in with.

If you have changed the username using hook_username_alter() then there is no token to get the raw username any more.

kiamlaluno’s picture

The equivalent hook in Drupal 8 is hook_user_format_name_alter().

dalin’s picture

There are many edge cases that you must consider when using this hook:

- The user object may not be fully populated. If $account->uid == $user->uid then $account may not have fields attached (Since during bootstrap Drupal only creates a minimal version of $user). So you may need to reload the user object.

- Working with Drupal's arrays of doom is not fun. I recommend using EntityMetadataWrapper (part of Entity API module) where possible.

- This hook may be called for a deleted user. In my particular case, user objects were being passed to a cron queue. But the user object might be deleted before the queue item is processed. So you may need a try/catch block.

- This may be called on a user object that is not yet saved and thus does not have a uid. This will throw havoc with a static cache variable. Albeit this scenario might only happen if you inflict this upon yourself somewhere in custom code.

Here's an example implementation that takes all of the above into consideration. You'll need to change the logic for determining the $key, and the bit in the middle for actually altering the username. (warning, the PHP code filter is throwing in funny line breaks and spacing)

/**
 * Implements hook_username_alter();
 */
function mymodule_username_alter(&$name, $account) {
  $accounts = drupal_static(__FUNCTION__, array());
  
  if (!$account) {
    return;
  }
  
  // We may not have enough of an object to use EMW.  But we need some sort of 
  // key for our static.  Use individual_id if present (a UUID), else use uid, else use
  // a random MD5.  In theory there should be no collisions.  The MD5 will not 
  // be consistent for each call of the function, but since this is for an 
  // unsaved user object, in theory it will get saved shortly.
  $key = !empty($account->field_user_individual_id['und'][0]['value'])  ? $account->field_user_individual_id['und'][0]['value'] : (isset($account->uid) ? $account->uid : md5(mt_rand()));
  
  if (!isset($accounts[$key])) {
    try {
      // $account is not always fully populated if $account->uid == $user->uid.
      if (!isset($account->field_user_name) && isset($account->uid)) {
        $wrapper = entity_metadata_wrapper('user', $account->uid);
      }
      else {
        $wrapper = entity_metadata_wrapper('user', $account);
      }
      
      // The default is what was passed in.
      $accounts[$key] = $name;
      
      if ($user_name = $wrapper->field_user_name->value()) {
        $accounts[$key] = $user_name;
      }
      
      // Append ' - retired' if necessary.
      if ($wrapper->field_user_retired->value()) {
        $accounts[$key] .= ' - ' . t('retired');
      }
    }
    catch (Exception $exc) {
      // Most likely because the user account has been deleted.  Don't even
      // bother logging this.
      $accounts[$key] = t('unknown user name');
    }
  }
  $name = $accounts[$key];
}