Skip to:
Content

bbPress.org

Changeset 5663


Ignore:
Timestamp:
03/25/2015 06:47:21 PM (9 years ago)
Author:
johnjamesjacoby
Message:

Users: Email address change improvements:

  • Introduce function for handling sending notification email
  • Clean up code required to update, save, confirm, & dismiss pending email address changes
  • Fixes bug in previous implementation making it impossible to interact with pending email address changes on multisite installations

Fixes #2780.

Location:
trunk/src/includes
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/includes/core/actions.php

    r5662 r5663  
    332332add_action( 'bbp_get_request', 'bbp_favorites_handler',           1  );
    333333add_action( 'bbp_get_request', 'bbp_subscriptions_handler',       1  );
    334 add_action( 'bbp_get_request', 'bbp_user_email_handler',          1  );
     334add_action( 'bbp_get_request', 'bbp_user_email_change_handler',   1  );
    335335add_action( 'bbp_get_request', 'bbp_forum_subscriptions_handler', 1  );
    336336add_action( 'bbp_get_request', 'bbp_search_results_redirect',     10 );
  • trunk/src/includes/users/functions.php

    r5662 r5663  
    12021202 * Handles the front end subscribing and unsubscribing topics
    12031203 *
     1204 * @since bbPress (r2790)
     1205 *
    12041206 * @param string $action The requested action to compare this function to
    12051207 * @uses bbp_is_subscriptions_active() To check if the subscriptions are active
     
    13061308/**
    13071309 * Handles the front end user editing from POST requests
     1310 *
     1311 * @since bbPress (r2790)
    13081312 *
    13091313 * @param string $action The requested action to compare this function to
     
    13551359    }
    13561360
     1361    // Empty email check
     1362    if ( empty( $_POST['email'] ) ) {
     1363        bbp_add_error( 'bbp_user_email_empty', __( '<strong>ERROR</strong>: That is not a valid email address.' ), array( 'form-field' => 'email' ) );
     1364        return;
     1365    }
     1366
     1367    // Get the users current email address to use for comparisons
     1368    $user_email = bbp_get_displayed_user_field( 'user_email', 'raw' );
     1369
     1370    // Bail if no email change
     1371    if ( $user_email !== $_POST['email'] ) {
     1372
     1373        // Check that new email address is valid
     1374        if ( ! is_email( $_POST['email'] ) ) {
     1375            bbp_add_error( 'bbp_user_email_invalid', __( '<strong>ERROR</strong>: That is not a valid email address.' ), array( 'form-field' => 'email' ) );
     1376            return;
     1377        }
     1378
     1379        // Check if email address is already in use
     1380        if ( email_exists( $_POST['email'] ) ) {
     1381            bbp_add_error( 'bbp_user_email_taken', __( '<strong>ERROR</strong>: That email address is already in use.' ), array( 'form-field' => 'email' ) );
     1382            return;
     1383        }
     1384
     1385        // Update the option
     1386        $key    = $user_id . '_new_email';
     1387        $hash   = md5( $_POST['email'] . time() . mt_rand() );
     1388        $option = array(
     1389            'hash'     => $hash,
     1390            'newemail' => $_POST['email']
     1391        );
     1392        update_option( $key, $option );
     1393
     1394        // Attempt to notify the user of email address change
     1395        bbp_edit_user_email_send_notification( $user_id, $option );
     1396
     1397        // Set the POST email variable back to the user's email address
     1398        // so `edit_user()` does not attempt to update it. This is not ideal,
     1399        // but it's also what send_confirmation_on_profile_email() does.
     1400        $_POST['email'] = $user_email;
     1401    }
     1402
    13571403    // Do action based on who's profile you're editing
    13581404    $edit_action = bbp_is_user_home_edit()
     
    13651411    if ( ! isset( $_POST['admin_bar_front'] ) && _get_admin_bar_pref( 'front', $user_id ) ) {
    13661412        $_POST['admin_bar_front'] = 1;
     1413    }
     1414
     1415    // Bail if errors already exist
     1416    if ( bbp_has_errors() ) {
     1417        return;
    13671418    }
    13681419
     
    14001451 * @global object $wpdb
    14011452 * @param  string $action
    1402  */
    1403 function bbp_user_email_handler( $action = '' ) {
     1453 *
     1454 * @uses bbp_is_user_home_edit()         To check if on the current users profile edit page
     1455 * @uses bbp_get_displayed_user_id()     To get the ID of the user being edited
     1456 * @uses bbp_get_user_profile_edit_url() To get the URL of the user being edited
     1457 * @uses bbp_redirect()                  To redirect away from the current page
     1458 * @uses hash_equals()                   To compare email hash to saved option hash
     1459 * @uses email_exists()                  To check if user has email address already
     1460 * @uses bbp_add_error()                 To add user feedback
     1461 * @uses wp_update_user()                To update the user with their new email address
     1462 * @uses bbp_verify_nonce_request()      To verify the intent of the user
     1463 */
     1464function bbp_user_email_change_handler( $action = '' ) {
    14041465
    14051466    // Bail if action is not `bbp-update-user-email`
     
    14191480
    14201481    // Get the displayed user ID & option key
    1421     $user_id = bbp_get_displayed_user_id();
    1422     $key     = $user_id . '_new_email';
     1482    $user_id     = bbp_get_displayed_user_id();
     1483    $key         = $user_id . '_new_email';
     1484    $redirect_to = bbp_get_user_profile_edit_url( $user_id );
    14231485
    14241486    // Execute confirmed email change.
     
    14261488
    14271489        // Check for email address change option
    1428         $new_email = get_option( $key, array() );
     1490        $new_email = get_option( $key );
    14291491
    14301492        // Redirect if *no* email address change exists
    1431         if ( empty( $new_email ) ) {
    1432             bbp_redirect( bbp_get_user_profile_edit_url( $user_id ) );
     1493        if ( false === $new_email ) {
     1494            bbp_redirect( $redirect_to );
    14331495        }
    14341496
     
    14371499            delete_option( $key );
    14381500
    1439             bbp_redirect( bbp_get_user_profile_edit_url( $user_id ) );
     1501            bbp_redirect( $redirect_to );
    14401502        }
    14411503
     
    14431505        if ( hash_equals( $new_email['hash'], $_GET['newuseremail'] ) ) {
    14441506
    1445             // Create a new user object, used for updating
    1446             $user             = new WP_User();
    1447             $user->ID         = $user_id;
    1448             $user->user_email = esc_html( trim( $new_email['newemail'] ) );
    1449 
    1450             global $wpdb;
    1451 
    1452             if ( $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM {$wpdb->signups} WHERE user_login = %s", bbp_get_displayed_user_field( 'user_login', 'raw' ) ) ) ) {
    1453                 $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->signups} SET user_email = %s WHERE user_login = %s", $user->user_email, bbp_get_displayed_user_field( 'user_login', 'raw' ) ) );
     1507            // Does another user have this email address already?
     1508            if ( email_exists( $new_email['newemail'] ) ) {
     1509                delete_option( $key );
     1510
     1511                bbp_add_error( 'bbp_user_email_taken', __( '<strong>ERROR</strong>: That email address is already in use.' ), array( 'form-field' => 'email' ) );
     1512
     1513            // Email address is good to change to
     1514            } else {
     1515
     1516                // Create a stdClass (for easy call to wp_update_user())
     1517                $user             = new stdClass();
     1518                $user->ID         = $user_id;
     1519                $user->user_email = esc_html( trim( $new_email['newemail'] ) );
     1520
     1521                // Attempt to update user email
     1522                $update_user = wp_update_user( $user );
     1523
     1524                // Error(s) editing the user, so copy them into the global
     1525                if ( is_wp_error( $update_user ) ) {
     1526                    bbpress()->errors = $update_user;
     1527
     1528                // All done, so redirect and show the updated message
     1529                } else {
     1530
     1531                    // Update signups table, if signups table & entry exists
     1532                    // For Multisite & BuddyPress compatibility
     1533                    global $wpdb;
     1534                    if ( ! empty( $wpdb->signups ) && $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM {$wpdb->signups} WHERE user_login = %s", bbp_get_displayed_user_field( 'user_login', 'raw' ) ) ) ) {
     1535                        $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->signups} SET user_email = %s WHERE user_login = %s", $user->user_email, bbp_get_displayed_user_field( 'user_login', 'raw' ) ) );
     1536                    }
     1537
     1538                    delete_option( $key );
     1539
     1540                    bbp_redirect( add_query_arg( array( 'updated' => 'true' ), $redirect_to ) );
     1541                }
    14541542            }
    1455 
    1456             wp_update_user( get_object_vars( $user ) );
    1457             delete_option( $key );
    1458 
    1459             bbp_redirect( add_query_arg( array( 'updated' => 'true' ), bbp_get_user_profile_edit_url( $user_id ) ) );
    14601543        }
    14611544
     
    14681551
    14691552        delete_option( $key );
    1470         bbp_redirect( bbp_get_user_profile_edit_url( $user_id ) );
    1471     }
     1553        bbp_redirect( $redirect_to );
     1554    }
     1555}
     1556
     1557/**
     1558 * Sends an email when an email address change occurs on POST requests
     1559 *
     1560 * @since bbPress (r5660)
     1561 *
     1562 * @see send_confirmation_on_profile_email()
     1563 *
     1564 * @uses bbp_parse_args()                To parse the option arguments
     1565 * @uses bbp_add_error()                 To provide feedback to user
     1566 * @uses bbp_get_displayed_user_field()  To get the user_login
     1567 * @uses bbp_get_user_profile_edit_url() To get the user profile edit link
     1568 * @uses add_query_arg()                 To add arguments the link
     1569 * @uses wp_mail()                       To send the notification
     1570 */
     1571function bbp_edit_user_email_send_notification( $user_id = 0, $args = '' ) {
     1572
     1573    // Parse args
     1574    $r = bbp_parse_args( $args, array(
     1575        'hash'     => '',
     1576        'newemail' => '',
     1577    ) );
     1578
     1579    // Bail if any relevant parameters are empty
     1580    if ( empty( $user_id ) || empty( $r['hash'] ) || empty( $r['newemail'] ) ) {
     1581        bbp_add_error( 'bbp_user_email_invalid_hash', __( '<strong>ERROR</strong>: An error occurred while updating your email address.' ), array( 'form-field' => 'email' ) );
     1582        return;
     1583    }
     1584
     1585    // Build the nonced URL to dismiss the pending change
     1586    $user_login  = bbp_get_displayed_user_field( 'user_login', 'raw' );
     1587    $user_url    = bbp_get_user_profile_edit_url( $user_id );
     1588    $confirm_url = add_query_arg( array(
     1589        'action'       => 'bbp-update-user-email',
     1590        'newuseremail' => $r['hash']
     1591    ), $user_url );
     1592
     1593    $email_text = __( '###USERNAME###,
     1594
     1595Someone requested a change to the email address on your account.
     1596
     1597Please click the following link to confirm this change:
     1598###PROFILE_URL###
     1599
     1600If you did not request this, you can safely ignore and delete this notification.
     1601
     1602This email was sent to: ###EMAIL###
     1603
     1604Regards,
     1605The ###SITENAME### Team
     1606###SITEURL###' );
     1607
     1608    /**
     1609     * Filter the email text sent when a user changes emails.
     1610     *
     1611     * The following strings have a special meaning and will get replaced dynamically:
     1612     *
     1613     * ###USERNAME###    The current user's username.
     1614     * ###PROFILE_URL### The link to click on to confirm the email change.
     1615     * ###EMAIL###       The new email.
     1616     * ###SITENAME###    The name of the site.
     1617     * ###SITEURL###     The URL to the site.
     1618     *
     1619     * @param string $email_text     Text in the email.
     1620     * @param string $new_user_email New user email that the current user has changed to.
     1621     */
     1622    $content = apply_filters( 'bbp_new_user_email_content', $email_text, $r );
     1623
     1624    // Replace a few strings
     1625    $content = str_replace( '###USERNAME###',    $user_login,    $content );
     1626    $content = str_replace( '###PROFILE_URL###', $confirm_url,   $content );
     1627    $content = str_replace( '###EMAIL###',       $r['newemail'], $content);
     1628    $content = str_replace( '###SITENAME###',    get_site_option( 'site_name' ), $content );
     1629    $content = str_replace( '###SITEURL###',     network_home_url(), $content );
     1630
     1631    // Build the email subject
     1632    $subject = sprintf( __( '[%s] New Email Address' ), wp_specialchars_decode( get_option( 'blogname' ) ) );
     1633
     1634    // Send the email
     1635    wp_mail( $r['newemail'], $subject, $content );
    14721636}
    14731637
Note: See TracChangeset for help on using the changeset viewer.