WordPress.org

Make WordPress Core

Opened 19 months ago

Last modified 9 months ago

#43734 new defect (bug)

user_profile_update_errors hook needs work-around to validate a to-be updated email address

Reported by: BjornW Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Users Keywords:
Focuses: docs Cc:
PR Number:

Description

The 'user_profile_update_errors' hook can be used to (in)validate (custom added) fields in the user_profile before these fields are saved.

As far as I know, the 'best-practice' to do this is, is by accessing the field using it's name in $_POST. Grab it's value, do your thing and if this results in an error, add an error message to the $errors object and prevent the field from being saved to the database.

This does not work with the email field anymore (since WordPress version 4.9.0?), because $_POST['email'] is reset to the current value in the database in the function send_confirmation_on_profile_email(). See: wp-includes/user.php

The reset of $_POST['email'] to the current email address in the database prevents the 'best-practice' of accessing a field's value through $_POST because the new email address is now gone from $_POST.

Why is there a reset on $_POST?

My assumption is:
Resetting $_POST['email'] to the current email address in the database is needed, because of the new flow in WordPres in which WordPress requests a user's confirmation of a proposed email change (by sending an email to the new address and requesting the user to clink a link to confirm the change) before saving the new email address.

Therefor the value in the form should (at least temporarily) not be changed until the user has confirmed the change in email address. The chosen solution is such that the new email address is temporarily saved in a user meta field with the name '_new_email' including a hash. This is then processed upon when the user clicks on the link in the email requesting the email change.

Solution
I don't have a good solution yet and by submitting this ticket I hope more people can have a look at this issue.

For now I'd suggest to update docs to include detailed information on how to use the user meta field _new_email['newemail']}} instead of {{{$_POST['email'] in the user_profile_update_errors hook.



Change History (4)

#1 follow-up: @soulseekah
18 months ago

I think the deeper issue is that there's no straightforward way to prevent send_confirmation_on_profile_email from running without prevalidation. Like what if I want to prevent certain domains from being picked as a new e-mail? I should be able to prevent everything from triggering.

One way is to register personal_options_update and edit_user_profile_update hooks and remove send_confirmation_on_profile_email and then run it after validation. But that seems hacky.

#2 in reply to: ↑ 1 @BjornW
18 months ago

Replying to soulseekah:

I think the deeper issue is that there's no straightforward way to prevent send_confirmation_on_profile_email from running without prevalidation. Like what if I want to prevent certain domains from being picked as a new e-mail? I should be able to prevent everything from triggering.

One way is to register personal_options_update and edit_user_profile_update hooks and remove send_confirmation_on_profile_email and then run it after validation. But that seems hacky.

I agree completely. Seems to me the current implementation warrants a better one taking these use cases into account. I guess we need to come up with a patch as a proof-of-concept?

This ticket was mentioned in Slack in #core by bjornw. View the logs.


17 months ago

#4 @pento
9 months ago

  • Version trunk deleted
Note: See TracTickets for help on using tickets.