[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-settings/actions/ -> general.php (source)

   1  <?php
   2  /**
   3   * Settings: Email address and password action handler.
   4   *
   5   * @package BuddyPress
   6   * @subpackage SettingsActions
   7   * @since 3.0.0
   8   */
   9  
  10  /**
  11   * Handles the changing and saving of user email addresses and passwords.
  12   *
  13   * We do quite a bit of logic and error handling here to make sure that users
  14   * do not accidentally lock themselves out of their accounts. We also try to
  15   * provide as accurate of feedback as possible without exposing anyone else's
  16   * information to them.
  17   *
  18   * Special considerations are made for super admins that are able to edit any
  19   * users accounts already, without knowing their existing password.
  20   *
  21   * @since 1.6.0
  22   *
  23   * @global BuddyPress $bp
  24   */
  25  function bp_settings_action_general() {
  26      if ( ! bp_is_post_request() ) {
  27          return;
  28      }
  29  
  30      // Bail if no submit action.
  31      if ( ! isset( $_POST['submit'] ) ) {
  32          return;
  33      }
  34  
  35      // Bail if not in settings.
  36      if ( ! bp_is_settings_component() || ! bp_is_current_action( 'general' ) ) {
  37          return;
  38      }
  39  
  40      // 404 if there are any additional action variables attached
  41      if ( bp_action_variables() ) {
  42          bp_do_404();
  43          return;
  44      }
  45  
  46      // Define local defaults
  47      $bp            = buddypress(); // The instance
  48      $email_error   = false;        // invalid|blocked|taken|empty|nochange
  49      $pass_error    = false;        // invalid|mismatch|empty|nochange
  50      $pass_changed  = false;        // true if the user changes their password
  51      $email_changed = false;        // true if the user changes their email
  52      $feedback_type = 'error';      // success|error
  53      $feedback      = array();      // array of strings for feedback.
  54  
  55      // Nonce check.
  56      check_admin_referer('bp_settings_general');
  57  
  58      // Validate the user again for the current password when making a big change.
  59      if ( ( is_super_admin() ) || ( !empty( $_POST['pwd'] ) && wp_check_password( $_POST['pwd'], $bp->displayed_user->userdata->user_pass, bp_displayed_user_id() ) ) ) {
  60  
  61          $update_user = array(
  62              'ID' => (int) bp_displayed_user_id(),
  63          );
  64  
  65          /* Email Change Attempt ******************************************/
  66  
  67          if ( ! empty( $_POST['email'] ) ) {
  68  
  69              // What is missing from the profile page vs signup -
  70              // let's double check the goodies.
  71              $user_email     = sanitize_email( esc_html( trim( $_POST['email'] ) ) );
  72              $old_user_email = $bp->displayed_user->userdata->user_email;
  73  
  74              // User is changing email address.
  75              if ( $old_user_email !== $user_email ) {
  76                  // Run some tests on the email address.
  77                  $email_checks = bp_core_validate_email_address( $user_email );
  78  
  79                  if ( true !== $email_checks ) {
  80                      if ( isset( $email_checks['invalid'] ) ) {
  81                          $email_error = 'invalid';
  82                      }
  83  
  84                      if ( isset( $email_checks['domain_banned'] ) || isset( $email_checks['domain_not_allowed'] ) ) {
  85                          $email_error = 'blocked';
  86                      }
  87  
  88                      if ( isset( $email_checks['in_use'] ) ) {
  89                          $email_error = 'taken';
  90                      }
  91                  }
  92  
  93                  // Store a hash to enable email validation.
  94                  if ( false === $email_error ) {
  95                      $hash = wp_generate_password( 32, false );
  96  
  97                      $pending_email = array(
  98                          'hash'     => $hash,
  99                          'newemail' => $user_email,
 100                      );
 101  
 102                      bp_update_user_meta( bp_displayed_user_id(), 'pending_email_change', $pending_email );
 103                      $verify_link = bp_displayed_user_domain() . bp_get_settings_slug() . '/?verify_email_change=' . $hash;
 104  
 105                      // Send the verification email.
 106                      $args = array(
 107                          'tokens' => array(
 108                              'displayname'    => bp_core_get_user_displayname( bp_displayed_user_id() ),
 109                              'old-user.email' => $old_user_email,
 110                              'user.email'     => $user_email,
 111                              'verify.url'     => esc_url( $verify_link ),
 112                          ),
 113                      );
 114                      bp_send_email( 'settings-verify-email-change', $user_email, $args );
 115  
 116                      // We mark that the change has taken place so as to ensure a
 117                      // success message, even though verification is still required.
 118                      $email_changed = true;
 119                  }
 120  
 121              // No change.
 122              } else {
 123                  $email_error = false;
 124              }
 125  
 126          // Email address cannot be empty.
 127          } else {
 128              $email_error = 'empty';
 129          }
 130  
 131          /* Password Change Attempt ***************************************/
 132  
 133          if ( ! empty( $_POST['pass1'] ) && ! empty( $_POST['pass2'] ) ) {
 134              $pass         = wp_unslash( $_POST['pass1'] );
 135              $pass_confirm = wp_unslash( $_POST['pass2'] );
 136  
 137              // Password strength check.
 138              $required_password_strength = bp_members_user_pass_required_strength();
 139              $current_password_strength  = null;
 140              if ( isset( $_POST['_password_strength_score'] ) ) {
 141                  $current_password_strength = (int) $_POST['_password_strength_score'];
 142              }
 143  
 144              if ( $required_password_strength && ! is_null( $current_password_strength ) && $required_password_strength > $current_password_strength ) {
 145                  $pass_error = new WP_Error(
 146                      'not_strong_enough_password',
 147                      __( 'Your password is not strong enough to be allowed on this site. Please use a stronger password.', 'buddypress' )
 148                  );
 149              } else {
 150                  $pass_error = bp_members_validate_user_password( $pass, $pass_confirm, $update_user );
 151  
 152                  if ( ! $pass_error->get_error_message() ) {
 153                      // Password change attempt is successful.
 154                      if ( ( ! empty( $_POST['pwd'] ) && wp_unslash( $_POST['pwd'] ) !== $pass ) || is_super_admin() )  {
 155                          $update_user['user_pass'] = $_POST['pass1'];
 156                          $pass_error               = false;
 157                          $pass_changed             = true;
 158  
 159                      // The new password is the same as the current password.
 160                      } else {
 161                          $pass_error->add( 'same_user_password', __( 'The new password must be different from the current password.', 'buddypress' ) );
 162                      }
 163                  }
 164              }
 165  
 166          // Both password fields were empty.
 167          } elseif ( empty( $_POST['pass1'] ) && empty( $_POST['pass2'] ) ) {
 168              $pass_error = false;
 169  
 170          // One of the password boxes was left empty.
 171          } elseif ( ( empty( $_POST['pass1'] ) && ! empty( $_POST['pass2'] ) ) || ( ! empty( $_POST['pass1'] ) && empty( $_POST['pass2'] ) ) ) {
 172              $pass_error = new WP_Error( 'empty_user_password', __( 'One of the password fields was empty.', 'buddypress' ) );
 173          }
 174  
 175          // Unset the password field to prevent it from emptying out the
 176          // user's user_pass field in the database.
 177          if ( false === $pass_changed ) {
 178              unset( $update_user['user_pass'] );
 179          }
 180  
 181          // Clear cached data, so that the changed settings take effect
 182          // on the current page load.
 183          if ( ( false === $email_error ) && ( false === $pass_error ) && ( wp_update_user( $update_user ) ) ) {
 184              $bp->displayed_user->userdata = bp_core_get_core_userdata( bp_displayed_user_id() );
 185          }
 186  
 187      // Password Error.
 188      } else {
 189          $pass_error = new WP_Error( 'invalid_user_password', __( 'Your current password is invalid.', 'buddypress' ) );
 190      }
 191  
 192      // Email feedback.
 193      switch ( $email_error ) {
 194          case 'invalid' :
 195              $feedback['email_invalid']  = __( 'That email address is invalid. Check the formatting and try again.', 'buddypress' );
 196              break;
 197          case 'blocked' :
 198              $feedback['email_blocked']  = __( 'That email address is currently unavailable for use.', 'buddypress' );
 199              break;
 200          case 'taken' :
 201              $feedback['email_taken']    = __( 'That email address is already taken.', 'buddypress' );
 202              break;
 203          case 'empty' :
 204              $feedback['email_empty']    = __( 'Email address cannot be empty.', 'buddypress' );
 205              break;
 206          case false :
 207              // No change.
 208              break;
 209      }
 210  
 211      if ( is_wp_error( $pass_error ) && $pass_error->get_error_message() ) {
 212          $feedback[ $pass_error->get_error_code() ] = $pass_error->get_error_message();
 213      }
 214  
 215      // No errors so show a simple success message.
 216      if ( ( ( false === $email_error ) || ( false == $pass_error ) ) && ( ( true === $pass_changed ) || ( true === $email_changed ) ) ) {
 217          $feedback[]    = __( 'Your settings have been saved.', 'buddypress' );
 218          $feedback_type = 'success';
 219  
 220      // Some kind of errors occurred.
 221      } elseif ( ( ( false === $email_error ) || ( false === $pass_error ) ) && ( ( false === $pass_changed ) || ( false === $email_changed ) ) ) {
 222          if ( bp_is_my_profile() ) {
 223              $feedback['nochange'] = __( 'No changes were made to your account.', 'buddypress' );
 224          } else {
 225              $feedback['nochange'] = __( 'No changes were made to this account.', 'buddypress' );
 226          }
 227      }
 228  
 229      // Set the feedback.
 230      bp_core_add_message( implode( "\n", $feedback ), $feedback_type );
 231  
 232      /**
 233       * Fires after the general settings have been saved, and before redirect.
 234       *
 235       * @since 1.5.0
 236       */
 237      do_action( 'bp_core_general_settings_after_save' );
 238  
 239      // Redirect to prevent issues with browser back button.
 240      bp_core_redirect( trailingslashit( bp_displayed_user_domain() . bp_get_settings_slug() . '/general' ) );
 241  }
 242  add_action( 'bp_actions', 'bp_settings_action_general' );
 243  
 244  /**
 245   * Process email change verification or cancel requests.
 246   *
 247   * @since 2.1.0
 248   */
 249  function bp_settings_verify_email_change() {
 250      if ( ! bp_is_settings_component() ) {
 251          return;
 252      }
 253  
 254      if ( ! bp_is_my_profile() ) {
 255          return;
 256      }
 257  
 258      $redirect_to = trailingslashit( bp_displayed_user_domain() . bp_get_settings_slug() );
 259  
 260      // Email change is being verified.
 261      if ( isset( $_GET['verify_email_change'] ) ) {
 262          $user_id       = bp_displayed_user_id();
 263          $pending_email = (array) bp_get_user_meta( $user_id, 'pending_email_change', true );
 264  
 265          // The user may have dismissed the email change.
 266          if ( ! array_filter( $pending_email ) ) {
 267              /**
 268               * Fires when a Pending Email Change is missing and before
 269               * BuddyPress redirects the user to an error message.
 270               *
 271               * @since 9.1.0
 272               *
 273               * @param int    $user_id     The user ID.
 274               * @param string $redirect_to The Default Front-end Settings Screen URL.
 275               */
 276              do_action( 'bp_settings_missing_pending_email_change_hash', $user_id, $redirect_to );
 277  
 278              bp_core_add_message( __( 'There was a problem verifying your new email address. If you haven’t dismissed the pending email change, please request a new email update.', 'buddypress' ), 'error' );
 279              bp_core_redirect( $redirect_to );
 280          }
 281  
 282          // Bail if the hash provided doesn't match the one saved in the database.
 283          if ( ! hash_equals( urldecode( $_GET['verify_email_change'] ), $pending_email['hash'] ) ) {
 284              return;
 285          }
 286  
 287          $email_changed = wp_update_user( array(
 288              'ID'         => $user_id,
 289              'user_email' => trim( $pending_email['newemail'] ),
 290          ) );
 291  
 292          if ( $email_changed ) {
 293              // Delete the pending email change key.
 294              bp_delete_user_meta( $user_id, 'pending_email_change' );
 295  
 296              /**
 297               * Fires when a Pending Email Change has been validated and before
 298               * BuddyPress redirects the user to a success message.
 299               *
 300               * @since 9.1.0
 301               *
 302               * @param int    $user_id     The user ID.
 303               * @param string $redirect_to The Default Front-end Settings Screen URL.
 304               */
 305              do_action( 'bp_settings_email_changed', $user_id, $redirect_to );
 306  
 307              // Post a success message and redirect.
 308              bp_core_add_message( __( 'You have successfully verified your new email address.', 'buddypress' ) );
 309          } else {
 310              // Unknown error.
 311              bp_core_add_message( __( 'There was a problem verifying your new email address. Please try again.', 'buddypress' ), 'error' );
 312          }
 313  
 314          bp_core_redirect( $redirect_to );
 315  
 316      // Email change is being dismissed.
 317      } elseif ( ! empty( $_GET['dismiss_email_change'] ) ) {
 318          $nonce_check = isset( $_GET['_wpnonce'] ) && wp_verify_nonce( wp_unslash( $_GET['_wpnonce'] ), 'bp_dismiss_email_change' );
 319  
 320          if ( $nonce_check ) {
 321              $user_id = bp_displayed_user_id();
 322              bp_delete_user_meta( $user_id, 'pending_email_change' );
 323  
 324              /**
 325               * Fires when a Pending Email Change has been dismissed and before
 326               * BuddyPress redirects the user to a success message.
 327               *
 328               * @since 9.1.0
 329               *
 330               * @param int    $user_id     The user ID.
 331               * @param string $redirect_to The Default Front-end Settings Screen URL.
 332               */
 333              do_action( 'bp_settings_email_change_dismissed', $user_id, $redirect_to );
 334  
 335              bp_core_add_message( __( 'You have successfully dismissed your pending email change.', 'buddypress' ) );
 336          }
 337  
 338          bp_core_redirect( $redirect_to );
 339      }
 340  }
 341  add_action( 'bp_actions', 'bp_settings_verify_email_change' );


Generated: Tue Mar 19 01:01:09 2024 Cross-referenced by PHPXref 0.7.1