wp_insert_user on init duplicate created user
-
Hello, i encounter a problem on using
wp_insert_user, called into an init hook.I try to stop execution before to call it, of course the user isn’t created, nor elsewhere at this time.
Then i try this, i exit immediately after:
$user_id = wp_insert_user( $userdata ); exit;
and what happen, is that a duplicated user created into wp db, with all the same, except ID.How it could be possible?
-
This topic was modified 6 years, 4 months ago by
axew3.
-
This topic was modified 6 years, 4 months ago by
-
It could be a plugin or your theme is making another request as part of the primary request. Thus “init” fires twice for a single primary request. Try deactivating all plugins and switching your theme to one of the twenty* default themes. Add your “init” hook temporarily to the theme’s functions.php. You should find only one user is added per request.
I verified on my site that inserting a user from the “init” hook does result in only one user added per request. There’s nothing in core WP that would cause the behavior you experience. Furthermore, WP should not insert another user with the same login name even if their ID is different.
Hello @bcworkz! I have think the same, but i have come out crazy after hours on understand how it can happen.
As said, if i stop the execution before:
exit; $user_id = wp_insert_user( $userdata );nothing happen at this point, no user inserted.
If i do this:
$user_id = wp_insert_user( $userdata );exit;
double user happen.
https://plugins.trac.ww.wp.xz.cn/export/HEAD/wp-w3all-phpbb-integration/trunk/class.wp.w3all-phpbb.php
line 1660:
$user_id = wp_insert_user( $userdata );
The verify_credentials function of course execute in sequence two times, because when user come with right credentials, then it is added, and a redirect happen.
After insertion, the redirect happen with an exit. But the user seem to be added at one time, twice, at same moment. May there is on queue in the stack, and already a call to this? I’ve so try out to comment out the wp_insert_user to look if it happen somewhere and not in this exact time/line of code.
Nothing to do, there is no insertion if the line removed. No other in the stack seem to interfere.I will try to look around again, i’m sure it is something like you describe. But how it happen, it is a mistery at moment, which i resolved with a trick that i would like, of course, to resolve in different common way.
I’m on tewntytwenty at moment.
I will return over asap.I think the redirect is causing the second insertion. It’s not “at same moment”, but that would be difficult to discern unless precise timestamps have been logged. It still does not explain how identical user names can be entered. It must be PHPbb or the w3all add-on allowing it.
Why insert users from “init” anyway. That does not sound like a good practice. There must be better actions to use. Or at least add something to your code to prevent duplicate insertions. It’s good practice to assume any action could fire more than once in any one request. Many actions do.
after_setup_theme
seem to work fine in front end.
The problem seem to disappear and all work smooth … testing more and move to this then. Or have a better or further suggestion?I will try to understand why it was happening if possible
Nope … unfortunately no, moving to
after_setup_themefrom init, did not resolved nothing at all.Hello!
So to anyone may fall on this, i would like to just leave a note, since i think i resolved, also thank to your hint.
The problem, isn’t when you just insert an user on init with priority 1,2 or 3 or 10, but,
the problem come out instead, if you immediately after do the follow:wp_set_current_user( $user->ID, $user->user_login ); wp_set_auth_cookie( $user->ID, $remember, is_ssl() ); do_action( 'wp_login', $user->user_login, $user );This seem to cause the double insertion of the user, i assume because into file
/wp-includes/user.php
where
$user = new WP_User( $user_id );
at this time the new WP_User still will not be may available for some other process, that execute the login (may i’m wrong on this but i will follow on reverse if i can asap) and on redirect, the mess come up.So i resolved doing this, into the init (ordered to be executed as first of all) that execute before (the define is not a required thing, only needed for my needs in this case):
if(!defined(“WPUSERJUSTINSDATA”)){
$udata = serialize($user);
define(“WPUSERJUSTINSDATA”,$udata);
return;
}Then into another place, ordered to be executed after, init 10:
add_action( 'init', array( 'WP_w3all_phpbb','w3_wplogin_after_ins'), 10, 0 );
then the function can be like this (note that the define is always just for this case and totally custom way), as example that need to be little improved, do this:public static function w3_wplogin_after_ins(){ if(defined("WPUSERJUSTINSDATA")){ $user = unserialize(WPUSERJUSTINSDATA); $remember = 1; wp_set_current_user( $user->ID, $user->user_login ); wp_set_auth_cookie( $user->ID, $remember, is_ssl() ); do_action( 'wp_login', $user->user_login, $user ); wp_redirect(home_url()); exit(); } }That resolve the issue.
Thank you again, your thought helped me a lot.
If any news, and still problems, i will return over again to just let you know.So, i tested further more and the solution to this has been:
on init with priority (like 2)
execute wp_insert_user
but do NOT execute, immediately after, something like this:wp_set_current_user( $user->ID, $user->user_login ); wp_set_auth_cookie( $user->ID, $remember, is_ssl() ); do_action( 'wp_login', $user->user_login, $user );and move this in case, to be executed (may) into same hook (an init in this case) with less priority (like 10).
For what i noted, this affect any way, any hook you could apply this in the sequence i mention above: the unique way, is to execute the login flow (may) also into same hook, but that will be fired after wp_insert_user execution.
So i mark this as resolved, thank u again!
Cheers!You’re welcome. I’m glad you found a solution. The fact you needed to move a portion into a separate callback tells me you’ve encountered a race condition. To give yourself a greater margin to allow one condition to fully complete before acting upon it, consider using a very large priority argument for the second part to allow all other init callbacks to execute first. Or even moving it to a later action, perhaps “wp”. A list of actions, in approximate order of execution:
https://codex.ww.wp.xz.cn/Plugin_API/Action_Reference
Remember that not all actions always fire on any given request.Awesome, thank a lot again @bcworkz
The topic ‘wp_insert_user on init duplicate created user’ is closed to new replies.