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


Generated: Tue Oct 26 01:00:55 2021 Cross-referenced by PHPXref 0.7.1