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


Generated: Fri Oct 18 01:01:36 2019 Cross-referenced by PHPXref 0.7.1