[ Index ]

PHP Cross Reference of BBPress

title

Body

[close]

/src/includes/users/ -> functions.php (source)

   1  <?php
   2  
   3  /**
   4   * bbPress User Functions
   5   *
   6   * @package bbPress
   7   * @subpackage Functions
   8   */
   9  
  10  // Exit if accessed directly
  11  defined( 'ABSPATH' ) || exit;
  12  
  13  /**
  14   * Redirect back to $url when attempting to use the login page
  15   *
  16   * @since 2.0.0 bbPress (r2815)
  17   *
  18   * @param string $url The url
  19   * @param string $raw_url Raw url
  20   * @param object $user User object
  21   */
  22  function bbp_redirect_login( $url = '', $raw_url = '', $user = '' ) {
  23  
  24      // Raw redirect_to was passed, so use it
  25      if ( ! empty( $raw_url ) ) {
  26          $url = $raw_url;
  27  
  28      // $url was manually set in wp-login.php to redirect to admin
  29      } elseif ( admin_url() === $url ) {
  30          $url = home_url();
  31  
  32      // $url is empty
  33      } elseif ( empty( $url ) ) {
  34          $url = home_url();
  35      }
  36  
  37      // Filter & return
  38      return apply_filters( 'bbp_redirect_login', $url, $raw_url, $user );
  39  }
  40  
  41  /**
  42   * Is an anonymous topic/reply being made?
  43   *
  44   * @since 2.0.0 bbPress (r2688)
  45   *
  46   * @return bool True if anonymous is allowed and user is not logged in, false if
  47   *               anonymous is not allowed or user is logged in
  48   */
  49  function bbp_is_anonymous() {
  50      $is_anonymous = ( ! is_user_logged_in() && bbp_allow_anonymous() );
  51  
  52      // Filter & return
  53      return (bool) apply_filters( 'bbp_is_anonymous', $is_anonymous );
  54  }
  55  
  56  /**
  57   * Echoes the values for current poster (uses WP comment cookies)
  58   *
  59   * @since 2.0.0 bbPress (r2734)
  60   *
  61   * @param string $key Which value to echo?
  62   */
  63  function bbp_current_anonymous_user_data( $key = '' ) {
  64      echo esc_attr( bbp_get_current_anonymous_user_data( $key ) );
  65  }
  66  
  67      /**
  68       * Get the cookies for current poster (uses WP comment cookies).
  69       *
  70       * @since 2.0.0 bbPress (r2734)
  71       *
  72       * @param string $key Optional. Which value to get? If not given, then
  73       *                     an array is returned.
  74       * @return string|array Cookie(s) for current poster
  75       */
  76  	function bbp_get_current_anonymous_user_data( $key = '' ) {
  77  
  78          // Array of allowed cookie names
  79          $cookie_names = array(
  80              'name'  => 'comment_author',
  81              'email' => 'comment_author_email',
  82              'url'   => 'comment_author_url',
  83  
  84              // Here just for the sake of them, use the above ones
  85              'comment_author'       => 'comment_author',
  86              'comment_author_email' => 'comment_author_email',
  87              'comment_author_url'   => 'comment_author_url',
  88          );
  89  
  90          // Get the current poster's info from the cookies
  91          $bbp_current_poster = wp_get_current_commenter();
  92  
  93          // Sanitize the cookie key being retrieved
  94          $key = sanitize_key( $key );
  95  
  96          // Maybe return a specific key
  97          if ( ! empty( $key ) && in_array( $key, array_keys( $cookie_names ), true ) ) {
  98              return $bbp_current_poster[ $cookie_names[ $key ] ];
  99          }
 100  
 101          // Return all keys
 102          return $bbp_current_poster;
 103      }
 104  
 105  /**
 106   * Set the cookies for current poster (uses WP comment cookies)
 107   *
 108   * @since 2.0.0 bbPress (r2734)
 109   *
 110   * @param array $anonymous_data Optional - if it's an anonymous post. Do not
 111   *                              supply if supplying $author_id. Should be
 112   *                              sanitized (see {@link bbp_filter_anonymous_post_data()}
 113   */
 114  function bbp_set_current_anonymous_user_data( $anonymous_data = array() ) {
 115  
 116      // Bail if empty or not an array
 117      if ( empty( $anonymous_data ) || ! is_array( $anonymous_data ) ) {
 118          return;
 119      }
 120  
 121      // Setup cookie expiration
 122      $lifetime = (int) apply_filters( 'comment_cookie_lifetime', 30000000 );
 123      $expiry   = time() + $lifetime;
 124      $secure   = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) );
 125  
 126      // Set the cookies
 127      setcookie( 'comment_author_'       . COOKIEHASH, $anonymous_data['bbp_anonymous_name'],    $expiry, COOKIEPATH, COOKIE_DOMAIN, $secure );
 128      setcookie( 'comment_author_email_' . COOKIEHASH, $anonymous_data['bbp_anonymous_email'],   $expiry, COOKIEPATH, COOKIE_DOMAIN, $secure );
 129      setcookie( 'comment_author_url_'   . COOKIEHASH, $anonymous_data['bbp_anonymous_website'], $expiry, COOKIEPATH, COOKIE_DOMAIN, $secure );
 130  }
 131  
 132  /**
 133   * Get the poster IP address
 134   *
 135   * @since 2.0.0 bbPress (r3120)
 136   * @since 2.6.0 bbPress (r5609) Added `empty()` check for unit tests
 137   *
 138   * @return string
 139   */
 140  function bbp_current_author_ip() {
 141  
 142      // Check for remote address
 143      $remote_address = ! empty( $_SERVER['REMOTE_ADDR'] )
 144          ? wp_unslash( $_SERVER['REMOTE_ADDR'] )
 145          : '127.0.0.1';
 146  
 147      // Remove any unsavory bits
 148      $retval = preg_replace( '/[^0-9a-fA-F:., ]/', '', $remote_address );
 149  
 150      // Filter & return
 151      return apply_filters( 'bbp_current_author_ip', $retval, $remote_address );
 152  }
 153  
 154  /**
 155   * Get the poster user agent
 156   *
 157   * @since 2.0.0 bbPress (r3446)
 158   *
 159   * @return string
 160   */
 161  function bbp_current_author_ua() {
 162      $retval = ! empty( $_SERVER['HTTP_USER_AGENT'] )
 163          ? mb_substr( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ), 0, 254 )
 164          : '';
 165  
 166      // Filter & return
 167      return apply_filters( 'bbp_current_author_ua', $retval );
 168  }
 169  
 170  /** Edit **********************************************************************/
 171  
 172  /**
 173   * Handles the front end user editing from POST requests
 174   *
 175   * @since 2.0.0 bbPress (r2790)
 176   *
 177   * @param string $action The requested action to compare this function to
 178   */
 179  function bbp_edit_user_handler( $action = '' ) {
 180  
 181      // Bail if action is not `bbp-update-user`
 182      if ( 'bbp-update-user' !== $action ) {
 183          return;
 184      }
 185  
 186      // Bail if in wp-admin
 187      if ( is_admin() ) {
 188          return;
 189      }
 190  
 191      // Get the displayed user ID
 192      $user_id = bbp_get_displayed_user_id();
 193  
 194      // Nonce check
 195      if ( ! bbp_verify_nonce_request( 'update-user_' . $user_id ) ) {
 196          bbp_add_error( 'bbp_update_user_nonce', __( '<strong>Error</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
 197          return;
 198      }
 199  
 200      // Cap check
 201      if ( ! current_user_can( 'edit_user', $user_id ) ) {
 202          bbp_add_error( 'bbp_update_user_capability', __( '<strong>Error</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
 203          return;
 204      }
 205  
 206      // Empty email check
 207      if ( empty( $_POST['email'] ) ) {
 208          bbp_add_error( 'bbp_user_email_empty', __( '<strong>Error</strong>: That is not a valid email address.', 'bbpress' ), array( 'form-field' => 'email' ) );
 209          return;
 210      }
 211  
 212      // Get the users current email address to use for comparisons
 213      $user_email = bbp_get_displayed_user_field( 'user_email', 'raw' );
 214  
 215      // Bail if no email change
 216      if ( $user_email !== $_POST['email'] ) {
 217  
 218          // Check that new email address is valid
 219          if ( ! is_email( $_POST['email'] ) ) {
 220              bbp_add_error( 'bbp_user_email_invalid', __( '<strong>Error</strong>: That is not a valid email address.', 'bbpress' ), array( 'form-field' => 'email' ) );
 221              return;
 222          }
 223  
 224          // Check if email address is already in use
 225          if ( email_exists( $_POST['email'] ) ) {
 226              bbp_add_error( 'bbp_user_email_taken', __( '<strong>Error</strong>: That email address is already in use.', 'bbpress' ), array( 'form-field' => 'email' ) );
 227              return;
 228          }
 229  
 230          // Update the option
 231          $option = array(
 232              'hash'     => md5( $_POST['email'] . time() . wp_rand() ),
 233              'newemail' => $_POST['email'],
 234          );
 235          update_user_meta( $user_id, '_new_email', $option );
 236  
 237          // Attempt to notify the user of email address change
 238          bbp_edit_user_email_send_notification( $user_id, $option );
 239  
 240          // Set the POST email variable back to the user's email address
 241          // so `edit_user()` does not attempt to update it. This is not ideal,
 242          // but it's also what send_confirmation_on_profile_email() does.
 243          $_POST['email'] = $user_email;
 244      }
 245  
 246      // Do action based on who's profile you're editing
 247      $edit_action = bbp_is_user_home_edit()
 248          ? 'personal_options_update'
 249          : 'edit_user_profile_update';
 250  
 251      do_action( $edit_action, $user_id );
 252  
 253      // Prevent edit_user() from wiping out the user's Toolbar on front setting
 254      if ( ! isset( $_POST['admin_bar_front'] ) && _get_admin_bar_pref( 'front', $user_id ) ) {
 255          $_POST['admin_bar_front'] = 1;
 256      }
 257  
 258      // Bail if errors already exist
 259      if ( bbp_has_errors() ) {
 260          return;
 261      }
 262  
 263      // Handle user edit
 264      $edit_user = edit_user( $user_id );
 265  
 266      // Error(s) editing the user, so copy them into the global.
 267      if ( is_wp_error( $edit_user ) ) {
 268          bbpress()->errors = $edit_user;
 269  
 270      // Successful edit to redirect
 271      } elseif ( is_integer( $edit_user ) ) {
 272  
 273          // Maybe update super admin ability
 274          if ( is_multisite() && ! bbp_is_user_home_edit() && current_user_can( 'manage_network_options' ) && is_super_admin() ) {
 275              empty( $_POST['super_admin'] )
 276                  ? revoke_super_admin( $edit_user )
 277                  : grant_super_admin( $edit_user );
 278          }
 279  
 280          // Redirect
 281          $args     = array( 'updated' => 'true' );
 282          $user_url = bbp_get_user_profile_edit_url( $edit_user );
 283          $redirect = add_query_arg( $args, $user_url );
 284  
 285          bbp_redirect( $redirect );
 286      }
 287  }
 288  
 289  /**
 290   * Handles user email address updating from GET requests
 291   *
 292   * @since 2.6.0 bbPress (r5660)
 293   *
 294   * @param string $action
 295   */
 296  function bbp_user_email_change_handler( $action = '' ) {
 297  
 298      // Bail if action is not `bbp-update-user-email`
 299      if ( 'bbp-update-user-email' !== $action ) {
 300          return;
 301      }
 302  
 303      // Bail if not on users own profile
 304      if ( ! bbp_is_user_home_edit() ) {
 305          return;
 306      }
 307  
 308      // Bail if not attempting to modify user email address
 309      if ( empty( $_GET['newuseremail'] ) && empty( $_GET['dismiss'] ) ) {
 310          return;
 311      }
 312  
 313      // Get the displayed user ID & option key
 314      $user_id     = bbp_get_displayed_user_id();
 315      $key         = '_new_email';
 316      $redirect_to = bbp_get_user_profile_edit_url( $user_id );
 317  
 318      // Execute confirmed email change.
 319      if ( ! empty( $_GET['newuseremail'] ) ) {
 320  
 321          // Check for email address change option
 322          $new_email = get_user_meta( $user_id, $key, true );
 323  
 324          // Redirect if *no* email address change exists
 325          if ( false === $new_email ) {
 326              bbp_redirect( $redirect_to );
 327          }
 328  
 329          // Cleanup & redirect if *invalid* email address change exists
 330          if ( empty( $new_email['hash'] ) || empty( $new_email['newemail'] ) ) {
 331              delete_user_meta( $user_id, $key );
 332  
 333              bbp_redirect( $redirect_to );
 334          }
 335  
 336          // Compare hashes, and update user if hashes match
 337          if ( hash_equals( $new_email['hash'], $_GET['newuseremail'] ) ) {
 338  
 339              // Does another user have this email address already?
 340              if ( email_exists( $new_email['newemail'] ) ) {
 341                  delete_user_meta( $user_id, $key );
 342  
 343                  bbp_add_error( 'bbp_user_email_taken', __( '<strong>Error</strong>: That email address is already in use.', 'bbpress' ), array( 'form-field' => 'email' ) );
 344  
 345              // Email address is good to change to
 346              } else {
 347  
 348                  // Create a stdClass (for easy call to wp_update_user())
 349                  $user             = new stdClass();
 350                  $user->ID         = $user_id;
 351                  $user->user_email = esc_html( trim( $new_email['newemail'] ) );
 352  
 353                  // Attempt to update user email
 354                  $update_user = wp_update_user( $user );
 355  
 356                  // Error(s) editing the user, so copy them into the global
 357                  if ( is_wp_error( $update_user ) ) {
 358                      bbpress()->errors = $update_user;
 359  
 360                  // All done, so redirect and show the updated message
 361                  } else {
 362  
 363                      // Update signups table, if signups table & entry exists
 364                      // For Multisite & BuddyPress compatibility
 365                      $bbp_db = bbp_db();
 366                      if ( ! empty( $bbp_db->signups ) && $bbp_db->get_var( $bbp_db->prepare( "SELECT user_login FROM {$bbp_db->signups} WHERE user_login = %s", bbp_get_displayed_user_field( 'user_login', 'raw' ) ) ) ) {
 367                          $bbp_db->query( $bbp_db->prepare( "UPDATE {$bbp_db->signups} SET user_email = %s WHERE user_login = %s", $user->user_email, bbp_get_displayed_user_field( 'user_login', 'raw' ) ) );
 368                      }
 369  
 370                      delete_user_meta( $user_id, $key );
 371  
 372                      bbp_redirect( add_query_arg( array( 'updated' => 'true' ), $redirect_to ) );
 373                  }
 374              }
 375          }
 376  
 377      // Delete new email address from user options
 378      } elseif ( ! empty( $_GET['dismiss'] ) && ( "{$user_id}{$key}" === $_GET['dismiss'] ) ) {
 379          if ( ! bbp_verify_nonce_request( "dismiss-{$user_id}{$key}" ) ) {
 380              bbp_add_error( 'bbp_dismiss_new_email_nonce', __( '<strong>Error</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
 381              return;
 382          }
 383  
 384          delete_user_meta( $user_id, $key );
 385          bbp_redirect( $redirect_to );
 386      }
 387  }
 388  
 389  /**
 390   * Sends an email when an email address change occurs on POST requests
 391   *
 392   * @since 2.6.0 bbPress (r5660)
 393   *
 394   * @see send_confirmation_on_profile_email()
 395   */
 396  function bbp_edit_user_email_send_notification( $user_id = 0, $args = array() ) {
 397  
 398      // Parse args
 399      $r = bbp_parse_args( $args, array(
 400          'hash'     => '',
 401          'newemail' => '',
 402      ) );
 403  
 404      // Bail if any relevant parameters are empty
 405      if ( empty( $user_id ) || empty( $r['hash'] ) || empty( $r['newemail'] ) ) {
 406          bbp_add_error( 'bbp_user_email_invalid_hash', __( '<strong>Error</strong>: An error occurred while updating your email address.', 'bbpress' ), array( 'form-field' => 'email' ) );
 407          return;
 408      }
 409  
 410      // Build the nonced URL to dismiss the pending change
 411      $user_login  = bbp_get_displayed_user_field( 'user_login', 'raw' );
 412      $user_url    = bbp_get_user_profile_edit_url( $user_id );
 413      $confirm_url = add_query_arg( array(
 414          'action'       => 'bbp-update-user-email',
 415          'newuseremail' => $r['hash']
 416      ), $user_url );
 417  
 418      $email_text = __( '%1$s
 419  
 420  Someone requested a change to the email address on your account.
 421  
 422  Please click the following link to confirm this change:
 423  %2$s
 424  
 425  If you did not request this, you can safely ignore and delete this notification.
 426  
 427  This email was sent to: %3$s
 428  
 429  Regards,
 430  The %4$s Team
 431  %5$s', 'bbpress' );
 432  
 433      /**
 434       * Filter the email text sent when a user changes emails.
 435       *
 436       * The following strings have a special meaning and will get replaced dynamically:
 437       *
 438       * %1$s - The current user's username
 439       * %2$s - The link to click on to confirm the email change
 440       * %3$s - The new email
 441       * %4$s - The name of the site
 442       * %5$s - The URL to the site
 443       *
 444       * @param string $email_text Text in the email.
 445       * @param string $r          New user email that the current user has changed to.
 446       */
 447      $content = apply_filters( 'bbp_user_email_update_content', $email_text, $r );
 448  
 449      // Build the email message
 450      $message = sprintf( $content, $user_login, $confirm_url, $r['newemail'], get_site_option( 'site_name' ), network_home_url() );
 451  
 452      // Build the email subject
 453      $subject = sprintf( __( '[%s] New Email Address', 'bbpress' ), wp_specialchars_decode( get_option( 'blogname' ) ) );
 454  
 455      // Send the email
 456      wp_mail( $r['newemail'], $subject, $message );
 457  }
 458  
 459  /**
 460   * Conditionally hook the core WordPress output actions to the end of the
 461   * default user's edit profile template
 462   *
 463   * This allows clever plugin authors to conditionally unhook the WordPress core
 464   * output actions if they don't want any unexpected junk to appear there, and
 465   * also avoids needing to pollute the templates with additional logic and actions.
 466   *
 467   * @since 2.2.0 bbPress (r4273)
 468   */
 469  function bbp_user_edit_after() {
 470      $action = bbp_is_user_home_edit() ? 'show_user_profile' : 'edit_user_profile';
 471  
 472      do_action( $action, get_userdata( bbp_get_displayed_user_id() ) );
 473  }
 474  
 475  /** User Queries **************************************************************/
 476  
 477  /**
 478   * Get the topics that a user created
 479   *
 480   * @since 2.0.0 bbPress (r2660)
 481   * @since 2.6.0 bbPress (r6618) Signature changed to accept an array of arguments
 482   *
 483   * @param array $args    Optional. Arguments to pass into bbp_has_topics()
 484   *
 485   * @return bool True if user has started topics, otherwise false
 486   */
 487  function bbp_get_user_topics_started( $args = array() ) {
 488  
 489      // Backwards compat for pre-2.6.0
 490      if ( is_numeric( $args ) ) {
 491          $args = array(
 492              'author' => bbp_get_user_id( $args, false, false )
 493          );
 494      }
 495  
 496      // Default arguments
 497      $defaults = array(
 498          'author' => bbp_get_displayed_user_id()
 499      );
 500  
 501      // Parse arguments
 502      $r = bbp_parse_args( $args, $defaults, 'get_user_topics_started' );
 503  
 504      // Get the topics
 505      $query   = bbp_has_topics( $r );
 506      $user_id = $r['author'];
 507  
 508      // Filter & return
 509      return apply_filters( 'bbp_get_user_topics_started', $query, $user_id, $r, $args );
 510  }
 511  
 512  /**
 513   * Get the replies that a user created
 514   *
 515   * @since 2.2.0 bbPress (r4225)
 516   * @since 2.6.0 bbPress (r6618) Signature changed to accept an array of arguments
 517   *
 518   * @param array $args Optional. Arguments to pass into bbp_has_replies()
 519   *
 520   * @return bool True if user has created replies, otherwise false
 521   */
 522  function bbp_get_user_replies_created( $args = array() ) {
 523  
 524      // Backwards compat for pre-2.6.0
 525      if ( is_numeric( $args ) ) {
 526          $args = array(
 527              'author' => bbp_get_user_id( $args, false, false ),
 528              'post_type' => bbp_get_reply_post_type(),
 529              'order'     => 'DESC'
 530          );
 531      }
 532  
 533      // Default arguments
 534      $defaults = array(
 535          'author'    => bbp_get_displayed_user_id(),
 536          'post_type' => bbp_get_reply_post_type(),
 537          'order'     => 'DESC'
 538      );
 539  
 540      // Parse arguments
 541      $r = bbp_parse_args( $args, $defaults, 'get_user_replies_created' );
 542  
 543      // Get the replies
 544      $query   = bbp_has_replies( $r );
 545      $user_id = $r['author'];
 546  
 547      // Filter & return
 548      return apply_filters( 'bbp_get_user_replies_created', $query, $user_id, $r, $args );
 549  }
 550  
 551  /**
 552   * Get user IDs from nicenames
 553   *
 554   * This function is primarily used when saving object moderators
 555   *
 556   * @since 2.6.0 bbPress
 557   *
 558   * @param mixed $user_nicenames
 559   * @return array
 560   */
 561  function bbp_get_user_ids_from_nicenames( $user_nicenames = array() ) {
 562  
 563      // Default value
 564      $retval = array();
 565  
 566      // Only query if nicenames
 567      if ( ! empty( $user_nicenames ) ) {
 568  
 569          // Maybe explode by comma
 570          $user_nicenames = ( is_string( $user_nicenames ) && strstr( $user_nicenames, ',' ) )
 571              ? explode( ',', $user_nicenames )
 572              : (array) $user_nicenames;
 573  
 574          // Sanitize each nicename in the array
 575          $user_nicenames = array_map( 'sanitize_title', $user_nicenames );
 576  
 577          // Get users
 578          $users = get_users( array(
 579              'nicename__in' => $user_nicenames
 580          ) );
 581  
 582          // Pluck or empty
 583          if ( ! empty( $users ) ) {
 584              $retval = wp_list_pluck( $users, 'ID' );
 585          }
 586      }
 587  
 588      // Filter & return
 589      return (array) apply_filters( 'bbp_get_user_ids_from_nicenames', $retval, $user_nicenames );
 590  }
 591  
 592  /**
 593   * Get user nicenames from IDs
 594   *
 595   * This function is primarily used when saving object moderators
 596   *
 597   * @since 2.6.0 bbPress
 598   *
 599   * @param mixed $user_ids
 600   * @return array
 601   */
 602  function bbp_get_user_nicenames_from_ids( $user_ids = array() ) {
 603  
 604      // Default value
 605      $retval = array();
 606  
 607      // Only query if nicenames
 608      if ( ! empty( $user_ids ) ) {
 609  
 610          // Get users
 611          $users = get_users( array(
 612              'include' => $user_ids
 613          ) );
 614  
 615          // Pluck or empty
 616          if ( ! empty( $users ) ) {
 617              $retval = wp_list_pluck( $users, 'user_nicename' );
 618          }
 619      }
 620  
 621      // Filter & return
 622      return (array) apply_filters( 'bbp_get_user_nicenames_from_ids', $retval, $user_ids );
 623  }
 624  
 625  /** Post Counts ***************************************************************/
 626  
 627  /**
 628   * Return the raw database count of topics by a user
 629   *
 630   * @since 2.1.0 bbPress (r3633)
 631   *
 632   * @param int $user_id User ID to get count for
 633   *
 634   * @return int Raw DB count of topics
 635   */
 636  function bbp_get_user_topic_count_raw( $user_id = 0 ) {
 637      $user_id = bbp_get_user_id( $user_id );
 638      $bbp_db  = bbp_db();
 639      $statii  = "'" . implode( "', '", bbp_get_public_topic_statuses() ) . "'";
 640      $sql     = "SELECT COUNT(*)
 641              FROM {$bbp_db->posts}
 642              WHERE post_author = %d
 643                  AND post_type = %s
 644                  AND post_status IN ({$statii})";
 645  
 646      $query   = $bbp_db->prepare( $sql, $user_id, bbp_get_topic_post_type() );
 647      $count   = (int) $bbp_db->get_var( $query );
 648  
 649      // Filter & return
 650      return (int) apply_filters( 'bbp_get_user_topic_count_raw', $count, $user_id );
 651  }
 652  
 653  /**
 654   * Return the raw database count of replies by a user
 655   *
 656   * @since 2.1.0 bbPress (r3633)
 657   *
 658   * @param int $user_id User ID to get count for
 659   *
 660   * @return int Raw DB count of replies
 661   */
 662  function bbp_get_user_reply_count_raw( $user_id = 0 ) {
 663      $user_id = bbp_get_user_id( $user_id );
 664      $bbp_db  = bbp_db();
 665      $statii  = "'" . implode( "', '", bbp_get_public_reply_statuses() ) . "'";
 666      $sql     = "SELECT COUNT(*)
 667              FROM {$bbp_db->posts}
 668              WHERE post_author = %d
 669                  AND post_type = %s
 670                  AND post_status IN ({$statii})";
 671  
 672      $query   = $bbp_db->prepare( $sql, $user_id, bbp_get_reply_post_type() );
 673      $count   = (int) $bbp_db->get_var( $query );
 674  
 675      // Filter & return
 676      return (int) apply_filters( 'bbp_get_user_reply_count_raw', $count, $user_id );
 677  }
 678  
 679  /**
 680   * Bump the topic count for a user by a certain amount.
 681   *
 682   * @since 2.6.0 bbPress (r5309)
 683   *
 684   * @param int $user_id
 685   * @param int $difference
 686   */
 687  function bbp_bump_user_topic_count( $user_id = 0, $difference = 1 ) {
 688  
 689      // Bail if no bump
 690      if ( empty( $difference ) ) {
 691          return false;
 692      }
 693  
 694      // Validate user ID
 695      $user_id = bbp_get_user_id( $user_id );
 696      if ( empty( $user_id ) ) {
 697          return false;
 698      }
 699  
 700      // Check meta for count, or query directly if not found
 701      $count = bbp_get_user_topic_count( $user_id, true );
 702      if ( empty( $count ) ) {
 703          $count = bbp_get_user_topic_count_raw( $user_id );
 704      }
 705  
 706      $difference       = (int) $difference;
 707      $user_topic_count = (int) ( $count + $difference );
 708  
 709      // Add them up and filter them
 710      $new_count = (int) apply_filters( 'bbp_bump_user_topic_count', $user_topic_count, $user_id, $difference, $count );
 711  
 712      return bbp_update_user_topic_count( $user_id, $new_count );
 713  }
 714  
 715  /**
 716   * Bump the reply count for a user by a certain amount.
 717   *
 718   * @since 2.6.0 bbPress (r5309)
 719   *
 720   * @param int $user_id
 721   * @param int $difference
 722   */
 723  function bbp_bump_user_reply_count( $user_id = 0, $difference = 1 ) {
 724  
 725      // Bail if no bump
 726      if ( empty( $difference ) ) {
 727          return false;
 728      }
 729  
 730      // Validate user ID
 731      $user_id = bbp_get_user_id( $user_id );
 732      if ( empty( $user_id ) ) {
 733          return false;
 734      }
 735  
 736      // Check meta for count, or query directly if not found
 737      $count = bbp_get_user_reply_count( $user_id, true );
 738      if ( empty( $count ) ) {
 739          $count = bbp_get_user_reply_count_raw( $user_id );
 740      }
 741  
 742      $difference       = (int) $difference;
 743      $user_reply_count = (int) ( $count + $difference );
 744  
 745      // Add them up and filter them
 746      $new_count = (int) apply_filters( 'bbp_bump_user_reply_count', $user_reply_count, $user_id, $difference, $count );
 747  
 748      return bbp_update_user_reply_count( $user_id, $new_count );
 749  }
 750  
 751  /**
 752   * Helper function used to increase (by one) the count of topics for a user when
 753   * a topic is published.
 754   *
 755   * @since 2.6.0 bbPress (r5309)
 756   *
 757   * @access
 758   * @param $topic_id
 759   * @param $forum_id
 760   * @param $anonymous_data
 761   * @param $topic_author
 762   */
 763  function bbp_increase_user_topic_count( $topic_id = 0 ) {
 764      $user_id = bbp_get_topic_author_id( $topic_id );
 765      return bbp_bump_user_topic_count( $user_id, 1 );
 766  }
 767  
 768  /**
 769   * Helper function used to increase (by one) the count of replies for a user when
 770   * a reply is published.
 771   *
 772   * This is a helper function, hooked to `bbp_new_reply`
 773   *
 774   * @since 2.6.0 bbPress (r5309)
 775   *
 776   * @param $topic_id
 777   * @param $forum_id
 778   * @param $anonymous_data
 779   * @param $topic_author
 780   */
 781  function bbp_increase_user_reply_count( $reply_id = 0 ) {
 782      $user_id = bbp_get_reply_author_id( $reply_id );
 783      return bbp_bump_user_reply_count( $user_id, 1 );
 784  }
 785  
 786  /**
 787   * Helper function used to decrease (by one) the count of topics for a user when
 788   * a topic is unpublished.
 789   *
 790   * @since 2.6.0 bbPress (r5309)
 791   *
 792   * @param $topic_id
 793   */
 794  function bbp_decrease_user_topic_count( $topic_id = 0 ) {
 795      $user_id = bbp_get_topic_author_id( $topic_id );
 796      return bbp_bump_user_topic_count( $user_id, -1 );
 797  }
 798  
 799  /**
 800   * Helper function used to increase (by one) the count of replies for a user when
 801   * a topic is unpublished.
 802   *
 803   * @since 2.6.0 bbPress (r5309)
 804   *
 805   * @param $reply_id
 806   */
 807  function bbp_decrease_user_reply_count( $reply_id = 0 ) {
 808      $user_id = bbp_get_reply_author_id( $reply_id );
 809      return bbp_bump_user_reply_count( $user_id, -1 );
 810  }
 811  
 812  /** Permissions ***************************************************************/
 813  
 814  /**
 815   * Redirect if unauthorized user is attempting to edit another user
 816   *
 817   * This is hooked to 'bbp_template_redirect' and controls the conditions under
 818   * which a user can edit another user (or themselves.) If these conditions are
 819   * met, we assume a user cannot perform this task, and look for ways they can
 820   * earn the ability to access this template.
 821   *
 822   * @since 2.1.0 bbPress (r3605)
 823   */
 824  function bbp_check_user_edit() {
 825  
 826      // Bail if not editing a user
 827      if ( ! bbp_is_single_user_edit() ) {
 828          return;
 829      }
 830  
 831      // Default to false
 832      $redirect = true;
 833      $user_id  = bbp_get_displayed_user_id();
 834  
 835      // Allow user to edit their own profile
 836      if ( bbp_is_user_home_edit() ) {
 837          $redirect = false;
 838  
 839      // Allow if current user can edit the displayed user
 840      } elseif ( current_user_can( 'edit_user', $user_id ) ) {
 841          $redirect = false;
 842  
 843      // Allow if user can manage network users, or edit-any is enabled
 844      } elseif ( current_user_can( 'manage_network_users' ) || apply_filters( 'enable_edit_any_user_configuration', false ) ) {
 845          $redirect = false;
 846      }
 847  
 848      // Allow conclusion to be overridden
 849      $redirect = (bool) apply_filters( 'bbp_check_user_edit', $redirect, $user_id );
 850  
 851      // Bail if not redirecting
 852      if ( false === $redirect ) {
 853          return;
 854      }
 855  
 856      // Filter redirect URL
 857      $profile_url = bbp_get_user_profile_url( $user_id );
 858      $redirect_to = apply_filters( 'bbp_check_user_edit_redirect_to', $profile_url, $user_id );
 859  
 860      // Redirect
 861      bbp_redirect( $redirect_to );
 862  }
 863  
 864  /**
 865   * Check if a user is blocked, or cannot spectate the forums.
 866   *
 867   * @since 2.0.0 bbPress (r2996)
 868   */
 869  function bbp_forum_enforce_blocked() {
 870  
 871      // Bail if not logged in or keymaster
 872      if ( ! is_user_logged_in() || bbp_is_user_keymaster() ) {
 873          return;
 874      }
 875  
 876      // Set 404 if in bbPress and user cannot spectate
 877      if ( is_bbpress() && ! current_user_can( 'spectate' ) ) {
 878          bbp_set_404();
 879      }
 880  }
 881  
 882  /** Sanitization **************************************************************/
 883  
 884  /**
 885   * Sanitize displayed user data, when viewing and editing any user.
 886   *
 887   * This somewhat monolithic function handles the escaping and sanitization of
 888   * user data for a bbPress profile. There are two reasons this all happens here:
 889   *
 890   * 1. bbPress took a similar approach to WordPress, and funnels all user profile
 891   *    data through a central helper. This eventually calls sanitize_user_field()
 892   *    which applies a few context based filters, which some third party plugins
 893   *    might be relying on bbPress to play nicely with.
 894   *
 895   * 2. Early versions of bbPress 2.x templates did not escape this data meaning
 896   *    a backwards compatible approach like this one was necessary to protect
 897   *    existing installations that may have custom template parts.
 898   *
 899   * @since 2.6.0 bbPress (r5368)
 900   *
 901   * @param string $value
 902   * @param string $field
 903   * @param string $context
 904   * @return string
 905   */
 906  function bbp_sanitize_displayed_user_field( $value = '', $field = '', $context = 'display' ) {
 907  
 908      // Bail if not editing or displaying (maybe we'll do more here later)
 909      if ( ! in_array( $context, array( 'edit', 'display' ), true ) ) {
 910          return $value;
 911      }
 912  
 913      // By default, no filter set (consider making this an array later)
 914      $filter = false;
 915  
 916      // Big switch statement to decide which user field we're sanitizing and how
 917      switch ( $field ) {
 918  
 919          // Description is a paragraph
 920          case 'description' :
 921              $filter = ( 'edit' === $context ) ? '' : 'wp_kses_data';
 922              break;
 923  
 924          // Email addresses are sanitized with a specific function
 925          case 'user_email'  :
 926              $filter = 'sanitize_email';
 927              break;
 928  
 929          // Name & login fields
 930          case 'user_login'   :
 931          case 'display_name' :
 932          case 'first_name'   :
 933          case 'last_name'    :
 934          case 'nick_name'    :
 935              $filter = ( 'edit' === $context ) ? 'esc_attr' : 'esc_html';
 936              break;
 937  
 938          // wp-includes/default-filters.php escapes this for us via esc_url()
 939          case 'user_url' :
 940              break;
 941      }
 942  
 943      // Run any applicable filters on the value
 944      if ( ! empty( $filter ) ) {
 945          $value = call_user_func( $filter, $value );
 946      }
 947  
 948      return $value;
 949  }
 950  
 951  /** Converter *****************************************************************/
 952  
 953  /**
 954   * Convert passwords from previous platform encryption to WordPress encryption.
 955   *
 956   * @since 2.1.0 bbPress (r3813)
 957   * @since 2.6.10 bbPress (r7244) Switched from direct query to get_user_by()
 958   */
 959  function bbp_user_maybe_convert_pass() {
 960  
 961      // Sanitize login
 962      $login = ! empty( $_POST['log'] )
 963          ? sanitize_user( wp_unslash( $_POST['log'] ) )
 964          : '';
 965  
 966      // Sanitize password
 967      $pass = ! empty( $_POST['pwd'] )
 968          ? trim( $_POST['pwd'] )
 969          : '';
 970  
 971      // Bail if no username or password
 972      if ( empty( $login ) || empty( $pass ) ) {
 973          return;
 974      }
 975  
 976      // Get user by login...
 977      $user = get_user_by( 'login', $login );
 978  
 979      // ...or get user by email
 980      if ( empty( $user ) && strpos( $login, '@' ) ) {
 981          $user = get_user_by( 'email', $login );
 982      }
 983  
 984      // Bail if no user
 985      if ( empty( $user ) ) {
 986          return;
 987      }
 988  
 989      // Get converter class from usermeta
 990      $class = get_user_meta( $user->ID, '_bbp_class', true );
 991  
 992      // Bail if no converter class in meta
 993      if ( empty( $class ) || ! is_string( $class ) ) {
 994          return;
 995      }
 996  
 997      // Setup the converter
 998      bbp_setup_converter();
 999  
1000      // Try to instantiate the converter class
1001      $converter = bbp_new_converter( $class );
1002  
1003      // Bail if no converter
1004      if ( empty( $converter ) ) {
1005          return;
1006      }
1007  
1008      // Try to call the password conversion callback method
1009      if ( ( $converter instanceof BBP_Converter_Base ) && method_exists( $converter, 'callback_pass' ) ) {
1010          $converter->callback_pass( $login, $pass );
1011      }
1012  }


Generated: Tue Dec 3 01:00:50 2024 Cross-referenced by PHPXref 0.7.1