• I’ve seen many requests for this, but no solutions. So a colleague and I spent the last few hours figuring this out.

    It’s quite dirty, but does the job, just place it in your theme functions.php on a single site, or in a functions.php file inside your mu-plugins folder on a multisite.

    The script will also scan existing users (if your site already has many) and any non unique display names will be updated and replaced with username.

    I know this isn’t totally ideal, but any suggestions for dealing with existing users or improvements are always welcome.

    // Make nickname & display_name unique
    // and automatically change non unique nicks & display name to username
    // in case you already have existing users
    // by Ashok & Vaughan Montgomery
    /*
     * adding action when user profile is updated
     */
    add_action('personal_options_update', 'check_display_name');
    add_action('edit_user_profile_update', 'check_display_name');
    function check_display_name($user_id) {
            global $wpdb;
        // Getting user data and user meta data
            $err['display'] = $wpdb->get_var($wpdb->prepare("SELECT COUNT(ID) FROM $wpdb->users WHERE display_name = %s AND ID <> %d", $_POST['display_name'], $_POST['user_id']));
        $err['nick'] = $wpdb->get_var($wpdb->prepare("SELECT COUNT(ID) FROM $wpdb->users as users, $wpdb->usermeta as meta WHERE users.ID = meta.user_id AND meta.meta_key = 'nickname' AND meta.meta_value = %s AND users.ID <> %d", $_POST['nickname'], $_POST['user_id']));
        foreach($err as $key => $e) {
            // If display name or nickname already exists
            if($e >= 1) {
                $err[$key] = $_POST['username'];
                // Adding filter to corresponding error
                add_filter('user_profile_update_errors', "check_{$key}_field", 10, 3);
            }
        }
    }
    /*
     * Filter function for display name error
     */
    function check_display_field($errors, $update, $user) {
            $errors->add('display_name_error',__('<span id="IL_AD9" class="IL_AD">Sorry</span>, Display Name is already in use. It needs to be unique.'));
            return false;
    }
    /*
     * Filter function for nickname error
     */
    function check_nick_field($errors, $update, $user) {
            $errors->add('display_nick_error',__('Sorry, Nickname is already in use. It needs to be unique.'));
            return false;
    }
    /*
     * Check for duplicate display name and nickname and <span id="IL_AD2" class="IL_AD">replace with</span> username
     */
    function display_name_and_nickname_duplicate_check() {
        global $wpdb;
        $query = $wpdb->get_results("SELECT * FROM $wpdb->users");
        $query2 = $wpdb->get_results("SELECT * FROM $wpdb->users as users, $wpdb->usermeta as meta WHERE users.ID = meta.user_id AND meta.meta_key = 'nickname'");
        $c = count($query);
        for($i = 0; $i < $c; $i++) {
            for($j = $i+1; $j < $c; $j++) {
                if($query[$i]->display_name == $query[$j]->display_name){
                    wp_update_user(
                            array(
                                  'ID' => $query[$i]->ID,
                                  'display_name' => $query[$i]->user_login
                            )
                        );
                }
                if($query2[$i]->meta_value == $query2[$j]->meta_value){
                    update_user_meta($query2[$i]->ID, 'nickname', $query2[$i]->user_login, $prev_value);
                }
            }
        }
    }
    // Call the function
    display_name_and_nickname_duplicate_check();
    
    /*
     * Calling the display_name_and_nickname_duplicate_check() again when a new user is registered
     */
    add_action( 'user_register', 'check_nickname', 10, 1 );
    function check_nickname() {
        display_name_and_nickname_duplicate_check();
    }
Viewing 7 replies - 1 through 7 (of 7 total)
  • Ashok

    (@bappidgreat)

    Awesome 🙂

    freelancer486

    (@freelancer486)

    Hi Vaughan:

    I’m not sure the above code completely addresses the problem.

    Here is what I did to circumvent the uniqueness test.

    I had two users with display name of “Bob”.

    I added the above code. It correctly changed one of these to the user’s email address, which is their username in this case.

    I logged in as the second “Bob” user. I set his nickname to the email address of the first user then made that his display name.

    Now I have two users with the display name of the first user.

    freelancer486

    (@freelancer486)

    Similarly by messing with combinations of first name and nick name, I’ve been able to steal the display name of another user and force his back to to his username.

    Thread Starter Vaughan

    (@m0nty)

    What happens if you only run the duplicate check once?

    So for an existing site, run it once.

    Then completely remove the following.

    /*
     * Check for duplicate display name and nickname and <span id="IL_AD2" class="IL_AD">replace with</span> username
     */
    function display_name_and_nickname_duplicate_check() {
        global $wpdb;
        $query = $wpdb->get_results("SELECT * FROM $wpdb->users");
        $query2 = $wpdb->get_results("SELECT * FROM $wpdb->users as users, $wpdb->usermeta as meta WHERE users.ID = meta.user_id AND meta.meta_key = 'nickname'");
        $c = count($query);
        for($i = 0; $i < $c; $i++) {
            for($j = $i+1; $j < $c; $j++) {
                if($query[$i]->display_name == $query[$j]->display_name){
                    wp_update_user(
                            array(
                                  'ID' => $query[$i]->ID,
                                  'display_name' => $query[$i]->user_login
                            )
                        );
                }
                if($query2[$i]->meta_value == $query2[$j]->meta_value){
                    update_user_meta($query2[$i]->ID, 'nickname', $query2[$i]->user_login, $prev_value);
                }
            }
        }
    }
    // Call the function
    display_name_and_nickname_duplicate_check();
    
    /*
     * Calling the display_name_and_nickname_duplicate_check() again when a new user is registered
     */
    add_action( 'user_register', 'check_nickname', 10, 1 );
    function check_nickname() {
        display_name_and_nickname_duplicate_check();
    }

    Are you able to still do that then?

    Initially I only planned that function needing to be ran 1 time only, not to be continually used.

    freelancer486

    (@freelancer486)

    Perhaps I have another plugin interfering, but I’m not getting the expected on screen errors and I don’t think the checks are working when saving out the profile. I tried running the code with the blocks you suggested removed but it did not seem to affect the behavior in my profile screen for my test users.

    I can set two users with the same nickname. When I view the forum, one of the users gets flipped back to their Username.

    I just set a user’s Nickname to “admin”. When viewed in the forums that user is masquerading as admin.

    When I set a third user’s nickname to “admin” and viewed the forum, the last user is now flipped to their username.

    A robust model would not allow a user to choose a displayname that is in use by another user, nor another users login name.

    We can’t have unintended confusion between users or intentional monkeyshines like users masquerading as an admin.

    I can’t believe this is not part of the WordPress core.

    freelancer486

    (@freelancer486)

    Kudos to you for attempting to resolve this problem.

    freelancer486

    (@freelancer486)

    I just tried moving the code to mu-plugins.

    The site locks up with the following error logged.

    PHP Fatal error: Call to undefined function get_userdata() in <mypath>/wp-includes/user.php on line 1466

    I have no idea how to proceed at this point.

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘How to make Displayname & nicknames Unique’ is closed to new replies.