I set up a front end form for logged in users to update their email address. So far it is working however I want the user, after confirming the email change via link sent to the new address, to be redirected to a custom front-end page.(after the change done in /wp-admin/edit-profile.php).
Thus the user never seeing the backend user profile page.
Here is the code for the form
<form action="<?php the_permalink(); ?>" method="post">
<div class="form-group">
<label for="e-mail">E-mail</label>
<input type="email" class="form-control" value="<?php echo esc_html($current_user->user_email); ?>" name="email" id="email">
<small class="form-text text-muted">If you change this we will send you an email at your new address to confirm it. <strong>The new address will not become active until confirmed.</strong></small>
</div>
<button class="btn btn-primary" type="submit">Change E-mail</button>
</form>
and the form processing
if (isset( $_POST['email'])) {
// check if user is really updating the value
if ($user_email != $_POST['email']) {
// check if email is free to use
if (email_exists( $_POST['email'] )){
// email already taken
echo 'That e-mail address is not available.';
exit();
} else {
$_POST['user_id'] = $current_user->ID;
send_confirmation_on_profile_email();
echo 'User update email ink sent to new email for verification.';
}
}else{
//same email
echo 'The email you entered is the same as your current email.';
}
}
This is the default code in edit-profile.php that handles the email change. Could I add a redirect here somewhere after email change. Is that a good idea?
// Execute confirmed email change. See send_confirmation_on_profile_email().
if ( IS_PROFILE_PAGE && isset( $_GET['newuseremail'] ) && $current_user->ID ) {
$new_email = get_user_meta( $current_user->ID, '_new_email', true );
if ( $new_email && hash_equals( $new_email['hash'], $_GET['newuseremail'] ) ) {
$user = new stdClass;
$user->ID = $current_user->ID;
$user->user_email = esc_html( trim( $new_email['newemail'] ) );
if ( is_multisite() && $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM {$wpdb->signups} WHERE user_login = %s", $current_user->user_login ) ) ) {
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->signups} SET user_email = %s WHERE user_login = %s", $user->user_email, $current_user->user_login ) );
}
wp_update_user( $user );
delete_user_meta( $current_user->ID, '_new_email' );
wp_redirect( add_query_arg( array( 'updated' => 'true' ), self_admin_url( 'profile.php' ) ) );
die();
} else {
wp_redirect( add_query_arg( array( 'error' => 'new-email' ), self_admin_url( 'profile.php' ) ) );
}
} elseif ( IS_PROFILE_PAGE && ! empty( $_GET['dismiss'] ) && $current_user->ID . '_new_email' === $_GET['dismiss'] ) {
check_admin_referer( 'dismiss-' . $current_user->ID . '_new_email' );
delete_user_meta( $current_user->ID, '_new_email' );
wp_redirect( add_query_arg( array( 'updated' => 'true' ), self_admin_url( 'profile.php' ) ) );
die();
}
I set up a front end form for logged in users to update their email address. So far it is working however I want the user, after confirming the email change via link sent to the new address, to be redirected to a custom front-end page.(after the change done in /wp-admin/edit-profile.php).
Thus the user never seeing the backend user profile page.
Here is the code for the form
<form action="<?php the_permalink(); ?>" method="post">
<div class="form-group">
<label for="e-mail">E-mail</label>
<input type="email" class="form-control" value="<?php echo esc_html($current_user->user_email); ?>" name="email" id="email">
<small class="form-text text-muted">If you change this we will send you an email at your new address to confirm it. <strong>The new address will not become active until confirmed.</strong></small>
</div>
<button class="btn btn-primary" type="submit">Change E-mail</button>
</form>
and the form processing
if (isset( $_POST['email'])) {
// check if user is really updating the value
if ($user_email != $_POST['email']) {
// check if email is free to use
if (email_exists( $_POST['email'] )){
// email already taken
echo 'That e-mail address is not available.';
exit();
} else {
$_POST['user_id'] = $current_user->ID;
send_confirmation_on_profile_email();
echo 'User update email ink sent to new email for verification.';
}
}else{
//same email
echo 'The email you entered is the same as your current email.';
}
}
This is the default code in edit-profile.php that handles the email change. Could I add a redirect here somewhere after email change. Is that a good idea?
// Execute confirmed email change. See send_confirmation_on_profile_email().
if ( IS_PROFILE_PAGE && isset( $_GET['newuseremail'] ) && $current_user->ID ) {
$new_email = get_user_meta( $current_user->ID, '_new_email', true );
if ( $new_email && hash_equals( $new_email['hash'], $_GET['newuseremail'] ) ) {
$user = new stdClass;
$user->ID = $current_user->ID;
$user->user_email = esc_html( trim( $new_email['newemail'] ) );
if ( is_multisite() && $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM {$wpdb->signups} WHERE user_login = %s", $current_user->user_login ) ) ) {
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->signups} SET user_email = %s WHERE user_login = %s", $user->user_email, $current_user->user_login ) );
}
wp_update_user( $user );
delete_user_meta( $current_user->ID, '_new_email' );
wp_redirect( add_query_arg( array( 'updated' => 'true' ), self_admin_url( 'profile.php' ) ) );
die();
} else {
wp_redirect( add_query_arg( array( 'error' => 'new-email' ), self_admin_url( 'profile.php' ) ) );
}
} elseif ( IS_PROFILE_PAGE && ! empty( $_GET['dismiss'] ) && $current_user->ID . '_new_email' === $_GET['dismiss'] ) {
check_admin_referer( 'dismiss-' . $current_user->ID . '_new_email' );
delete_user_meta( $current_user->ID, '_new_email' );
wp_redirect( add_query_arg( array( 'updated' => 'true' ), self_admin_url( 'profile.php' ) ) );
die();
}
- eg. if I add something like this wp_redirect(esc_url(site_url('/profile'))) in wp-adin/edit-user.php is that safe and will it be deleted with future updates of wordpress core files? – user176147 Commented Dec 14, 2019 at 17:08
1 Answer
Reset to default 0You need to do the processing of the form before headers are sent downstream. Otherwise, if you do it while the body is loading (the way you have it now), then redirecting after a successful email change will result in an error.
A lot of people would use the init
action for this; but personally, I like to use template_redirect
to hook form processing to. It comes a little later and then the $post
object is loaded if you need any data from that.
Here's how I would approach it:
add_action( 'template_redirect', 'my_user_email_update' );
function my_user_email_update() {
global $error;
$error = false;
if ( is_user_logged_in() && isset( $_POST['email'] ) ) {
// ALWAYS sanitize untrusted input!
$new_email = sanitize_email( $_POST['email'] );
// Get the user info for validating that the email is changing
$user = wp_get_current_user();
// check if user is really updating the value
if ( $user->user_email != $new_email ) {
// Is the new email actually an email address?
if ( ! is_email( $new_email ) ) {
$error = 'Please input a valid email address.';
}
// check if email is free to use
if ( email_exists( $new_email ) ) {
// email already taken
$error = 'That e-mail address is not available.';
} else {
$_POST['user_id'] = $current_user->ID; // This doesn't make sense.
$success = wp_update_user( array( 'ID'=>$user->ID, 'user_email'=>$new_email ) );
send_confirmation_on_profile_email();
// You could redirect here and pass a query string to indicate successful update
}
} else {
//same email
$error = 'The email you entered is the same as your current email.';
}
}
}
Some things to note:
- ALWAYS sanitize input. Instead of retrieving
$_POST['email']
each time, put it in a variable and sanitize it. Then use the sanitized result in the variable throughout. - You validate with
email_exists()
which is good. You should also validate that the posted value is actually a valid email withis_email()
. - I'm not sure what the
$_POST['user_id'] = $current_user->ID
is for. Neither of these make sense, so I'm not sure what was intended in that line. - As I mentioned, if you want to redirect, you need to do this before headers are sent, as I have in this example. I operated under the assumption that if there is any type of error, you won't redirect but rather display the error message on the existing form. So there is a
global $error
and any error result loads into that variable. I initialized it asfalse
so you can check it in the area of your form and if it's not false, display the result.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744903476a4600115.html
评论列表(0条)