Opened 8 years ago
Last modified 5 years ago
#39370 new defect (bug)
wp_insert_user() appends suffix to nicename when updating already existing user
Reported by: | alfhen | Owned by: | |
---|---|---|---|
Milestone: | Future Release | Priority: | normal |
Severity: | normal | Version: | 4.6.1 |
Component: | Users | Keywords: | reporter-feedback has-patch needs-testing needs-unit-tests |
Focuses: | Cc: |
Description
wp_insert_user() appends suffix to nicename when updating already existing user, even though the user_nicename prop is set to exactly the same value as it currently has.
Steps to reproduce:
- Asuming you have a user in your wordpress database with the ID 1 and user_nicename set to 'test-nicename'.
- If you then make an update using wp_insert_user() of that user and in the update set the user_nicename to 'test-nicename', then wordpress will update the user, but append -2 as a suffix to the nicename.
This happens because of a check located on line 1597 - 1609 in wp-includes/user.php
<?php $user_nicename_check = $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1" , $user_nicename, $user_login)); if ( $user_nicename_check) { $suffix = 2; while ($user_nicename_check) { // user_nicename allows 50 chars. Subtract one for a hyphen, plus the length of the suffix. $base_length = 49 - mb_strlen( $suffix ); $alt_user_nicename = mb_substr( $user_nicename, 0, $base_length ) . "-$suffix"; $user_nicename_check = $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1" , $alt_user_nicename, $user_login)); $suffix++; } $user_nicename = $alt_user_nicename; }
This code is there to make sure that there are no duplicate nicenames in the wp_users table, which is fine. However it does not take into account updating the nicename of a user with the same value as it currently has.
The way to solve it is very easy, only simply changes the if() statement to check the id fethced in $user_nicename_check against the ID of the user currently being updated, like so:
<?php $user_nicename_check = $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1" , $user_nicename, $user_login)); if ( $user_nicename_check && $ID != $user_nicename_check) { $suffix = 2; while ($user_nicename_check) { // user_nicename allows 50 chars. Subtract one for a hyphen, plus the length of the suffix. $base_length = 49 - mb_strlen( $suffix ); $alt_user_nicename = mb_substr( $user_nicename, 0, $base_length ) . "-$suffix"; $user_nicename_check = $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1" , $alt_user_nicename, $user_login)); $suffix++; } $user_nicename = $alt_user_nicename; }
This makes prevents the code from appending the suffix when the $user_nicename_check ID matches the ID of the user currently being updated
Attachments (2)
Change History (8)
#2
@
5 years ago
- Keywords reporter-feedback added
Hello @alfhen,
Welcome in WordPress trac! I know that this ticket is quite old now but I'm having difficulties to reproduce the problem.
Using wp_insert_user()
without ID
param and with user_nicename
that already exists will create a new user with suffixed user_nicename
.
Using wp_insert_user()
with ID
and with user_nicename
that's the same as the current user's user_nicename
will update the user info properly. user_nicename
isn't suffixed.
In short, I can't seem to find a way to use wp_insert_user()
that updates the an existing user that also suffixed the user_nicename
. If you can give the exact wp_insert_user()
code you use to produce the problem, it will definitely help.
Thank you!
This ticket was mentioned in Slack in #core by david.baumwald. View the logs.
5 years ago
#4
@
5 years ago
- Milestone changed from 5.4 to Future Release
With 5.4 Beta 3 landing tomorrow, this is being moved to Future Release
. If any maintainer or committer feels this can be resolved in time or wishes to assume ownership during a specific cycle, feel free to update the milestone accordingly.
#5
@
5 years ago
As far as I see this can happen when the $user_login
has been changed. This cannot happen in code by default ($user_login is not changeable), but can be added/enabled by a plugin.
Then the DB query will "find" a user ID as the updated $user_login
hasn't been saved yet. So using the $user_login
to confirm if it is the same user doesn't work. Would be better to use the user ID for that.
Patch with the mentioned fix