[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-core/ -> bp-core-avatars.php (source)

   1  <?php
   2  /**
   3   * BuddyPress Avatars.
   4   *
   5   * @package BuddyPress
   6   * @subpackage Core
   7   * @since 1.0.0
   8   */
   9  
  10  // Exit if accessed directly.
  11  defined( 'ABSPATH' ) || exit;
  12  
  13  /**
  14   * Set up the constants we need for avatar support.
  15   *
  16   * @since 1.2.0
  17   */
  18  function bp_core_set_avatar_constants() {
  19  
  20      $bp = buddypress();
  21  
  22      if ( !defined( 'BP_AVATAR_THUMB_WIDTH' ) )
  23          define( 'BP_AVATAR_THUMB_WIDTH', 50 );
  24  
  25      if ( !defined( 'BP_AVATAR_THUMB_HEIGHT' ) )
  26          define( 'BP_AVATAR_THUMB_HEIGHT', 50 );
  27  
  28      if ( !defined( 'BP_AVATAR_FULL_WIDTH' ) )
  29          define( 'BP_AVATAR_FULL_WIDTH', 150 );
  30  
  31      if ( !defined( 'BP_AVATAR_FULL_HEIGHT' ) )
  32          define( 'BP_AVATAR_FULL_HEIGHT', 150 );
  33  
  34      if ( !defined( 'BP_AVATAR_ORIGINAL_MAX_WIDTH' ) )
  35          define( 'BP_AVATAR_ORIGINAL_MAX_WIDTH', 450 );
  36  
  37      if ( !defined( 'BP_AVATAR_ORIGINAL_MAX_FILESIZE' ) ) {
  38          define( 'BP_AVATAR_ORIGINAL_MAX_FILESIZE', bp_attachments_get_max_upload_file_size( 'avatar' ) );
  39      }
  40  
  41      if ( ! defined( 'BP_SHOW_AVATARS' ) ) {
  42          define( 'BP_SHOW_AVATARS', bp_get_option( 'show_avatars' ) );
  43      }
  44  }
  45  add_action( 'bp_init', 'bp_core_set_avatar_constants', 3 );
  46  
  47  /**
  48   * Set up global variables related to avatars.
  49   *
  50   * @since 1.5.0
  51   */
  52  function bp_core_set_avatar_globals() {
  53      $bp = buddypress();
  54  
  55      $bp->avatar        = new stdClass;
  56      $bp->avatar->thumb = new stdClass;
  57      $bp->avatar->full  = new stdClass;
  58  
  59      // Dimensions.
  60      $bp->avatar->thumb->width  = BP_AVATAR_THUMB_WIDTH;
  61      $bp->avatar->thumb->height = BP_AVATAR_THUMB_HEIGHT;
  62      $bp->avatar->full->width   = BP_AVATAR_FULL_WIDTH;
  63      $bp->avatar->full->height  = BP_AVATAR_FULL_HEIGHT;
  64  
  65      // Upload maximums.
  66      $bp->avatar->original_max_width    = BP_AVATAR_ORIGINAL_MAX_WIDTH;
  67      $bp->avatar->original_max_filesize = BP_AVATAR_ORIGINAL_MAX_FILESIZE;
  68  
  69      // Defaults.
  70      $bp->avatar->thumb->default = bp_core_avatar_default_thumb();
  71      $bp->avatar->full->default  = bp_core_avatar_default();
  72  
  73      // These have to be set on page load in order to avoid infinite filter loops at runtime.
  74      $bp->avatar->upload_path = bp_core_avatar_upload_path();
  75      $bp->avatar->url = bp_core_avatar_url();
  76  
  77      // Cache the root blog's show_avatars setting, to avoid unnecessary
  78      // calls to switch_to_blog().
  79      $bp->avatar->show_avatars = (bool) BP_SHOW_AVATARS;
  80  
  81      // Backpat for pre-1.5.
  82      if ( ! defined( 'BP_AVATAR_UPLOAD_PATH' ) )
  83          define( 'BP_AVATAR_UPLOAD_PATH', $bp->avatar->upload_path );
  84  
  85      // Backpat for pre-1.5.
  86      if ( ! defined( 'BP_AVATAR_URL' ) )
  87          define( 'BP_AVATAR_URL', $bp->avatar->url );
  88  
  89      /**
  90       * Fires at the end of the core avatar globals setup.
  91       *
  92       * @since 1.5.0
  93       */
  94      do_action( 'bp_core_set_avatar_globals' );
  95  }
  96  add_action( 'bp_setup_globals', 'bp_core_set_avatar_globals' );
  97  
  98  /**
  99   * Checks whether a given gravatar is one of the default ones.
 100   *
 101   * @since 8.0.0
 102   *
 103   * @param string $d The name of the default gravatar.
 104   * @return bool True if it's a default gravatar. False otherwise.
 105   */
 106  function bp_core_is_default_gravatar( $d = '' ) {
 107      if ( ! $d ) {
 108          return false;
 109      }
 110  
 111      /** this filter is documented in wp-admin/options-discussion.php */
 112      $gravatar_defaults = apply_filters(
 113          'avatar_defaults',
 114          array_fill_keys(
 115              array(
 116                  'mystery',
 117                  'blank',
 118                  'gravatar_default',
 119                  'identicon',
 120                  'wavatar',
 121                  'monsterid',
 122                  'retro',
 123              ),
 124              ''
 125          )
 126      );
 127  
 128      return isset( $gravatar_defaults[ $d ] );
 129  }
 130  
 131  /**
 132   * Get an avatar for a BuddyPress object.
 133   *
 134   * Supports avatars for users, groups, and blogs by default, but can be
 135   * extended to support custom components as well.
 136   *
 137   * This function gives precedence to locally-uploaded avatars. When a local
 138   * avatar is not found, Gravatar is queried. To disable Gravatar fallbacks
 139   * locally:
 140   *    add_filter( 'bp_core_fetch_avatar_no_grav', '__return_true' );
 141   *
 142   * @since 1.1.0
 143   * @since 2.4.0 Added 'extra_attr', 'scheme', 'rating' and 'force_default' for $args.
 144   *              These are inherited from WordPress 4.2.0. See {@link get_avatar()}.
 145   *
 146   * @param array|string $args {
 147   *     An array of arguments. All arguments are technically optional; some
 148   *     will, if not provided, be auto-detected by bp_core_fetch_avatar(). This
 149   *     auto-detection is described more below, when discussing specific
 150   *     arguments.
 151   *
 152   *     @type int|bool    $item_id    The numeric ID of the item for which you're requesting
 153   *                                   an avatar (eg, a user ID). If no 'item_id' is present,
 154   *                                   the function attempts to infer an ID from the 'object' + the
 155   *                                   current context: if 'object' is 'user' and the current page is a
 156   *                                   user page, 'item_id' will default to the displayed user ID; if
 157   *                                   'group' and on a group page, to the current group ID; if 'blog',
 158   *                                   to the current blog's ID. If no 'item_id' can be determined in
 159   *                                   this way, the function returns false. Default: false.
 160   *     @type string      $object     The kind of object for which you're getting an
 161   *                                   avatar. BuddyPress natively supports three options: 'user',
 162   *                                   'group', 'blog'; a plugin may register more.  Default: 'user'.
 163   *     @type string      $type       When a new avatar is uploaded to BP, 'thumb' and
 164   *                                   'full' versions are saved. This parameter specifies whether you'd
 165   *                                   like the 'full' or smaller 'thumb' avatar. Default: 'thumb'.
 166   *     @type string|bool $avatar_dir The name of the subdirectory where the
 167   *                                   requested avatar should be found. If no value is passed,
 168   *                                   'avatar_dir' is inferred from 'object': 'user' becomes 'avatars',
 169   *                                   'group' becomes 'group-avatars', 'blog' becomes 'blog-avatars'.
 170   *                                   Remember that this string denotes a subdirectory of BP's main
 171   *                                   avatar directory (usually based on {@link wp_upload_dir()}); it's a
 172   *                                   string like 'group-avatars' rather than the full directory path.
 173   *                                   Generally, it'll only be necessary to override the default value if
 174   *                                   storing avatars in a non-default location. Defaults to false
 175   *                                   (auto-detected).
 176   *     @type int|bool    $width      Requested avatar width. The unit is px. This value
 177   *                                   is used to build the 'width' attribute for the <img> element. If
 178   *                                   no value is passed, BP uses the global avatar width for this
 179   *                                   avatar type. Default: false (auto-detected).
 180   *     @type int|bool    $height     Requested avatar height. The unit is px. This
 181   *                                   value is used to build the 'height' attribute for the <img>
 182   *                                   element. If no value is passed, BP uses the global avatar height
 183   *                                   for this avatar type. Default: false (auto-detected).
 184   *     @type string      $class      The CSS class for the <img> element. Note that BP
 185   *                                   uses the 'avatar' class fairly extensively in its default styling,
 186   *                                   so if you plan to pass a custom value, consider appending it to
 187   *                                   'avatar' (eg 'avatar foo') rather than replacing it altogether.
 188   *                                   Default: 'avatar'.
 189   *     @type string|bool $css_id     The CSS id for the <img> element.
 190   *                                   Default: false.
 191   *     @type string      $title      The title attribute for the <img> element.
 192   *                                   Default: false.
 193   *     @type string      $alt        The alt attribute for the <img> element. In BP, this
 194   *                                   value is generally passed by the wrapper functions, where the data
 195   *                                   necessary for concatenating the string is at hand; see
 196   *                                   {@link bp_get_activity_avatar()} for an example. Default: ''.
 197   *     @type string|bool $email      An email to use in Gravatar queries. Unless
 198   *                                   otherwise configured, BP uses Gravatar as a fallback for avatars
 199   *                                   that are not provided locally. Gravatar's API requires using a hash
 200   *                                   of the user's email address; this argument provides it. If not
 201   *                                   provided, the function will infer it: for users, by getting the
 202   *                                   user's email from the database, for groups/blogs, by concatenating
 203   *                                   "{$item_id}-{$object}@{bp_get_root_domain()}". The user query adds
 204   *                                   overhead, so it's recommended that wrapper functions provide a
 205   *                                   value for 'email' when querying user IDs. Default: false.
 206   *     @type bool       $no_grav     Whether to disable the default Gravatar fallback.
 207   *                                   By default, BP will fall back on Gravatar when it cannot find a
 208   *                                   local avatar. In some cases, this may be undesirable, in which
 209   *                                   case 'no_grav' should be set to true. To disable Gravatar
 210   *                                   fallbacks globally, see the 'bp_core_fetch_avatar_no_grav' filter.
 211   *                                   Default: true for groups, otherwise false.
 212   *     @type bool       $html        Whether to return an <img> HTML element, vs a raw URL
 213   *                                   to an avatar. If false, <img>-specific arguments (like 'css_id')
 214   *                                   will be ignored. Default: true.
 215   *     @type string     $extra_attr  HTML attributes to insert in the IMG element. Not sanitized. Default: ''.
 216   *     @type string     $scheme      URL scheme to use. See set_url_scheme() for accepted values.
 217   *                                   Default null.
 218   *     @type string     $rating      What rating to display Gravatars for. Accepts 'G', 'PG', 'R', 'X'.
 219   *                                   Default is the value of the 'avatar_rating' option.
 220   *     @type bool       $force_default Used when creating the Gravatar URL. Whether to force the default
 221   *                                     image regardless if the Gravatar exists. Default: false.
 222   * }
 223   * @return string Formatted HTML <img> element, or raw avatar URL based on $html arg.
 224   */
 225  function bp_core_fetch_avatar( $args = '' ) {
 226      $bp = buddypress();
 227  
 228      // If avatars are disabled for the root site, obey that request and bail.
 229      if ( ! $bp->avatar || ! $bp->avatar->show_avatars ) {
 230          return;
 231      }
 232  
 233      // Set the default variables array and parse it against incoming $args array.
 234      $params = wp_parse_args( $args, array(
 235          'item_id'       => false,
 236          'object'        => 'user',
 237          'type'          => 'thumb',
 238          'avatar_dir'    => false,
 239          'width'         => false,
 240          'height'        => false,
 241          'class'         => 'avatar',
 242          'css_id'        => false,
 243          'alt'           => '',
 244          'email'         => false,
 245          'no_grav'       => null,
 246          'html'          => true,
 247          'title'         => '',
 248          'extra_attr'    => '',
 249          'scheme'        => null,
 250          'rating'        => get_option( 'avatar_rating' ),
 251          'force_default' => false,
 252      ) );
 253  
 254      /* Set item_id ***********************************************************/
 255  
 256      if ( empty( $params['item_id'] ) ) {
 257  
 258          switch ( $params['object'] ) {
 259  
 260              case 'blog'  :
 261                  $params['item_id'] = get_current_blog_id();
 262                  break;
 263  
 264              case 'group' :
 265                  if ( bp_is_active( 'groups' ) ) {
 266                      $params['item_id'] = $bp->groups->current_group->id;
 267                  } else {
 268                      $params['item_id'] = false;
 269                  }
 270  
 271                  break;
 272  
 273              case 'user'  :
 274              default      :
 275                  $params['item_id'] = bp_displayed_user_id();
 276                  break;
 277          }
 278  
 279          /**
 280           * Filters the ID of the item being requested.
 281           *
 282           * @since 1.1.0
 283           *
 284           * @param string $value  ID of avatar item being requested.
 285           * @param string $value  Avatar type being requested.
 286           * @param array  $params Array of parameters for the request.
 287           */
 288          $params['item_id'] = apply_filters( 'bp_core_avatar_item_id', $params['item_id'], $params['object'], $params );
 289  
 290          if ( empty( $params['item_id'] ) ) {
 291              return false;
 292          }
 293      }
 294  
 295      /* Set avatar_dir ********************************************************/
 296  
 297      if ( empty( $params['avatar_dir'] ) ) {
 298  
 299          switch ( $params['object'] ) {
 300  
 301              case 'blog'  :
 302                  $params['avatar_dir'] = 'blog-avatars';
 303                  break;
 304  
 305              case 'group' :
 306                  if ( bp_is_active( 'groups' ) ) {
 307                      $params['avatar_dir'] = 'group-avatars';
 308                  } else {
 309                      $params['avatar_dir'] = false;
 310                  }
 311  
 312                  break;
 313  
 314              case 'user'  :
 315              default      :
 316                  $params['avatar_dir'] = 'avatars';
 317                  break;
 318          }
 319  
 320          /**
 321           * Filters the avatar directory to use.
 322           *
 323           * @since 1.1.0
 324           *
 325           * @param string $value  Name of the subdirectory where the requested avatar should be found.
 326           * @param string $value  Avatar type being requested.
 327           * @param array  $params Array of parameters for the request.
 328           */
 329          $params['avatar_dir'] = apply_filters( 'bp_core_avatar_dir', $params['avatar_dir'], $params['object'], $params );
 330  
 331          if ( empty( $params['avatar_dir'] ) ) {
 332              return false;
 333          }
 334      }
 335  
 336      /* <img> alt *************************************************************/
 337  
 338      if ( false !== strpos( $params['alt'], '%s' ) || false !== strpos( $params['alt'], '%1$s' ) ) {
 339  
 340          switch ( $params['object'] ) {
 341  
 342              case 'blog'  :
 343                  $item_name = get_blog_option( $params['item_id'], 'blogname' );
 344                  break;
 345  
 346              case 'group' :
 347                  $item_name = bp_get_group_name( groups_get_group( $params['item_id'] ) );
 348                  break;
 349  
 350              case 'user'  :
 351              default :
 352                  $item_name = bp_core_get_user_displayname( $params['item_id'] );
 353                  break;
 354          }
 355  
 356          /**
 357           * Filters the alt attribute value to be applied to avatar.
 358           *
 359           * @since 1.5.0
 360           *
 361           * @param string $value  alt to be applied to avatar.
 362           * @param string $value  ID of avatar item being requested.
 363           * @param string $value  Avatar type being requested.
 364           * @param array  $params Array of parameters for the request.
 365           */
 366          $item_name = apply_filters( 'bp_core_avatar_alt', $item_name, $params['item_id'], $params['object'], $params );
 367          $params['alt'] = sprintf( $params['alt'], $item_name );
 368      }
 369  
 370      /* Sanity Checks *********************************************************/
 371  
 372      // Get a fallback for the 'alt' parameter, create html output.
 373      if ( empty( $params['alt'] ) ) {
 374          $params['alt'] = __( 'Profile Photo', 'buddypress' );
 375      }
 376      $html_alt = ' alt="' . esc_attr( $params['alt'] ) . '"';
 377  
 378      // Filter image title and create html string.
 379      $html_title = '';
 380  
 381      /**
 382       * Filters the title attribute value to be applied to avatar.
 383       *
 384       * @since 1.5.0
 385       *
 386       * @param string $value  Title to be applied to avatar.
 387       * @param string $value  ID of avatar item being requested.
 388       * @param string $value  Avatar type being requested.
 389       * @param array  $params Array of parameters for the request.
 390       */
 391      $params['title'] = apply_filters( 'bp_core_avatar_title', $params['title'], $params['item_id'], $params['object'], $params );
 392  
 393      if ( ! empty( $params['title'] ) ) {
 394          $html_title = ' title="' . esc_attr( $params['title'] ) . '"';
 395      }
 396  
 397      // Extra attributes.
 398      $extra_attr = '';
 399      if ( ! empty( $params['extra_attr'] ) ) {
 400          $extra_attr = ' ' . $params['extra_attr'];
 401      }
 402  
 403      // Set CSS ID and create html string.
 404      $html_css_id = '';
 405  
 406      /**
 407       * Filters the ID attribute to be applied to avatar.
 408       *
 409       * @since 2.2.0
 410       *
 411       * @param string $value  ID to be applied to avatar.
 412       * @param string $value  ID of avatar item being requested.
 413       * @param string $value  Avatar type being requested.
 414       * @param array  $params Array of parameters for the request.
 415       */
 416      $params['css_id'] = apply_filters( 'bp_core_css_id', $params['css_id'], $params['item_id'], $params['object'], $params );
 417  
 418      if ( ! empty( $params['css_id'] ) ) {
 419          $html_css_id = ' id="' . esc_attr( $params['css_id'] ) . '"';
 420      }
 421  
 422      // Set image width.
 423      if ( false !== $params['width'] ) {
 424          // Width has been specified. No modification necessary.
 425      } elseif ( 'thumb' == $params['type'] ) {
 426          $params['width'] = bp_core_avatar_thumb_width();
 427      } else {
 428          $params['width'] = bp_core_avatar_full_width();
 429      }
 430      $html_width = ' width="' . $params['width'] . '"';
 431  
 432      // Set image height.
 433      if ( false !== $params['height'] ) {
 434          // Height has been specified. No modification necessary.
 435      } elseif ( 'thumb' == $params['type'] ) {
 436          $params['height'] = bp_core_avatar_thumb_height();
 437      } else {
 438          $params['height'] = bp_core_avatar_full_height();
 439      }
 440      $html_height = ' height="' . $params['height'] . '"';
 441  
 442      /**
 443       * Filters the classes to be applied to the avatar.
 444       *
 445       * @since 1.6.0
 446       *
 447       * @param array|string $value  Class(es) to be applied to the avatar.
 448       * @param string       $value  ID of the avatar item being requested.
 449       * @param string       $value  Avatar type being requested.
 450       * @param array        $params Array of parameters for the request.
 451       */
 452      $params['class'] = apply_filters( 'bp_core_avatar_class', $params['class'], $params['item_id'], $params['object'], $params );
 453  
 454      // Use an alias to leave the param unchanged.
 455      $avatar_classes = $params['class'];
 456      if ( ! is_array( $avatar_classes ) ) {
 457          $avatar_classes = explode( ' ', $avatar_classes );
 458      }
 459  
 460      // Merge classes.
 461      $avatar_classes = array_merge( $avatar_classes, array(
 462          $params['object'] . '-' . $params['item_id'] . '-avatar',
 463          'avatar-' . $params['width'],
 464      ) );
 465  
 466      // Sanitize each class.
 467      $avatar_classes = array_map( 'sanitize_html_class', $avatar_classes );
 468  
 469      // Populate the class attribute.
 470      $html_class = ' class="' . join( ' ', $avatar_classes ) . ' photo"';
 471  
 472      // Set img URL and DIR based on prepopulated constants.
 473      $avatar_loc        = new stdClass();
 474      $avatar_loc->path  = trailingslashit( bp_core_avatar_upload_path() );
 475      $avatar_loc->url   = trailingslashit( bp_core_avatar_url() );
 476  
 477      $avatar_loc->dir   = trailingslashit( $params['avatar_dir'] );
 478  
 479      /**
 480       * Filters the avatar folder directory URL.
 481       *
 482       * @since 1.1.0
 483       *
 484       * @param string $value Path to the avatar folder URL.
 485       * @param int    $value ID of the avatar item being requested.
 486       * @param string $value Avatar type being requested.
 487       * @param string $value Subdirectory where the requested avatar should be found.
 488       */
 489      $avatar_folder_url = apply_filters( 'bp_core_avatar_folder_url', ( $avatar_loc->url  . $avatar_loc->dir . $params['item_id'] ), $params['item_id'], $params['object'], $params['avatar_dir'] );
 490  
 491      /**
 492       * Filters the avatar folder directory path.
 493       *
 494       * @since 1.1.0
 495       *
 496       * @param string $value Path to the avatar folder directory.
 497       * @param int    $value ID of the avatar item being requested.
 498       * @param string $value Avatar type being requested.
 499       * @param string $value Subdirectory where the requested avatar should be found.
 500       */
 501      $avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', ( $avatar_loc->path . $avatar_loc->dir . $params['item_id'] ), $params['item_id'], $params['object'], $params['avatar_dir'] );
 502  
 503      /**
 504       * Look for uploaded avatar first. Use it if it exists.
 505       * Set the file names to search for, to select the full size
 506       * or thumbnail image.
 507       */
 508      $avatar_size              = ( 'full' == $params['type'] ) ? '-bpfull' : '-bpthumb';
 509      $legacy_user_avatar_name  = ( 'full' == $params['type'] ) ? '-avatar2' : '-avatar1';
 510      $legacy_group_avatar_name = ( 'full' == $params['type'] ) ? '-groupavatar-full' : '-groupavatar-thumb';
 511  
 512      // Check for directory.
 513      if ( ! $params['force_default'] && file_exists( $avatar_folder_dir ) ) {
 514  
 515          // Open directory.
 516          if ( $av_dir = opendir( $avatar_folder_dir ) ) {
 517  
 518              // Stash files in an array once to check for one that matches.
 519              $avatar_files = array();
 520              while ( false !== ( $avatar_file = readdir( $av_dir ) ) ) {
 521                  // Only add files to the array (skip directories).
 522                  if ( 2 < strlen( $avatar_file ) ) {
 523                      $avatar_files[] = $avatar_file;
 524                  }
 525              }
 526  
 527              // Check for array.
 528              if ( 0 < count( $avatar_files ) ) {
 529  
 530                  // Check for current avatar.
 531                  foreach( $avatar_files as $key => $value ) {
 532                      if ( strpos ( $value, $avatar_size )!== false ) {
 533                          $avatar_url = $avatar_folder_url . '/' . $avatar_files[$key];
 534                      }
 535                  }
 536  
 537                  // Legacy avatar check.
 538                  if ( !isset( $avatar_url ) ) {
 539                      foreach( $avatar_files as $key => $value ) {
 540                          if ( strpos ( $value, $legacy_user_avatar_name )!== false ) {
 541                              $avatar_url = $avatar_folder_url . '/' . $avatar_files[$key];
 542                          }
 543                      }
 544  
 545                      // Legacy group avatar check.
 546                      if ( !isset( $avatar_url ) ) {
 547                          foreach( $avatar_files as $key => $value ) {
 548                              if ( strpos ( $value, $legacy_group_avatar_name )!== false ) {
 549                                  $avatar_url = $avatar_folder_url . '/' . $avatar_files[$key];
 550                              }
 551                          }
 552                      }
 553                  }
 554              }
 555          }
 556  
 557          // Close the avatar directory.
 558          closedir( $av_dir );
 559  
 560          // If we found a locally uploaded avatar.
 561          if ( isset( $avatar_url ) ) {
 562              // Support custom scheme.
 563              $avatar_url = set_url_scheme( $avatar_url, $params['scheme'] );
 564  
 565              // Return it wrapped in an <img> element.
 566              if ( true === $params['html'] ) {
 567  
 568                  /**
 569                   * Filters an avatar URL wrapped in an <img> element.
 570                   *
 571                   * @since 1.1.0
 572                   *
 573                   * @param string $value             Full <img> element for an avatar.
 574                   * @param array  $params            Array of parameters for the request.
 575                   * @param string $value             ID of the item requested.
 576                   * @param string $value             Subdirectory where the requested avatar should be found.
 577                   * @param string $html_css_id       ID attribute for avatar.
 578                   * @param string $html_width        Width attribute for avatar.
 579                   * @param string $html_height       Height attribute for avatar.
 580                   * @param string $avatar_folder_url Avatar URL path.
 581                   * @param string $avatar_folder_dir Avatar DIR path.
 582                   */
 583                  return apply_filters( 'bp_core_fetch_avatar', '<img src="' . $avatar_url . '"' . $html_class . $html_css_id  . $html_width . $html_height . $html_alt . $html_title . $extra_attr . ' />', $params, $params['item_id'], $params['avatar_dir'], $html_css_id, $html_width, $html_height, $avatar_folder_url, $avatar_folder_dir );
 584  
 585              // ...or only the URL
 586              } else {
 587  
 588                  /**
 589                   * Filters a locally uploaded avatar URL.
 590                   *
 591                   * @since 1.2.5
 592                   *
 593                   * @param string $avatar_url URL for a locally uploaded avatar.
 594                   * @param array  $params     Array of parameters for the request.
 595                   */
 596                  return apply_filters( 'bp_core_fetch_avatar_url', $avatar_url, $params );
 597              }
 598          }
 599      }
 600  
 601      // By default, Gravatar is not pinged for groups.
 602      if ( null === $params['no_grav'] ) {
 603          $params['no_grav'] = 'group' === $params['object'];
 604      }
 605  
 606      /**
 607       * Filters whether or not to skip Gravatar check.
 608       *
 609       * @since 1.5.0
 610       *
 611       * @param bool  $value  Whether or not to skip Gravatar.
 612       * @param array $params Array of parameters for the avatar request.
 613       */
 614      if ( ! apply_filters( 'bp_core_fetch_avatar_no_grav', $params['no_grav'], $params ) ) {
 615  
 616          // Set gravatar type.
 617          if ( empty( $bp->grav_default->{$params['object']} ) ) {
 618              $default_grav = 'wavatar';
 619          } elseif ( 'mystery' == $bp->grav_default->{$params['object']} ) {
 620  
 621              /**
 622               * Filters the Mystery person avatar src value.
 623               *
 624               * @since 1.2.0
 625               *
 626               * @param string $value Avatar value.
 627               * @param string $value Width to display avatar at.
 628               */
 629              $default_grav = apply_filters( 'bp_core_mysteryman_src', 'mm', $params['width'] );
 630          } else {
 631              $default_grav = $bp->grav_default->{$params['object']};
 632          }
 633  
 634          // Set gravatar object.
 635          if ( empty( $params['email'] ) ) {
 636              if ( 'user' == $params['object'] ) {
 637                  $params['email'] = bp_core_get_user_email( $params['item_id'] );
 638              } elseif ( 'group' == $params['object'] || 'blog' == $params['object'] ) {
 639                  $params['email'] = $params['item_id'] . '-' . $params['object'] . '@' . bp_get_root_domain();
 640              }
 641          }
 642  
 643          /**
 644           * Filters the Gravatar email to use.
 645           *
 646           * @since 1.1.0
 647           *
 648           * @param string $value Email to use in Gravatar request.
 649           * @param string $value ID of the item being requested.
 650           * @param string $value Object type being requested.
 651           */
 652          $params['email'] = apply_filters( 'bp_core_gravatar_email', $params['email'], $params['item_id'], $params['object'] );
 653  
 654          /**
 655           * Filters the Gravatar URL host.
 656           *
 657           * @since 1.0.2
 658           *
 659           * @param string $value Gravatar URL host.
 660           */
 661          $gravatar = apply_filters( 'bp_gravatar_url', '//www.gravatar.com/avatar/' );
 662  
 663          // Append email hash to Gravatar.
 664          $gravatar .=  md5( strtolower( $params['email'] ) );
 665  
 666          // Main Gravatar URL args.
 667          $url_args = array(
 668              's' => $params['width']
 669          );
 670  
 671          // Custom Gravatar URL args.
 672          if ( ! empty( $params['force_default'] ) ) {
 673              $url_args['f'] = 'y';
 674              $url_args['d'] = $params['default'];
 675          }
 676          if ( ! empty( $params['rating'] ) ) {
 677              $url_args['r'] = strtolower( $params['rating'] );
 678          }
 679  
 680          /** This filter is documented in wp-includes/deprecated.php */
 681          $d = apply_filters_deprecated(
 682              'bp_core_avatar_default',
 683              array( $default_grav, $params ),
 684              '8.0.0',
 685              'bp_core_avatar_gravatar_default||bp_core_default_avatar',
 686              __( 'This filter was used for 2 different purposes. If your goal was to filter the default *Gravatar*, please use `bp_core_avatar_gravatar_default` instead. Otherwise, please use `bp_core_default_avatar` instead.', 'buddypress' )
 687          );
 688  
 689          if ( bp_core_is_default_gravatar( $d ) ) {
 690              $default_grav = $d;
 691          }
 692  
 693          /**
 694           * Filters the Gravatar "d" parameter.
 695           *
 696           * @since 2.6.0
 697           * @since 8.0.0 The name of the filter was changed to `bp_core_avatar_gravatar_default`.
 698           *
 699           * @param string $default_grav The avatar default.
 700           * @param array  $params       The avatar's data.
 701           */
 702          $default_grav = apply_filters( 'bp_core_avatar_gravatar_default', $default_grav, $params );
 703  
 704          // Only set default image if 'Gravatar Logo' is not requested.
 705          if ( ! $params['force_default'] && 'gravatar_default' !== $default_grav ) {
 706              $url_args['d'] = $default_grav;
 707          }
 708  
 709          // Set up the Gravatar URL.
 710          $gravatar = esc_url( add_query_arg(
 711              rawurlencode_deep( array_filter( $url_args ) ),
 712              $gravatar
 713          ) );
 714  
 715      // No avatar was found, and we've been told not to use a gravatar.
 716      } else {
 717  
 718          /**
 719           * Filters the avatar default when Gravatar is not used.
 720           *
 721           * This is a variable filter dependent on the avatar type being requested.
 722           *
 723           * @since 1.5.0
 724           *
 725           * @param string $value  Default avatar for non-gravatar requests.
 726           * @param array  $params Array of parameters for the avatar request.
 727           */
 728          $gravatar = apply_filters( 'bp_core_default_avatar_' . $params['object'], bp_core_avatar_default( 'local', $params ), $params );
 729      }
 730  
 731      if ( true === $params['html'] ) {
 732  
 733          /** This filter is documented in bp-core/bp-core-avatars.php */
 734          return apply_filters( 'bp_core_fetch_avatar', '<img src="' . $gravatar . '"' . $html_css_id . $html_class . $html_width . $html_height . $html_alt . $html_title . $extra_attr . ' />', $params, $params['item_id'], $params['avatar_dir'], $html_css_id, $html_width, $html_height, $avatar_folder_url, $avatar_folder_dir );
 735      } else {
 736  
 737          /** This filter is documented in bp-core/bp-core-avatars.php */
 738          return apply_filters( 'bp_core_fetch_avatar_url', $gravatar, $params );
 739      }
 740  }
 741  
 742  /**
 743   * Delete an existing avatar.
 744   *
 745   * @since 1.1.0
 746   *
 747   * @param array|string $args {
 748   *     Array of function parameters.
 749   *     @type bool|int    $item_id    ID of the item whose avatar you're deleting.
 750   *                                   Defaults to the current item of type $object.
 751   *     @type string      $object     Object type of the item whose avatar you're
 752   *                                   deleting. 'user', 'group', 'blog', or custom.
 753   *                                   Default: 'user'.
 754   *     @type bool|string $avatar_dir Subdirectory where avatar is located.
 755   *                                   Default: false, which falls back on the default location
 756   *                                   corresponding to the $object.
 757   * }
 758   * @return bool True on success, false on failure.
 759   */
 760  function bp_core_delete_existing_avatar( $args = '' ) {
 761  
 762      $defaults = array(
 763          'item_id'    => false,
 764          'object'     => 'user', // User OR group OR blog OR custom type (if you use filters).
 765          'avatar_dir' => false
 766      );
 767  
 768      $args = wp_parse_args( $args, $defaults );
 769  
 770      /**
 771       * Filters whether or not to handle deleting an existing avatar.
 772       *
 773       * If you want to override this function, make sure you return false.
 774       *
 775       * @since 2.5.1
 776       *
 777       * @param bool  $value Whether or not to delete the avatar.
 778       * @param array $args {
 779       *     Array of function parameters.
 780       *
 781       *     @type bool|int    $item_id    ID of the item whose avatar you're deleting.
 782       *                                   Defaults to the current item of type $object.
 783       *     @type string      $object     Object type of the item whose avatar you're
 784       *                                   deleting. 'user', 'group', 'blog', or custom.
 785       *                                   Default: 'user'.
 786       *     @type bool|string $avatar_dir Subdirectory where avatar is located.
 787       *                                   Default: false, which falls back on the default location
 788       *                                   corresponding to the $object.
 789       * }
 790       */
 791      if ( ! apply_filters( 'bp_core_pre_delete_existing_avatar', true, $args ) ) {
 792          return true;
 793      }
 794  
 795      if ( empty( $args['item_id'] ) ) {
 796          if ( 'user' === $args['object'] ) {
 797              $args['item_id'] = bp_displayed_user_id();
 798          } elseif ( 'group' === $args['object'] ) {
 799              $args['item_id'] = buddypress()->groups->current_group->id;
 800          } elseif ( 'blog' === $args['object'] ) {
 801              $args['item_id'] = get_current_blog_id();
 802          }
 803  
 804          /** This filter is documented in bp-core/bp-core-avatars.php */
 805          $item_id = apply_filters( 'bp_core_avatar_item_id', $args['item_id'], $args['object'] );
 806      } else {
 807          $item_id = $args['item_id'];
 808      }
 809  
 810      if ( $item_id && ( ctype_digit( $item_id ) || is_int( $item_id ) ) ) {
 811          $item_id = (int) $item_id;
 812      } else {
 813          return false;
 814      }
 815  
 816      if ( empty( $args['avatar_dir'] ) ) {
 817          if ( 'user' === $args['object'] ) {
 818              $args['avatar_dir'] = 'avatars';
 819          } elseif ( 'group' === $args['object'] ) {
 820              $args['avatar_dir'] = 'group-avatars';
 821          } elseif ( 'blog' === $args['object'] ) {
 822              $args['avatar_dir'] = 'blog-avatars';
 823          }
 824  
 825          /** This filter is documented in bp-core/bp-core-avatars.php */
 826          $avatar_dir = apply_filters( 'bp_core_avatar_dir', $args['avatar_dir'], $args['object'] );
 827      } else {
 828          $avatar_dir = $args['avatar_dir'];
 829      }
 830  
 831      if ( ! $avatar_dir ) {
 832          return false;
 833      }
 834  
 835      /** This filter is documented in bp-core/bp-core-avatars.php */
 836      $avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', bp_core_avatar_upload_path() . '/' . $avatar_dir . '/' . $item_id, $item_id, $args['object'], $avatar_dir );
 837  
 838      if ( ! is_dir( $avatar_folder_dir ) ) {
 839          return false;
 840      }
 841  
 842      if ( $av_dir = opendir( $avatar_folder_dir ) ) {
 843          while ( false !== ( $avatar_file = readdir( $av_dir ) ) ) {
 844              if ( ( preg_match( "/-bpfull/", $avatar_file ) || preg_match( "/-bpthumb/", $avatar_file ) ) && '.' != $avatar_file && '..' != $avatar_file ) {
 845                  @unlink( $avatar_folder_dir . '/' . $avatar_file );
 846              }
 847          }
 848      }
 849      closedir( $av_dir );
 850  
 851      @rmdir( $avatar_folder_dir );
 852  
 853      /**
 854       * Fires after deleting an existing avatar.
 855       *
 856       * @since 1.1.0
 857       *
 858       * @param array $args Array of arguments used for avatar deletion.
 859       */
 860      do_action( 'bp_core_delete_existing_avatar', $args );
 861  
 862      return true;
 863  }
 864  
 865  /**
 866   * Ajax delete an avatar for a given object and item id.
 867   *
 868   * @since 2.3.0
 869   *
 870   * @return string|null A JSON object containing success data if the avatar was deleted,
 871   *                     error message otherwise.
 872   */
 873  function bp_avatar_ajax_delete() {
 874      if ( ! bp_is_post_request() ) {
 875          wp_send_json_error();
 876      }
 877  
 878      $avatar_data = $_POST;
 879  
 880      if ( empty( $avatar_data['object'] ) || empty( $avatar_data['item_id'] ) ) {
 881          wp_send_json_error();
 882      }
 883  
 884      $nonce = 'bp_delete_avatar_link';
 885      if ( 'group' === $avatar_data['object'] ) {
 886          $nonce = 'bp_group_avatar_delete';
 887      }
 888  
 889      // Check the nonce.
 890      check_admin_referer( $nonce, 'nonce' );
 891  
 892      // Capability check.
 893      if ( ! bp_attachments_current_user_can( 'edit_avatar', $avatar_data ) ) {
 894          wp_send_json_error();
 895      }
 896  
 897      // Handle delete.
 898      if ( bp_core_delete_existing_avatar( array( 'item_id' => $avatar_data['item_id'], 'object' => $avatar_data['object'] ) ) ) {
 899          $return = array(
 900              'avatar' => esc_url( bp_core_fetch_avatar( array(
 901                  'object'  => $avatar_data['object'],
 902                  'item_id' => $avatar_data['item_id'],
 903                  'html'    => false,
 904                  'type'    => 'full',
 905              ) ) ),
 906              'feedback_code' => 4,
 907              'item_id'       => $avatar_data['item_id'],
 908          );
 909  
 910          wp_send_json_success( $return );
 911      } else {
 912          wp_send_json_error( array(
 913              'feedback_code' => 3,
 914          ) );
 915      }
 916  }
 917  add_action( 'wp_ajax_bp_avatar_delete', 'bp_avatar_ajax_delete' );
 918  
 919  /**
 920   * Handle avatar uploading.
 921   *
 922   * The functions starts off by checking that the file has been uploaded
 923   * properly using bp_core_check_avatar_upload(). It then checks that the file
 924   * size is within limits, and that it has an accepted file extension (jpg, gif,
 925   * png). If everything checks out, crop the image and move it to its real
 926   * location.
 927   *
 928   * @since 1.1.0
 929   *
 930   * @see bp_core_check_avatar_upload()
 931   * @see bp_core_check_avatar_type()
 932   *
 933   * @param array  $file              The appropriate entry the from $_FILES superglobal.
 934   * @param string $upload_dir_filter A filter to be applied to 'upload_dir'.
 935   * @return bool True on success, false on failure.
 936   */
 937  function bp_core_avatar_handle_upload( $file, $upload_dir_filter ) {
 938  
 939      /**
 940       * Filters whether or not to handle uploading.
 941       *
 942       * If you want to override this function, make sure you return false.
 943       *
 944       * @since 1.2.4
 945       *
 946       * @param bool   $value             Whether or not to crop.
 947       * @param array  $file              Appropriate entry from $_FILES superglobal.
 948       * @parma string $upload_dir_filter A filter to be applied to 'upload_dir'.
 949       */
 950      if ( ! apply_filters( 'bp_core_pre_avatar_handle_upload', true, $file, $upload_dir_filter ) ) {
 951          return true;
 952      }
 953  
 954      // Setup some variables.
 955      $bp          = buddypress();
 956      $upload_path = bp_core_avatar_upload_path();
 957  
 958      // Upload the file.
 959      $avatar_attachment = new BP_Attachment_Avatar();
 960      $bp->avatar_admin->original = $avatar_attachment->upload( $file, $upload_dir_filter );
 961  
 962      // In case of an error, stop the process and display a feedback to the user.
 963      if ( ! empty( $bp->avatar_admin->original['error'] ) ) {
 964          /* translators: %s: the upload error message */
 965          bp_core_add_message( sprintf( __( 'Upload Failed! Error was: %s', 'buddypress' ), $bp->avatar_admin->original['error'] ), 'error' );
 966          return false;
 967      }
 968  
 969      // The Avatar UI available width.
 970      $ui_available_width = 0;
 971  
 972      // Try to set the ui_available_width using the avatar_admin global.
 973      if ( isset( $bp->avatar_admin->ui_available_width ) ) {
 974          $ui_available_width = $bp->avatar_admin->ui_available_width;
 975      }
 976  
 977      // Maybe resize.
 978      $bp->avatar_admin->resized = $avatar_attachment->shrink( $bp->avatar_admin->original['file'], $ui_available_width );
 979      $bp->avatar_admin->image   = new stdClass();
 980  
 981      // We only want to handle one image after resize.
 982      if ( empty( $bp->avatar_admin->resized ) || is_wp_error( $bp->avatar_admin->resized ) ) {
 983          $bp->avatar_admin->image->file = $bp->avatar_admin->original['file'];
 984          $bp->avatar_admin->image->dir  = str_replace( $upload_path, '', $bp->avatar_admin->original['file'] );
 985      } else {
 986          $bp->avatar_admin->image->file = $bp->avatar_admin->resized['path'];
 987          $bp->avatar_admin->image->dir  = str_replace( $upload_path, '', $bp->avatar_admin->resized['path'] );
 988          @unlink( $bp->avatar_admin->original['file'] );
 989      }
 990  
 991      // Check for WP_Error on what should be an image.
 992      if ( is_wp_error( $bp->avatar_admin->image->dir ) ) {
 993          /* translators: %s: the upload error message */
 994          bp_core_add_message( sprintf( __( 'Upload failed! Error was: %s', 'buddypress' ), $bp->avatar_admin->image->dir->get_error_message() ), 'error' );
 995          return false;
 996      }
 997  
 998      // If the uploaded image is smaller than the "full" dimensions, throw a warning.
 999      if ( $avatar_attachment->is_too_small( $bp->avatar_admin->image->file ) ) {
1000          /* translators: 1: the advised width size in pixels. 2: the advised height size in pixels. */
1001          bp_core_add_message( sprintf( __( 'You have selected an image that is smaller than recommended. For best results, upload a picture larger than %1$d x %2$d pixels.', 'buddypress' ), bp_core_avatar_full_width(), bp_core_avatar_full_height() ), 'error' );
1002      }
1003  
1004      // Set the url value for the image.
1005      $bp->avatar_admin->image->url = bp_core_avatar_url() . $bp->avatar_admin->image->dir;
1006  
1007      return true;
1008  }
1009  
1010  /**
1011   * Ajax upload an avatar.
1012   *
1013   * @since 2.3.0
1014   *
1015   * @return string|null A JSON object containing success data if the upload succeeded
1016   *                     error message otherwise.
1017   */
1018  function bp_avatar_ajax_upload() {
1019      if ( ! bp_is_post_request() ) {
1020          wp_die();
1021      }
1022  
1023      /**
1024       * Sending the json response will be different if
1025       * the current Plupload runtime is html4.
1026       */
1027      $is_html4 = false;
1028      if ( ! empty( $_POST['html4' ] ) ) {
1029          $is_html4 = true;
1030      }
1031  
1032      // Check the nonce.
1033      check_admin_referer( 'bp-uploader' );
1034  
1035      // Init the BuddyPress parameters.
1036      $bp_params = array();
1037  
1038      // We need it to carry on.
1039      if ( ! empty( $_POST['bp_params' ] ) ) {
1040          $bp_params = $_POST['bp_params' ];
1041      } else {
1042          bp_attachments_json_response( false, $is_html4 );
1043      }
1044  
1045      // We need the object to set the uploads dir filter.
1046      if ( empty( $bp_params['object'] ) ) {
1047          bp_attachments_json_response( false, $is_html4 );
1048      }
1049  
1050      // Capability check.
1051      if ( ! bp_attachments_current_user_can( 'edit_avatar', $bp_params ) ) {
1052          bp_attachments_json_response( false, $is_html4 );
1053      }
1054  
1055      $bp = buddypress();
1056      $bp_params['upload_dir_filter'] = '';
1057      $needs_reset = array();
1058  
1059      if ( 'user' === $bp_params['object'] && bp_is_active( 'members' ) ) {
1060          $bp_params['upload_dir_filter'] = 'bp_members_avatar_upload_dir';
1061  
1062          if ( ! bp_displayed_user_id() && ! empty( $bp_params['item_id'] ) ) {
1063              $needs_reset = array( 'key' => 'displayed_user', 'value' => $bp->displayed_user );
1064              $bp->displayed_user->id = $bp_params['item_id'];
1065          }
1066      } elseif ( 'group' === $bp_params['object'] && bp_is_active( 'groups' ) ) {
1067          $bp_params['upload_dir_filter'] = 'groups_avatar_upload_dir';
1068  
1069          if ( ! bp_get_current_group_id() && ! empty( $bp_params['item_id'] ) ) {
1070              $needs_reset = array( 'component' => 'groups', 'key' => 'current_group', 'value' => $bp->groups->current_group );
1071              $bp->groups->current_group = groups_get_group( $bp_params['item_id'] );
1072          }
1073      } else {
1074          /**
1075           * Filter here to deal with other components.
1076           *
1077           * @since 2.3.0
1078           *
1079           * @var array $bp_params the BuddyPress Ajax parameters.
1080           */
1081          $bp_params = apply_filters( 'bp_core_avatar_ajax_upload_params', $bp_params );
1082      }
1083  
1084      if ( ! isset( $bp->avatar_admin ) ) {
1085          $bp->avatar_admin = new stdClass();
1086      }
1087  
1088      /**
1089       * The BuddyPress upload parameters is including the Avatar UI Available width,
1090       * add it to the avatar_admin global for a later use.
1091       */
1092      if ( isset( $bp_params['ui_available_width'] ) ) {
1093          $bp->avatar_admin->ui_available_width =  (int) $bp_params['ui_available_width'];
1094      }
1095  
1096      // Upload the avatar.
1097      $avatar = bp_core_avatar_handle_upload( $_FILES, $bp_params['upload_dir_filter'] );
1098  
1099      // Reset objects.
1100      if ( ! empty( $needs_reset ) ) {
1101          if ( ! empty( $needs_reset['component'] ) ) {
1102              $bp->{$needs_reset['component']}->{$needs_reset['key']} = $needs_reset['value'];
1103          } else {
1104              $bp->{$needs_reset['key']} = $needs_reset['value'];
1105          }
1106      }
1107  
1108      // Init the feedback message.
1109      $feedback_message = false;
1110  
1111      if ( ! empty( $bp->template_message ) ) {
1112          $feedback_message = $bp->template_message;
1113  
1114          // Remove template message.
1115          $bp->template_message      = false;
1116          $bp->template_message_type = false;
1117  
1118          @setcookie( 'bp-message', false, time() - 1000, COOKIEPATH, COOKIE_DOMAIN, is_ssl() );
1119          @setcookie( 'bp-message-type', false, time() - 1000, COOKIEPATH, COOKIE_DOMAIN, is_ssl() );
1120      }
1121  
1122      if ( empty( $avatar ) ) {
1123          // Default upload error.
1124          $message = __( 'Upload failed.', 'buddypress' );
1125  
1126          // Use the template message if set.
1127          if ( ! empty( $feedback_message ) ) {
1128              $message = $feedback_message;
1129          }
1130  
1131          // Upload error reply.
1132          bp_attachments_json_response( false, $is_html4, array(
1133              'type'    => 'upload_error',
1134              'message' => $message,
1135          ) );
1136      }
1137  
1138      if ( empty( $bp->avatar_admin->image->file ) ) {
1139          bp_attachments_json_response( false, $is_html4 );
1140      }
1141  
1142      $uploaded_image = @getimagesize( $bp->avatar_admin->image->file );
1143  
1144      // Set the name of the file.
1145      $name = $_FILES['file']['name'];
1146      $name_parts = pathinfo( $name );
1147      $name = trim( substr( $name, 0, - ( 1 + strlen( $name_parts['extension'] ) ) ) );
1148  
1149      // Finally return the avatar to the editor.
1150      bp_attachments_json_response( true, $is_html4, array(
1151          'name'      => $name,
1152          'url'       => $bp->avatar_admin->image->url,
1153          'width'     => $uploaded_image[0],
1154          'height'    => $uploaded_image[1],
1155          'feedback'  => $feedback_message,
1156      ) );
1157  }
1158  add_action( 'wp_ajax_bp_avatar_upload', 'bp_avatar_ajax_upload' );
1159  
1160  /**
1161   * Handle avatar webcam capture.
1162   *
1163   * @since 2.3.0
1164   *
1165   * @param string $data    Base64 encoded image.
1166   * @param int    $item_id Item to associate.
1167   * @return bool True on success, false on failure.
1168   */
1169  function bp_avatar_handle_capture( $data = '', $item_id = 0 ) {
1170      if ( empty( $data ) || empty( $item_id ) ) {
1171          return false;
1172      }
1173  
1174      /**
1175       * Filters whether or not to handle avatar webcam capture.
1176       *
1177       * If you want to override this function, make sure you return false.
1178       *
1179       * @since 2.5.1
1180       *
1181       * @param bool   $value   Whether or not to crop.
1182       * @param string $data    Base64 encoded image.
1183       * @param int    $item_id Item to associate.
1184       */
1185      if ( ! apply_filters( 'bp_avatar_pre_handle_capture', true, $data, $item_id ) ) {
1186          return true;
1187      }
1188  
1189      $avatar_dir = bp_core_avatar_upload_path() . '/avatars';
1190  
1191      // It's not a regular upload, we may need to create this folder.
1192      if ( ! file_exists( $avatar_dir ) ) {
1193          if ( ! wp_mkdir_p( $avatar_dir ) ) {
1194              return false;
1195          }
1196      }
1197  
1198      /**
1199       * Filters the Avatar folder directory.
1200       *
1201       * @since 2.3.0
1202       *
1203       * @param string $avatar_dir Directory for storing avatars.
1204       * @param int    $item_id    ID of the item being acted on.
1205       * @param string $value      Avatar type.
1206       * @param string $value      Avatars word.
1207       */
1208      $avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', $avatar_dir . '/' . $item_id, $item_id, 'user', 'avatars' );
1209  
1210      // It's not a regular upload, we may need to create this folder.
1211      if( ! is_dir( $avatar_folder_dir ) ) {
1212          if ( ! wp_mkdir_p( $avatar_folder_dir ) ) {
1213              return false;
1214          }
1215      }
1216  
1217      $original_file = $avatar_folder_dir . '/webcam-capture-' . $item_id . '.png';
1218  
1219      if ( file_put_contents( $original_file, $data ) ) {
1220          $avatar_to_crop = str_replace( bp_core_avatar_upload_path(), '', $original_file );
1221  
1222          // Crop to default values.
1223          $crop_args = array( 'item_id' => $item_id, 'original_file' => $avatar_to_crop, 'crop_x' => 0, 'crop_y' => 0 );
1224  
1225          return bp_core_avatar_handle_crop( $crop_args );
1226      } else {
1227          return false;
1228      }
1229  }
1230  
1231  /**
1232   * Crop an uploaded avatar.
1233   *
1234   * @since 1.1.0
1235   *
1236   * @param array|string $args {
1237   *     Array of function parameters.
1238   *
1239   *     @type string      $object        Object type of the item whose avatar you're
1240   *                                      handling. 'user', 'group', 'blog', or custom.
1241   *                                      Default: 'user'.
1242   *     @type string      $avatar_dir    Subdirectory where avatar should be stored.
1243   *                                      Default: 'avatars'.
1244   *     @type bool|int    $item_id       ID of the item that the avatar belongs to.
1245   *     @type bool|string $original_file Absolute path to the original avatar file.
1246   *     @type int         $crop_w        Crop width. Default: the global 'full' avatar width,
1247   *                                      as retrieved by bp_core_avatar_full_width().
1248   *     @type int         $crop_h        Crop height. Default: the global 'full' avatar height,
1249   *                                      as retrieved by bp_core_avatar_full_height().
1250   *     @type int         $crop_x        The horizontal starting point of the crop. Default: 0.
1251   *     @type int         $crop_y        The vertical starting point of the crop. Default: 0.
1252   * }
1253   * @return bool True on success, false on failure.
1254   */
1255  function bp_core_avatar_handle_crop( $args = '' ) {
1256  
1257      $r = wp_parse_args( $args, array(
1258          'object'        => 'user',
1259          'avatar_dir'    => 'avatars',
1260          'item_id'       => false,
1261          'original_file' => false,
1262          'crop_w'        => bp_core_avatar_full_width(),
1263          'crop_h'        => bp_core_avatar_full_height(),
1264          'crop_x'        => 0,
1265          'crop_y'        => 0
1266      ) );
1267  
1268      /**
1269       * Filters whether or not to handle cropping.
1270       *
1271       * If you want to override this function, make sure you return false.
1272       *
1273       * @since 1.2.4
1274       *
1275       * @param bool  $value Whether or not to crop.
1276       * @param array $r     Array of parsed arguments for function.
1277       */
1278      if ( ! apply_filters( 'bp_core_pre_avatar_handle_crop', true, $r ) ) {
1279          return true;
1280      }
1281  
1282      // Crop the file.
1283      $avatar_attachment = new BP_Attachment_Avatar();
1284      $cropped           = $avatar_attachment->crop( $r );
1285  
1286      // Check for errors.
1287      if ( empty( $cropped['full'] ) || empty( $cropped['thumb'] ) || is_wp_error( $cropped['full'] ) || is_wp_error( $cropped['thumb'] ) ) {
1288          return false;
1289      }
1290  
1291      return true;
1292  }
1293  
1294  /**
1295   * Ajax set an avatar for a given object and item id.
1296   *
1297   * @since 2.3.0
1298   *
1299   * @return string|null A JSON object containing success data if the crop/capture succeeded
1300   *                     error message otherwise.
1301   */
1302  function bp_avatar_ajax_set() {
1303      if ( ! bp_is_post_request() ) {
1304          wp_send_json_error();
1305      }
1306  
1307      // Check the nonce.
1308      check_admin_referer( 'bp_avatar_cropstore', 'nonce' );
1309  
1310      $avatar_data = wp_parse_args( $_POST, array(
1311          'crop_w' => bp_core_avatar_full_width(),
1312          'crop_h' => bp_core_avatar_full_height(),
1313          'crop_x' => 0,
1314          'crop_y' => 0
1315      ) );
1316  
1317      if ( empty( $avatar_data['object'] ) || empty( $avatar_data['item_id'] ) || empty( $avatar_data['original_file'] ) ) {
1318          wp_send_json_error();
1319      }
1320  
1321      // Capability check.
1322      if ( ! bp_attachments_current_user_can( 'edit_avatar', $avatar_data ) ) {
1323          wp_send_json_error();
1324      }
1325  
1326      if ( ! empty( $avatar_data['type'] ) && 'camera' === $avatar_data['type'] && 'user' === $avatar_data['object'] ) {
1327          $webcam_avatar = false;
1328  
1329          if ( ! empty( $avatar_data['original_file'] ) ) {
1330              $webcam_avatar = str_replace( array( 'data:image/png;base64,', ' ' ), array( '', '+' ), $avatar_data['original_file'] );
1331              $webcam_avatar = base64_decode( $webcam_avatar );
1332          }
1333  
1334          if ( ! bp_avatar_handle_capture( $webcam_avatar, $avatar_data['item_id'] ) ) {
1335              wp_send_json_error( array(
1336                  'feedback_code' => 1
1337              ) );
1338  
1339          } else {
1340              $return = array(
1341                  'avatar' => esc_url( bp_core_fetch_avatar( array(
1342                      'object'  => $avatar_data['object'],
1343                      'item_id' => $avatar_data['item_id'],
1344                      'html'    => false,
1345                      'type'    => 'full',
1346                  ) ) ),
1347                  'feedback_code' => 2,
1348                  'item_id'       => $avatar_data['item_id'],
1349              );
1350  
1351              /** This action is documented in wp-includes/deprecated.php */
1352              do_action_deprecated( 'xprofile_avatar_uploaded', array( (int) $avatar_data['item_id'], $avatar_data['type'], $avatar_data ), '6.0.0', 'bp_members_avatar_uploaded' );
1353  
1354              /**
1355               * Fires if the new avatar was successfully captured.
1356               *
1357               * @since 6.0.0
1358               *
1359               * @param string $item_id     Inform about the user id the avatar was set for.
1360               * @param string $type        Inform about the way the avatar was set ('camera').
1361               * @param array  $avatar_data Array of parameters passed to the avatar handler.
1362               */
1363              do_action( 'bp_members_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'], $avatar_data );
1364  
1365              wp_send_json_success( $return );
1366          }
1367  
1368          return;
1369      }
1370  
1371      $original_file = str_replace( bp_core_avatar_url(), '', $avatar_data['original_file'] );
1372  
1373      // Set avatars dir & feedback part.
1374      if ( 'user' === $avatar_data['object'] ) {
1375          $avatar_dir = 'avatars';
1376  
1377      // Defaults to object-avatars dir.
1378      } else {
1379          $avatar_dir = sanitize_key( $avatar_data['object'] ) . '-avatars';
1380      }
1381  
1382      // Crop args.
1383      $r = array(
1384          'item_id'       => $avatar_data['item_id'],
1385          'object'        => $avatar_data['object'],
1386          'avatar_dir'    => $avatar_dir,
1387          'original_file' => $original_file,
1388          'crop_w'        => $avatar_data['crop_w'],
1389          'crop_h'        => $avatar_data['crop_h'],
1390          'crop_x'        => $avatar_data['crop_x'],
1391          'crop_y'        => $avatar_data['crop_y']
1392      );
1393  
1394      // Handle crop.
1395      if ( bp_core_avatar_handle_crop( $r ) ) {
1396          $return = array(
1397              'avatar' => esc_url( bp_core_fetch_avatar( array(
1398                  'object'  => $avatar_data['object'],
1399                  'item_id' => $avatar_data['item_id'],
1400                  'html'    => false,
1401                  'type'    => 'full',
1402              ) ) ),
1403              'feedback_code' => 2,
1404              'item_id'       => $avatar_data['item_id'],
1405          );
1406  
1407          if ( 'user' === $avatar_data['object'] ) {
1408              /** This action is documented in wp-includes/deprecated.php */
1409              do_action_deprecated( 'xprofile_avatar_uploaded', array( (int) $avatar_data['item_id'], $avatar_data['type'], $r ), '6.0.0', 'bp_members_avatar_uploaded' );
1410  
1411              /** This action is documented in bp-core/bp-core-avatars.php */
1412              do_action( 'bp_members_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'], $r );
1413          } elseif ( 'group' === $avatar_data['object'] ) {
1414              /** This action is documented in bp-groups/bp-groups-screens.php */
1415              do_action( 'groups_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'], $r );
1416          }
1417  
1418          wp_send_json_success( $return );
1419      } else {
1420          wp_send_json_error( array(
1421              'feedback_code' => 1,
1422          ) );
1423      }
1424  }
1425  add_action( 'wp_ajax_bp_avatar_set', 'bp_avatar_ajax_set' );
1426  
1427  /**
1428   * Filter {@link get_avatar_url()} to use the BuddyPress user avatar URL.
1429   *
1430   * @since 2.9.0
1431   *
1432   * @param  string $retval      The URL of the avatar.
1433   * @param  mixed  $id_or_email The Gravatar to retrieve. Accepts a user_id, gravatar md5 hash,
1434   *                             user email, WP_User object, WP_Post object, or WP_Comment object.
1435   * @param  array  $args        Arguments passed to get_avatar_data(), after processing.
1436   * @return string
1437   */
1438  function bp_core_get_avatar_data_url_filter( $retval, $id_or_email, $args ) {
1439      $user = null;
1440  
1441      // Ugh, hate duplicating code; process the user identifier.
1442      if ( is_numeric( $id_or_email ) ) {
1443          $user = get_user_by( 'id', absint( $id_or_email ) );
1444      } elseif ( $id_or_email instanceof WP_User ) {
1445          // User Object
1446          $user = $id_or_email;
1447      } elseif ( $id_or_email instanceof WP_Post ) {
1448          // Post Object
1449          $user = get_user_by( 'id', (int) $id_or_email->post_author );
1450      } elseif ( $id_or_email instanceof WP_Comment ) {
1451          if ( ! empty( $id_or_email->user_id ) ) {
1452              $user = get_user_by( 'id', (int) $id_or_email->user_id );
1453          }
1454      } elseif ( is_email( $id_or_email ) ) {
1455          $user = get_user_by( 'email', $id_or_email );
1456      }
1457  
1458      // No user, so bail.
1459      if ( false === $user instanceof WP_User ) {
1460          return $retval;
1461      }
1462  
1463      // Set BuddyPress-specific avatar args.
1464      $args['item_id'] = $user->ID;
1465      $args['html']    = false;
1466  
1467      // Use the 'full' type if size is larger than BP's thumb width.
1468      if ( (int) $args['size'] > bp_core_avatar_thumb_width() ) {
1469          $args['type'] = 'full';
1470      }
1471  
1472      // Get the BuddyPress avatar URL.
1473      if ( $bp_avatar = bp_core_fetch_avatar( $args ) ) {
1474          return $bp_avatar;
1475      }
1476  
1477      return $retval;
1478  }
1479  add_filter( 'get_avatar_url', 'bp_core_get_avatar_data_url_filter', 10, 3 );
1480  
1481  /**
1482   * Is the current avatar upload error-free?
1483   *
1484   * @since 1.0.0
1485   *
1486   * @param array $file The $_FILES array.
1487   * @return bool True if no errors are found. False if there are errors.
1488   */
1489  function bp_core_check_avatar_upload( $file ) {
1490      if ( isset( $file['error'] ) && $file['error'] )
1491          return false;
1492  
1493      return true;
1494  }
1495  
1496  /**
1497   * Is the file size of the current avatar upload permitted?
1498   *
1499   * @since 1.0.0
1500   *
1501   * @param array $file The $_FILES array.
1502   * @return bool True if the avatar is under the size limit, otherwise false.
1503   */
1504  function bp_core_check_avatar_size( $file ) {
1505      if ( $file['file']['size'] > bp_core_avatar_original_max_filesize() )
1506          return false;
1507  
1508      return true;
1509  }
1510  
1511  /**
1512   * Get allowed avatar types.
1513   *
1514   * @since 2.3.0
1515   *
1516   * @return array
1517   */
1518  function bp_core_get_allowed_avatar_types() {
1519      $allowed_types = bp_attachments_get_allowed_types( 'avatar' );
1520  
1521      /**
1522       * Filters the list of allowed image types.
1523       *
1524       * @since 2.3.0
1525       *
1526       * @param array $allowed_types List of image types.
1527       */
1528      $avatar_types = (array) apply_filters( 'bp_core_get_allowed_avatar_types', $allowed_types );
1529  
1530      if ( empty( $avatar_types ) ) {
1531          $avatar_types = $allowed_types;
1532      } else {
1533          $avatar_types = array_intersect( $allowed_types, $avatar_types );
1534      }
1535  
1536      return array_values( $avatar_types );
1537  }
1538  
1539  /**
1540   * Get allowed avatar mime types.
1541   *
1542   * @since 2.3.0
1543   *
1544   * @return array
1545   */
1546  function bp_core_get_allowed_avatar_mimes() {
1547      $allowed_types  = bp_core_get_allowed_avatar_types();
1548  
1549      return bp_attachments_get_allowed_mimes( 'avatar', $allowed_types );
1550  }
1551  
1552  /**
1553   * Does the current avatar upload have an allowed file type?
1554   *
1555   * Permitted file types are JPG, GIF and PNG.
1556   *
1557   * @since 1.0.0
1558   *
1559   * @param array $file The $_FILES array.
1560   * @return bool True if the file extension is permitted, otherwise false.
1561   */
1562  function bp_core_check_avatar_type( $file ) {
1563      return bp_attachments_check_filetype( $file['file']['tmp_name'], $file['file']['name'], bp_core_get_allowed_avatar_mimes() );
1564  }
1565  
1566  /**
1567   * Fetch data from the BP root blog's upload directory.
1568   *
1569   * @since 1.8.0
1570   *
1571   * @param string $type The variable we want to return from the $bp->avatars object.
1572   *                     Only 'upload_path' and 'url' are supported. Default: 'upload_path'.
1573   * @return string The avatar upload directory path.
1574   */
1575  function bp_core_get_upload_dir( $type = 'upload_path' ) {
1576      $bp = buddypress();
1577  
1578      switch ( $type ) {
1579          case 'upload_path' :
1580              $constant = 'BP_AVATAR_UPLOAD_PATH';
1581              $key      = 'basedir';
1582  
1583              break;
1584  
1585          case 'url' :
1586              $constant = 'BP_AVATAR_URL';
1587              $key      = 'baseurl';
1588  
1589              break;
1590  
1591          default :
1592              return false;
1593  
1594              break;
1595      }
1596  
1597      // See if the value has already been calculated and stashed in the $bp global.
1598      if ( isset( $bp->avatar->$type ) ) {
1599          $retval = $bp->avatar->$type;
1600      } else {
1601          // If this value has been set in a constant, just use that.
1602          if ( defined( $constant ) ) {
1603              $retval = constant( $constant );
1604          } else {
1605  
1606              // Use cached upload dir data if available.
1607              if ( ! empty( $bp->avatar->upload_dir ) ) {
1608                  $upload_dir = $bp->avatar->upload_dir;
1609  
1610              // No cache, so query for it.
1611              } else {
1612  
1613                  // Get upload directory information from current site.
1614                  $upload_dir = bp_upload_dir();
1615  
1616                  // Stash upload directory data for later use.
1617                  $bp->avatar->upload_dir = $upload_dir;
1618              }
1619  
1620              // Directory does not exist and cannot be created.
1621              if ( ! empty( $upload_dir['error'] ) ) {
1622                  $retval = '';
1623  
1624              } else {
1625                  $retval = $upload_dir[$key];
1626  
1627                  // If $key is 'baseurl', check to see if we're on SSL
1628                  // Workaround for WP13941, WP15928, WP19037.
1629                  if ( $key == 'baseurl' && is_ssl() ) {
1630                      $retval = str_replace( 'http://', 'https://', $retval );
1631                  }
1632              }
1633  
1634          }
1635  
1636          // Stash in $bp for later use.
1637          $bp->avatar->$type = $retval;
1638      }
1639  
1640      return $retval;
1641  }
1642  
1643  /**
1644   * Get the absolute upload path for the WP installation.
1645   *
1646   * @since 1.2.0
1647   *
1648   * @return string Absolute path to WP upload directory.
1649   */
1650  function bp_core_avatar_upload_path() {
1651  
1652      /**
1653       * Filters the absolute upload path for the WP installation.
1654       *
1655       * @since 1.2.0
1656       *
1657       * @param string $value Absolute upload path for the WP installation.
1658       */
1659      return apply_filters( 'bp_core_avatar_upload_path', bp_core_get_upload_dir() );
1660  }
1661  
1662  /**
1663   * Get the raw base URL for root site upload location.
1664   *
1665   * @since 1.2.0
1666   *
1667   * @return string Full URL to current upload location.
1668   */
1669  function bp_core_avatar_url() {
1670  
1671      /**
1672       * Filters the raw base URL for root site upload location.
1673       *
1674       * @since 1.2.0
1675       *
1676       * @param string $value Raw base URL for the root site upload location.
1677       */
1678      return apply_filters( 'bp_core_avatar_url', bp_core_get_upload_dir( 'url' ) );
1679  }
1680  
1681  /**
1682   * Check if a given user ID has an uploaded avatar.
1683   *
1684   * @since 1.0.0
1685   *
1686   * @param int $user_id ID of the user whose avatar is being checked.
1687   * @return bool True if the user has uploaded a local avatar. Otherwise false.
1688   */
1689  function bp_get_user_has_avatar( $user_id = 0 ) {
1690  
1691      if ( empty( $user_id ) )
1692          $user_id = bp_displayed_user_id();
1693  
1694      $retval = false;
1695      if ( bp_core_fetch_avatar( array( 'item_id' => $user_id, 'no_grav' => true, 'html' => false, 'type' => 'full' ) ) != bp_core_avatar_default( 'local' ) )
1696          $retval = true;
1697  
1698      /**
1699       * Filters whether or not a user has an uploaded avatar.
1700       *
1701       * @since 1.6.0
1702       *
1703       * @param bool $retval  Whether or not a user has an uploaded avatar.
1704       * @param int  $user_id ID of the user being checked.
1705       */
1706      return (bool) apply_filters( 'bp_get_user_has_avatar', $retval, $user_id );
1707  }
1708  
1709  /**
1710   * Utility function for fetching an avatar dimension setting.
1711   *
1712   * @since 1.5.0
1713   *
1714   * @param string $type   Dimension type you're fetching dimensions for. 'thumb'
1715   *                       or 'full'. Default: 'thumb'.
1716   * @param string $h_or_w Which dimension is being fetched. 'height' or 'width'.
1717   *                       Default: 'height'.
1718   * @return int|bool $dim The dimension.
1719   */
1720  function bp_core_avatar_dimension( $type = 'thumb', $h_or_w = 'height' ) {
1721      $bp  = buddypress();
1722      $dim = isset( $bp->avatar->{$type}->{$h_or_w} ) ? (int) $bp->avatar->{$type}->{$h_or_w} : false;
1723  
1724      /**
1725       * Filters the avatar dimension setting.
1726       *
1727       * @since 1.5.0
1728       *
1729       * @param int|bool $dim    Dimension setting for the type.
1730       * @param string   $type   The type of avatar whose dimensions are requested. Default 'thumb'.
1731       * @param string   $h_or_w The dimension parameter being requested. Default 'height'.
1732       */
1733      return apply_filters( 'bp_core_avatar_dimension', $dim, $type, $h_or_w );
1734  }
1735  
1736  /**
1737   * Get the 'thumb' avatar width setting.
1738   *
1739   * @since 1.5.0
1740   *
1741   * @return int The 'thumb' width.
1742   */
1743  function bp_core_avatar_thumb_width() {
1744  
1745      /**
1746       * Filters the 'thumb' avatar width setting.
1747       *
1748       * @since 1.5.0
1749       *
1750       * @param int $value Value for the 'thumb' avatar width setting.
1751       */
1752      return apply_filters( 'bp_core_avatar_thumb_width', bp_core_avatar_dimension( 'thumb', 'width' ) );
1753  }
1754  
1755  /**
1756   * Get the 'thumb' avatar height setting.
1757   *
1758   * @since 1.5.0
1759   *
1760   * @return int The 'thumb' height.
1761   */
1762  function bp_core_avatar_thumb_height() {
1763  
1764      /**
1765       * Filters the 'thumb' avatar height setting.
1766       *
1767       * @since 1.5.0
1768       *
1769       * @param int $value Value for the 'thumb' avatar height setting.
1770       */
1771      return apply_filters( 'bp_core_avatar_thumb_height', bp_core_avatar_dimension( 'thumb', 'height' ) );
1772  }
1773  
1774  /**
1775   * Get the 'full' avatar width setting.
1776   *
1777   * @since 1.5.0
1778   *
1779   * @return int The 'full' width.
1780   */
1781  function bp_core_avatar_full_width() {
1782  
1783      /**
1784       * Filters the 'full' avatar width setting.
1785       *
1786       * @since 1.5.0
1787       *
1788       * @param int $value Value for the 'full' avatar width setting.
1789       */
1790      return apply_filters( 'bp_core_avatar_full_width', bp_core_avatar_dimension( 'full', 'width' ) );
1791  }
1792  
1793  /**
1794   * Get the 'full' avatar height setting.
1795   *
1796   * @since 1.5.0
1797   *
1798   * @return int The 'full' height.
1799   */
1800  function bp_core_avatar_full_height() {
1801  
1802      /**
1803       * Filters the 'full' avatar height setting.
1804       *
1805       * @since 1.5.0
1806       *
1807       * @param int $value Value for the 'full' avatar height setting.
1808       */
1809      return apply_filters( 'bp_core_avatar_full_height', bp_core_avatar_dimension( 'full', 'height' ) );
1810  }
1811  
1812  /**
1813   * Get the max width for original avatar uploads.
1814   *
1815   * @since 1.5.0
1816   *
1817   * @return int The max width for original avatar uploads.
1818   */
1819  function bp_core_avatar_original_max_width() {
1820  
1821      /**
1822       * Filters the max width for original avatar uploads.
1823       *
1824       * @since 1.5.0
1825       *
1826       * @param int $value Value for the max width.
1827       */
1828      return apply_filters( 'bp_core_avatar_original_max_width', (int) buddypress()->avatar->original_max_width );
1829  }
1830  
1831  /**
1832   * Get the max filesize for original avatar uploads.
1833   *
1834   * @since 1.5.0
1835   *
1836   * @return int The max filesize for original avatar uploads.
1837   */
1838  function bp_core_avatar_original_max_filesize() {
1839  
1840      /**
1841       * Filters the max filesize for original avatar uploads.
1842       *
1843       * @since 1.5.0
1844       *
1845       * @param int $value Value for the max filesize.
1846       */
1847      return apply_filters( 'bp_core_avatar_original_max_filesize', (int) buddypress()->avatar->original_max_filesize );
1848  }
1849  
1850  /**
1851   * Get the URL of the 'full' default avatar.
1852   *
1853   * @since 1.5.0
1854   * @since 2.6.0 Introduced `$params` and `$object_type` parameters.
1855   *
1856   * @param string $type   'local' if the fallback should be the locally-hosted version
1857   *                       of the mystery person, 'gravatar' if the fallback should be
1858   *                       Gravatar's version. Default: 'gravatar'.
1859   * @param array  $params Parameters passed to bp_core_fetch_avatar().
1860   * @return string The URL of the default avatar.
1861   */
1862  function bp_core_avatar_default( $type = 'gravatar', $params = array() ) {
1863      // Local override.
1864      if ( defined( 'BP_AVATAR_DEFAULT' ) ) {
1865          $avatar = BP_AVATAR_DEFAULT;
1866  
1867      // Use the local default image.
1868      } elseif ( 'local' === $type ) {
1869          $size = '';
1870          if (
1871              ( isset( $params['type'] ) && 'thumb' === $params['type'] && bp_core_avatar_thumb_width() <= 50 ) ||
1872              ( isset( $params['width'] ) && $params['width'] <= 50 )
1873          ) {
1874  
1875              $size = '-50';
1876          }
1877  
1878          $avatar = buddypress()->plugin_url . "bp-core/images/mystery-man{$size}.jpg";
1879  
1880      // Use Gravatar's mystery person as fallback.
1881      } else {
1882          $size = '';
1883          if ( isset( $params['type'] ) && 'thumb' === $params['type'] ) {
1884              $size = bp_core_avatar_thumb_width();
1885          } else {
1886              $size = bp_core_avatar_full_width();
1887          }
1888          $avatar = '//www.gravatar.com/avatar/00000000000000000000000000000000?d=mm&amp;s=' . $size;
1889      }
1890  
1891      /** This filter is documented in wp-includes/deprecated.php */
1892      $a = apply_filters_deprecated(
1893          'bp_core_avatar_default',
1894          array( $avatar, $params ),
1895          '8.0.0',
1896          'bp_core_avatar_gravatar_default||bp_core_default_avatar',
1897          __( 'This filter was used for 2 different purposes. If your goal was to filter the default *Gravatar*, please use `bp_core_avatar_gravatar_default` instead. Otherwise, please use `bp_core_default_avatar` instead.', 'buddypress' )
1898      );
1899  
1900      if ( ! bp_core_is_default_gravatar( $a ) && false !== strpos( $avatar, '//' ) ) {
1901          $avatar = $a;
1902      }
1903  
1904      /**
1905       * Filters the URL of the 'full' default avatar.
1906       *
1907       * @since 1.5.0
1908       * @since 2.6.0 Added `$params`.
1909       * @since 8.0.0 The name of the filter was changed to `bp_core_default_avatar`.
1910       *
1911       * @param string $avatar URL of the default avatar.
1912       * @param array  $params Params provided to bp_core_fetch_avatar().
1913       */
1914      return apply_filters( 'bp_core_default_avatar', $avatar, $params );
1915  }
1916  
1917  /**
1918   * Get the URL of the 'thumb' default avatar.
1919   *
1920   * Uses Gravatar's mystery-person avatar, unless BP_AVATAR_DEFAULT_THUMB has been
1921   * defined.
1922   *
1923   * @since 1.5.0
1924   * @since 2.6.0 Introduced `$object_type` parameter.
1925   *
1926   * @param string $type   'local' if the fallback should be the locally-hosted version
1927   *                       of the mystery person, 'gravatar' if the fallback should be
1928   *                       Gravatar's version. Default: 'gravatar'.
1929   * @param array  $params Parameters passed to bp_core_fetch_avatar().
1930   * @return string The URL of the default avatar thumb.
1931   */
1932  function bp_core_avatar_default_thumb( $type = 'gravatar', $params = array() ) {
1933      // Local override.
1934      if ( defined( 'BP_AVATAR_DEFAULT_THUMB' ) ) {
1935          $avatar = BP_AVATAR_DEFAULT_THUMB;
1936  
1937      // Use the local default image.
1938      } elseif ( 'local' === $type ) {
1939          $avatar = buddypress()->plugin_url . 'bp-core/images/mystery-man-50.jpg';
1940  
1941      // Use Gravatar's mystery person as fallback.
1942      } else {
1943          $avatar = '//www.gravatar.com/avatar/00000000000000000000000000000000?d=mm&amp;s=' . bp_core_avatar_thumb_width();
1944      }
1945  
1946      /**
1947       * Filters the URL of the 'thumb' default avatar.
1948       *
1949       * @since 1.5.0
1950       * @since 2.6.0 Added `$params`.
1951       *
1952       * @param string $avatar URL of the default avatar.
1953       * @param string $params Params provided to bp_core_fetch_avatar().
1954       */
1955      return apply_filters( 'bp_core_avatar_thumb', $avatar, $params );
1956  }
1957  
1958  /**
1959   * Reset the week parameter of the WordPress main query if needed.
1960   *
1961   * When cropping an avatar, a $_POST['w'] var is sent, setting the 'week'
1962   * parameter of the WordPress main query to this posted var. To avoid
1963   * notices, we need to make sure this 'week' query var is reset to 0.
1964   *
1965   * @since 2.2.0
1966   *
1967   * @param WP_Query|null $posts_query The main query object.
1968   */
1969  function bp_core_avatar_reset_query( $posts_query = null ) {
1970      $reset_w = false;
1971  
1972      // Group's avatar edit screen.
1973      if ( bp_is_group_admin_page() ) {
1974          $reset_w = bp_is_group_admin_screen( 'group-avatar' );
1975  
1976      // Group's avatar create screen.
1977      } elseif ( bp_is_group_create() ) {
1978          /**
1979           * We can't use bp_get_groups_current_create_step().
1980           * as it's not set yet
1981           */
1982          $reset_w = 'group-avatar' === bp_action_variable( 1 );
1983  
1984      // User's change avatar screen.
1985      } else {
1986          $reset_w = bp_is_user_change_avatar();
1987      }
1988  
1989      // A user or a group is cropping an avatar.
1990      if ( true === $reset_w && isset( $_POST['avatar-crop-submit'] ) ) {
1991          $posts_query->set( 'w', 0 );
1992      }
1993  }
1994  add_action( 'bp_parse_query', 'bp_core_avatar_reset_query', 10, 1 );
1995  
1996  /**
1997   * Checks whether Avatar UI should be loaded.
1998   *
1999   * @since 2.3.0
2000   *
2001   * @return bool True if Avatar UI should load, false otherwise.
2002   */
2003  function bp_avatar_is_front_edit() {
2004      $retval = false;
2005  
2006      if ( bp_is_user_change_avatar() && 'crop-image' !== bp_get_avatar_admin_step() ) {
2007          $retval = ! bp_core_get_root_option( 'bp-disable-avatar-uploads' );
2008      }
2009  
2010      if ( bp_is_active( 'groups' ) ) {
2011          // Group creation.
2012          if ( bp_is_group_create() && bp_is_group_creation_step( 'group-avatar' ) && 'crop-image' !== bp_get_avatar_admin_step() ) {
2013              $retval = ! bp_disable_group_avatar_uploads();
2014  
2015          // Group Manage.
2016          } elseif ( bp_is_group_admin_page() && bp_is_group_admin_screen( 'group-avatar' ) && 'crop-image' !== bp_get_avatar_admin_step() ) {
2017              $retval = ! bp_disable_group_avatar_uploads();
2018          }
2019      }
2020  
2021      /**
2022       * Use this filter if you need to :
2023       * - Load the avatar UI for a component that is !groups or !user (return true regarding your conditions)
2024       * - Completely disable the avatar UI introduced in 2.3 (eg: __return_false())
2025       *
2026       * @since 2.3.0
2027       *
2028       * @param bool $retval Whether or not to load the Avatar UI.
2029       */
2030      return apply_filters( 'bp_avatar_is_front_edit', $retval );
2031  }
2032  
2033  /**
2034   * Checks whether the Webcam Avatar UI part should be loaded.
2035   *
2036   * @since 2.3.0
2037   *
2038   * @global $is_safari
2039   * @global $is_IE
2040   *
2041   * @return bool True to load the Webcam Avatar UI part. False otherwise.
2042   */
2043  function bp_avatar_use_webcam() {
2044      global $is_safari, $is_IE, $is_chrome;
2045  
2046      /**
2047       * Do not use the webcam feature for mobile devices
2048       * to avoid possible confusions.
2049       */
2050      if ( wp_is_mobile() ) {
2051          return false;
2052      }
2053  
2054      /**
2055       * Bail when the browser does not support getUserMedia.
2056       *
2057       * @see http://caniuse.com/#feat=stream
2058       */
2059      if ( $is_safari || $is_IE || ( $is_chrome && ! is_ssl() ) ) {
2060          return false;
2061      }
2062  
2063      /**
2064       * Use this filter if you need to disable the webcam capture feature
2065       * by returning false.
2066       *
2067       * @since 2.3.0
2068       *
2069       * @param bool $value Whether or not to load Webcam Avatar UI part.
2070       */
2071      return apply_filters( 'bp_avatar_use_webcam', true );
2072  }
2073  
2074  /**
2075   * Template function to load the Avatar UI javascript templates.
2076   *
2077   * @since 2.3.0
2078   */
2079  function bp_avatar_get_templates() {
2080      if ( ! bp_avatar_is_front_edit() ) {
2081          return;
2082      }
2083  
2084      bp_attachments_get_template_part( 'avatars/index' );
2085  }
2086  
2087  /**
2088   * Trick to check if the theme's BuddyPress templates are up to date.
2089   *
2090   * If the "avatar templates" are not including the new template tag, this will
2091   * help users to get the avatar UI.
2092   *
2093   * @since 2.3.0
2094   */
2095  function bp_avatar_template_check() {
2096      if ( ! bp_avatar_is_front_edit() ) {
2097          return;
2098      }
2099  
2100      if ( ! did_action( 'bp_attachments_avatar_check_template' ) ) {
2101          bp_attachments_get_template_part( 'avatars/index' );
2102      }
2103  }


Generated: Mon Aug 2 01:01:43 2021 Cross-referenced by PHPXref 0.7.1