[ 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  
  77                  // Run some tests on the email address.
  78                  $email_checks = bp_core_validate_email_address( $user_email );
  79  
  80                  if ( true !== $email_checks ) {
  81                      if ( isset( $email_checks['invalid'] ) ) {
  82                          $email_error = 'invalid';
  83                      }
  84  
  85                      if ( isset( $email_checks['domain_banned'] ) || isset( $email_checks['domain_not_allowed'] ) ) {
  86                          $email_error = 'blocked';
  87                      }
  88  
  89                      if ( isset( $email_checks['in_use'] ) ) {
  90                          $email_error = 'taken';
  91                      }
  92                  }
  93  
  94                  // Store a hash to enable email validation.
  95                  if ( false === $email_error ) {
  96                      $hash = wp_generate_password( 32, false );
  97  
  98                      $pending_email = array(
  99                          'hash'     => $hash,
 100                          'newemail' => $user_email,
 101                      );
 102  
 103                      bp_update_user_meta( bp_displayed_user_id(), 'pending_email_change', $pending_email );
 104                      $verify_link = bp_displayed_user_domain() . bp_get_settings_slug() . '/?verify_email_change=' . $hash;
 105  
 106                      // Send the verification email.
 107                      $args = array(
 108                          'tokens' => array(
 109                              'displayname'    => bp_core_get_user_displayname( bp_displayed_user_id() ),
 110                              'old-user.email' => $old_user_email,
 111                              'user.email'     => $user_email,
 112                              'verify.url'     => esc_url( $verify_link ),
 113                          ),
 114                      );
 115                      bp_send_email( 'settings-verify-email-change', $user_email, $args );
 116  
 117                      // We mark that the change has taken place so as to ensure a
 118                      // success message, even though verification is still required.
 119                      $email_changed = true;
 120                  }
 121  
 122              // No change.
 123              } else {
 124                  $email_error = false;
 125              }
 126  
 127          // Email address cannot be empty.
 128          } else {
 129              $email_error = 'empty';
 130          }
 131  
 132          /* Password Change Attempt ***************************************/
 133  
 134          if ( ! empty( $_POST['pass1'] ) && ! empty( $_POST['pass2'] ) ) {
 135              $pass         = wp_unslash( $_POST['pass1'] );
 136              $pass_confirm = wp_unslash( $_POST['pass2'] );
 137              $pass_error   = bp_members_validate_user_password( $pass, $pass_confirm, $update_user );
 138  
 139              if ( ! $pass_error->get_error_message() ) {
 140                  // Password change attempt is successful.
 141                  if ( ( ! empty( $_POST['pwd'] ) && wp_unslash( $_POST['pwd'] ) !== $pass ) || is_super_admin() )  {
 142                      $update_user['user_pass'] = $_POST['pass1'];
 143                      $pass_error               = false;
 144                      $pass_changed             = true;
 145  
 146                  // The new password is the same as the current password.
 147                  } else {
 148                      $pass_error->add( 'same_user_password', __( 'The new password must be different from the current password.', 'buddypress' ) );
 149                  }
 150              }
 151  
 152          // Both password fields were empty.
 153          } elseif ( empty( $_POST['pass1'] ) && empty( $_POST['pass2'] ) ) {
 154              $pass_error = false;
 155  
 156          // One of the password boxes was left empty.
 157          } elseif ( ( empty( $_POST['pass1'] ) && ! empty( $_POST['pass2'] ) ) || ( ! empty( $_POST['pass1'] ) && empty( $_POST['pass2'] ) ) ) {
 158              $pass_error = new WP_Error( 'empty_user_password', __( 'One of the password fields was empty.', 'buddypress' ) );
 159          }
 160  
 161          // Unset the password field to prevent it from emptying out the
 162          // user's user_pass field in the database.
 163          if ( false === $pass_changed ) {
 164              unset( $update_user['user_pass'] );
 165          }
 166  
 167          // Clear cached data, so that the changed settings take effect
 168          // on the current page load.
 169          if ( ( false === $email_error ) && ( false === $pass_error ) && ( wp_update_user( $update_user ) ) ) {
 170              $bp->displayed_user->userdata = bp_core_get_core_userdata( bp_displayed_user_id() );
 171          }
 172  
 173      // Password Error.
 174      } else {
 175          $pass_error = new WP_Error( 'invalid_user_password', __( 'Your current password is invalid.', 'buddypress' ) );
 176      }
 177  
 178      // Email feedback.
 179      switch ( $email_error ) {
 180          case 'invalid' :
 181              $feedback['email_invalid']  = __( 'That email address is invalid. Check the formatting and try again.', 'buddypress' );
 182              break;
 183          case 'blocked' :
 184              $feedback['email_blocked']  = __( 'That email address is currently unavailable for use.', 'buddypress' );
 185              break;
 186          case 'taken' :
 187              $feedback['email_taken']    = __( 'That email address is already taken.', 'buddypress' );
 188              break;
 189          case 'empty' :
 190              $feedback['email_empty']    = __( 'Email address cannot be empty.', 'buddypress' );
 191              break;
 192          case false :
 193              // No change.
 194              break;
 195      }
 196  
 197      if ( is_wp_error( $pass_error ) && $pass_error->get_error_message() ) {
 198          $feedback[ $pass_error->get_error_code() ] = $pass_error->get_error_message();
 199      }
 200  
 201      // No errors so show a simple success message.
 202      if ( ( ( false === $email_error ) || ( false == $pass_error ) ) && ( ( true === $pass_changed ) || ( true === $email_changed ) ) ) {
 203          $feedback[]    = __( 'Your settings have been saved.', 'buddypress' );
 204          $feedback_type = 'success';
 205  
 206      // Some kind of errors occurred.
 207      } elseif ( ( ( false === $email_error ) || ( false === $pass_error ) ) && ( ( false === $pass_changed ) || ( false === $email_changed ) ) ) {
 208          if ( bp_is_my_profile() ) {
 209              $feedback['nochange'] = __( 'No changes were made to your account.', 'buddypress' );
 210          } else {
 211              $feedback['nochange'] = __( 'No changes were made to this account.', 'buddypress' );
 212          }
 213      }
 214  
 215      // Set the feedback.
 216      bp_core_add_message( implode( "\n", $feedback ), $feedback_type );
 217  
 218      /**
 219       * Fires after the general settings have been saved, and before redirect.
 220       *
 221       * @since 1.5.0
 222       */
 223      do_action( 'bp_core_general_settings_after_save' );
 224  
 225      // Redirect to prevent issues with browser back button.
 226      bp_core_redirect( trailingslashit( bp_displayed_user_domain() . bp_get_settings_slug() . '/general' ) );
 227  }
 228  add_action( 'bp_actions', 'bp_settings_action_general' );
 229  
 230  /**
 231   * Process email change verification or cancel requests.
 232   *
 233   * @since 2.1.0
 234   */
 235  function bp_settings_verify_email_change() {
 236      if ( ! bp_is_settings_component() ) {
 237          return;
 238      }
 239  
 240      if ( ! bp_is_my_profile() ) {
 241          return;
 242      }
 243  
 244      $redirect_to = trailingslashit( bp_displayed_user_domain() . bp_get_settings_slug() );
 245  
 246      // Email change is being verified.
 247      if ( isset( $_GET['verify_email_change'] ) ) {
 248          $user_id       = bp_displayed_user_id();
 249          $pending_email = (array) bp_get_user_meta( $user_id, 'pending_email_change', true );
 250  
 251          // The user may have dismissed the email change.
 252          if ( ! array_filter( $pending_email ) ) {
 253              /**
 254               * Fires when a Pending Email Change is missing and before
 255               * BuddyPress redirects the user to an error message.
 256               *
 257               * @since 9.1.0
 258               *
 259               * @param int    $user_id     The user ID.
 260               * @param string $redirect_to The Default Front-end Settings Screen URL.
 261               */
 262              do_action( 'bp_settings_missing_pending_email_change_hash', $user_id, $redirect_to );
 263  
 264              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' );
 265              bp_core_redirect( $redirect_to );
 266          }
 267  
 268          // Bail if the hash provided doesn't match the one saved in the database.
 269          if ( ! hash_equals( urldecode( $_GET['verify_email_change'] ), $pending_email['hash'] ) ) {
 270              return;
 271          }
 272  
 273          $email_changed = wp_update_user( array(
 274              'ID'         => $user_id,
 275              'user_email' => trim( $pending_email['newemail'] ),
 276          ) );
 277  
 278          if ( $email_changed ) {
 279              // Delete the pending email change key.
 280              bp_delete_user_meta( $user_id, 'pending_email_change' );
 281  
 282              /**
 283               * Fires when a Pending Email Change has been validated and before
 284               * BuddyPress redirects the user to a success message.
 285               *
 286               * @since 9.1.0
 287               *
 288               * @param int    $user_id     The user ID.
 289               * @param string $redirect_to The Default Front-end Settings Screen URL.
 290               */
 291              do_action( 'bp_settings_email_changed', $user_id, $redirect_to );
 292  
 293              // Post a success message and redirect.
 294              bp_core_add_message( __( 'You have successfully verified your new email address.', 'buddypress' ) );
 295          } else {
 296              // Unknown error.
 297              bp_core_add_message( __( 'There was a problem verifying your new email address. Please try again.', 'buddypress' ), 'error' );
 298          }
 299  
 300          bp_core_redirect( $redirect_to );
 301  
 302      // Email change is being dismissed.
 303      } elseif ( ! empty( $_GET['dismiss_email_change'] ) ) {
 304          $nonce_check = isset( $_GET['_wpnonce'] ) && wp_verify_nonce( wp_unslash( $_GET['_wpnonce'] ), 'bp_dismiss_email_change' );
 305  
 306          if ( $nonce_check ) {
 307              $user_id = bp_displayed_user_id();
 308              bp_delete_user_meta( $user_id, 'pending_email_change' );
 309  
 310              /**
 311               * Fires when a Pending Email Change has been dismissed and before
 312               * BuddyPress redirects the user to a success message.
 313               *
 314               * @since 9.1.0
 315               *
 316               * @param int    $user_id     The user ID.
 317               * @param string $redirect_to The Default Front-end Settings Screen URL.
 318               */
 319              do_action( 'bp_settings_email_change_dismissed', $user_id, $redirect_to );
 320  
 321              bp_core_add_message( __( 'You have successfully dismissed your pending email change.', 'buddypress' ) );
 322          }
 323  
 324          bp_core_redirect( $redirect_to );
 325      }
 326  }
 327  add_action( 'bp_actions', 'bp_settings_verify_email_change' );


Generated: Tue Sep 21 01:01:37 2021 Cross-referenced by PHPXref 0.7.1