[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-core/classes/ -> class-bp-attachment-avatar.php (source)

   1  <?php
   2  /**
   3   * Core Avatars attachment class.
   4   *
   5   * @package BuddyPress
   6   * @subpackage Core
   7   * @since 2.3.0
   8   */
   9  
  10  // Exit if accessed directly.
  11  defined( 'ABSPATH' ) || exit;
  12  
  13  /**
  14   * BP Attachment Avatar class.
  15   *
  16   * Extends BP Attachment to manage the avatar uploads.
  17   *
  18   * @since 2.3.0
  19   */
  20  class BP_Attachment_Avatar extends BP_Attachment {
  21  
  22      /**
  23       * Construct Upload parameters.
  24       *
  25       * @since 2.3.0
  26       *
  27       * @see  BP_Attachment::__construct() for list of parameters
  28       */
  29  	public function __construct() {
  30          // Allowed avatar types.
  31          $allowed_types = bp_core_get_allowed_avatar_types();
  32  
  33          parent::__construct( array(
  34              'action'                => 'bp_avatar_upload',
  35              'file_input'            => 'file',
  36              'original_max_filesize' => bp_core_avatar_original_max_filesize(),
  37  
  38              // Specific errors for avatars.
  39              'upload_error_strings'  => array(
  40                  /* translators: %s: Max file size for the profile photo */
  41                  9  => sprintf( _x( 'That photo is too big. Please upload one smaller than %s', 'profile photo upload error', 'buddypress' ), size_format( bp_core_avatar_original_max_filesize() ) ),
  42  
  43                  /* translators: %s: comma separated list of file types allowed for the profile photo */
  44                  10 => sprintf( _nx( 'Please upload only this file type: %s.', 'Please upload only these file types: %s.', count( $allowed_types ), 'profile photo upload error', 'buddypress' ), self::get_avatar_types( $allowed_types ) ),
  45              ),
  46          ) );
  47      }
  48  
  49      /**
  50       * Gets the available avatar types.
  51       *
  52       * @since 2.3.0
  53       *
  54       * @param array $allowed_types Array of allowed avatar types.
  55       * @return string comma separated list of allowed avatar types.
  56       */
  57  	public static function get_avatar_types( $allowed_types = array() ) {
  58          $types = array_map( 'strtoupper', $allowed_types );
  59          $comma = _x( ',', 'avatar types separator', 'buddypress' );
  60          return join( $comma . ' ', $types );
  61      }
  62  
  63      /**
  64       * Set Upload Dir data for avatars.
  65       *
  66       * @since 2.3.0
  67       */
  68  	public function set_upload_dir() {
  69          if ( bp_core_avatar_upload_path() && bp_core_avatar_url() ) {
  70              $this->upload_path = bp_core_avatar_upload_path();
  71              $this->url         = bp_core_avatar_url();
  72              $this->upload_dir  = bp_upload_dir();
  73          } else {
  74              parent::set_upload_dir();
  75          }
  76      }
  77  
  78      /**
  79       * Avatar specific rules.
  80       *
  81       * Adds an error if the avatar size or type don't match BuddyPress needs.
  82       * The error code is the index of $upload_error_strings.
  83       *
  84       * @since 2.3.0
  85       *
  86       * @param array $file the temporary file attributes (before it has been moved).
  87       * @return array the file with extra errors if needed.
  88       */
  89  	public function validate_upload( $file = array() ) {
  90          // Bail if already an error.
  91          if ( ! empty( $file['error'] ) ) {
  92              return $file;
  93          }
  94  
  95          // File size is too big.
  96          if ( ! bp_core_check_avatar_size( array( 'file' => $file ) ) ) {
  97              $file['error'] = 9;
  98  
  99          // File is of invalid type.
 100          } elseif ( ! bp_core_check_avatar_type( array( 'file' => $file ) ) ) {
 101              $file['error'] = 10;
 102          }
 103  
 104          // Return with error code attached.
 105          return $file;
 106      }
 107  
 108      /**
 109       * Maybe shrink the attachment to fit maximum allowed width.
 110       *
 111       * @since 2.3.0
 112       * @since 2.4.0 Add the $ui_available_width parameter, to inform about the Avatar UI width.
 113       *
 114       * @param string $file               The absolute path to the file.
 115       * @param int    $ui_available_width Available width for the UI.
 116       * @return false|string|WP_Image_Editor|WP_Error
 117       */
 118  	public static function shrink( $file = '', $ui_available_width = 0 ) {
 119          // Get image size.
 120          $avatar_data = parent::get_image_data( $file );
 121  
 122          // Init the edit args.
 123          $edit_args = array();
 124  
 125          // Defaults to the Avatar original max width constant.
 126          $original_max_width = bp_core_avatar_original_max_width();
 127  
 128          // The ui_available_width is defined and it's smaller than the Avatar original max width.
 129          if ( ! empty( $ui_available_width ) && $ui_available_width < $original_max_width ) {
 130              /**
 131               * In this case, to make sure the content of the image will be fully displayed
 132               * during the cropping step, let's use the Avatar UI Available width.
 133               */
 134              $original_max_width = $ui_available_width;
 135  
 136              // $original_max_width has to be larger than the avatar's full width.
 137              if ( $original_max_width < bp_core_avatar_full_width() ) {
 138                  $original_max_width = bp_core_avatar_full_width();
 139              }
 140          }
 141  
 142          // Do we need to resize the image?
 143          if ( isset( $avatar_data['width'] ) && $avatar_data['width'] > $original_max_width ) {
 144              $edit_args = array(
 145                  'max_w' => $original_max_width,
 146                  'max_h' => $original_max_width,
 147              );
 148          }
 149  
 150          // Do we need to rotate the image?
 151          $angles = array(
 152              3 => 180,
 153              6 => -90,
 154              8 =>  90,
 155          );
 156  
 157          if ( isset( $avatar_data['meta']['orientation'] ) && isset( $angles[ $avatar_data['meta']['orientation'] ] ) ) {
 158              $edit_args['rotate'] = $angles[ $avatar_data['meta']['orientation'] ];
 159          }
 160  
 161          // No need to edit the avatar, original file will be used.
 162          if ( empty( $edit_args ) ) {
 163              return false;
 164  
 165          // Add the file to the edit arguments.
 166          } else {
 167              $edit_args['file'] = $file;
 168          }
 169  
 170          return parent::edit_image( 'avatar', $edit_args );
 171      }
 172  
 173      /**
 174       * Check if the image dimensions are smaller than full avatar dimensions.
 175       *
 176       * @since 2.3.0
 177       *
 178       *
 179       * @param string $file the absolute path to the file.
 180       * @return bool
 181       */
 182  	public static function is_too_small( $file = '' ) {
 183          $uploaded_image = @getimagesize( $file );
 184          $full_width     = bp_core_avatar_full_width();
 185          $full_height    = bp_core_avatar_full_height();
 186  
 187          if ( isset( $uploaded_image[0] ) && $uploaded_image[0] < $full_width || $uploaded_image[1] < $full_height ) {
 188              return true;
 189          }
 190  
 191          return false;
 192      }
 193  
 194      /**
 195       * Crop the avatar.
 196       *
 197       * @since 2.3.0
 198       *
 199       * @see  BP_Attachment::crop for the list of parameters
 200       *
 201       * @param array $args Array of arguments for the cropping.
 202       * @return array The cropped avatars (full and thumb).
 203       */
 204  	public function crop( $args = array() ) {
 205          // Bail if the original file is missing.
 206          if ( empty( $args['original_file'] ) ) {
 207              return false;
 208          }
 209  
 210          if ( ! bp_attachments_current_user_can( 'edit_avatar', $args ) ) {
 211              return false;
 212          }
 213  
 214          if ( 'user' === $args['object'] ) {
 215              $avatar_dir = 'avatars';
 216          } else {
 217              $avatar_dir = sanitize_key( $args['object'] ) . '-avatars';
 218          }
 219  
 220          $args['item_id'] = (int) $args['item_id'];
 221  
 222          /**
 223           * Original file is a relative path to the image
 224           * eg: /avatars/1/avatar.jpg
 225           */
 226          $relative_path = sprintf( '/%s/%s/%s', $avatar_dir, $args['item_id'], basename( $args['original_file'] ) );
 227          $absolute_path = $this->upload_path . $relative_path;
 228  
 229          // Bail if the avatar is not available.
 230          if ( ! file_exists( $absolute_path ) )  {
 231              return false;
 232          }
 233  
 234          if ( empty( $args['item_id'] ) ) {
 235  
 236              /** This filter is documented in bp-core/bp-core-avatars.php */
 237              $avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', dirname( $absolute_path ), $args['item_id'], $args['object'], $args['avatar_dir'] );
 238          } else {
 239  
 240              /** This filter is documented in bp-core/bp-core-avatars.php */
 241              $avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', $this->upload_path . '/' . $args['avatar_dir'] . '/' . $args['item_id'], $args['item_id'], $args['object'], $args['avatar_dir'] );
 242          }
 243  
 244          // Bail if the avatar folder is missing for this item_id.
 245          if ( ! file_exists( $avatar_folder_dir ) ) {
 246              return false;
 247          }
 248  
 249          // Delete the existing avatar files for the object.
 250          $existing_avatar = bp_core_fetch_avatar( array(
 251              'object'  => $args['object'],
 252              'item_id' => $args['item_id'],
 253              'html' => false,
 254          ) );
 255  
 256          /**
 257           * Check that the new avatar doesn't have the same name as the
 258           * old one before deleting
 259           */
 260          if ( ! empty( $existing_avatar ) && $existing_avatar !== $this->url . $relative_path ) {
 261              bp_core_delete_existing_avatar( array( 'object' => $args['object'], 'item_id' => $args['item_id'], 'avatar_path' => $avatar_folder_dir ) );
 262          }
 263  
 264          // Make sure we at least have minimal data for cropping.
 265          if ( empty( $args['crop_w'] ) ) {
 266              $args['crop_w'] = bp_core_avatar_full_width();
 267          }
 268  
 269          if ( empty( $args['crop_h'] ) ) {
 270              $args['crop_h'] = bp_core_avatar_full_height();
 271          }
 272  
 273          // Get the file extension.
 274          $data = @getimagesize( $absolute_path );
 275          $ext  = $data['mime'] == 'image/png' ? 'png' : 'jpg';
 276  
 277          $args['original_file'] = $absolute_path;
 278          $args['src_abs']       = false;
 279          $avatar_types = array( 'full' => '', 'thumb' => '' );
 280  
 281          foreach ( $avatar_types as $key_type => $type ) {
 282              if ( 'thumb' === $key_type ) {
 283                  $args['dst_w'] = bp_core_avatar_thumb_width();
 284                  $args['dst_h'] = bp_core_avatar_thumb_height();
 285              } else {
 286                  $args['dst_w'] = bp_core_avatar_full_width();
 287                  $args['dst_h'] = bp_core_avatar_full_height();
 288              }
 289  
 290              $filename         = wp_unique_filename( $avatar_folder_dir, uniqid() . "-bp{$key_type}.{$ext}" );
 291              $args['dst_file'] = $avatar_folder_dir . '/' . $filename;
 292  
 293              $avatar_types[ $key_type ] = parent::crop( $args );
 294          }
 295  
 296          // Remove the original.
 297          @unlink( $absolute_path );
 298  
 299          // Return the full and thumb cropped avatars.
 300          return $avatar_types;
 301      }
 302  
 303      /**
 304       * Get the user id to set its avatar.
 305       *
 306       * @since 2.3.0
 307       *
 308       * @return integer The user ID.
 309       */
 310  	private function get_user_id() {
 311          $bp = buddypress();
 312          $user_id = 0;
 313  
 314          if ( bp_is_user() ) {
 315              $user_id = bp_displayed_user_id();
 316          }
 317  
 318          if ( ! empty( $bp->members->admin->user_id ) ) {
 319              $user_id = $bp->members->admin->user_id;
 320          }
 321  
 322          return $user_id;
 323      }
 324  
 325      /**
 326       * Get the group id to set its avatar.
 327       *
 328       * @since 2.3.0
 329       *
 330       * @return integer The group ID.
 331       */
 332  	private function get_group_id() {
 333          $group_id = 0;
 334  
 335          if ( bp_is_group() ) {
 336              $group_id = bp_get_current_group_id();
 337          }
 338  
 339          return $group_id;
 340      }
 341  
 342      /**
 343       * Build script data for the Uploader UI.
 344       *
 345       * @since 2.3.0
 346       *
 347       * @return array The javascript localization data.
 348       */
 349  	public function script_data() {
 350          // Get default script data.
 351          $script_data = parent::script_data();
 352  
 353          // Defaults to Avatar Backbone script.
 354          $js_scripts = array( 'bp-avatar' );
 355  
 356          // Default object.
 357          $object = '';
 358  
 359          // Get the possible item ids.
 360          $user_id  = $this->get_user_id();
 361          $group_id = $this->get_group_id();
 362  
 363          if ( ! empty( $user_id ) ) {
 364              // Should we load the the Webcam Avatar javascript file.
 365              if ( bp_avatar_use_webcam() ) {
 366                  $js_scripts = array( 'bp-webcam' );
 367              }
 368  
 369              $script_data['bp_params'] = array(
 370                  'object'     => 'user',
 371                  'item_id'    => $user_id,
 372                  'has_avatar' => bp_get_user_has_avatar( $user_id ),
 373                  'nonces'  => array(
 374                      'set'    => wp_create_nonce( 'bp_avatar_cropstore' ),
 375                      'remove' => wp_create_nonce( 'bp_delete_avatar_link' ),
 376                  ),
 377              );
 378  
 379              // Set feedback messages.
 380              $script_data['feedback_messages'] = array(
 381                  1 => __( 'There was a problem cropping your profile photo.', 'buddypress' ),
 382                  2 => __( 'Your new profile photo was uploaded successfully.', 'buddypress' ),
 383                  3 => __( 'There was a problem deleting your profile photo. Please try again.', 'buddypress' ),
 384                  4 => __( 'Your profile photo was deleted successfully!', 'buddypress' ),
 385              );
 386          } elseif ( ! empty( $group_id ) ) {
 387              $script_data['bp_params'] = array(
 388                  'object'     => 'group',
 389                  'item_id'    => $group_id,
 390                  'has_avatar' => bp_get_group_has_avatar( $group_id ),
 391                  'nonces'     => array(
 392                      'set'    => wp_create_nonce( 'bp_avatar_cropstore' ),
 393                      'remove' => wp_create_nonce( 'bp_group_avatar_delete' ),
 394                  ),
 395              );
 396  
 397              // Set feedback messages.
 398              $script_data['feedback_messages'] = array(
 399                  1 => __( 'There was a problem cropping the group profile photo.', 'buddypress' ),
 400                  2 => __( 'The group profile photo was uploaded successfully.', 'buddypress' ),
 401                  3 => __( 'There was a problem deleting the group profile photo. Please try again.', 'buddypress' ),
 402                  4 => __( 'The group profile photo was deleted successfully!', 'buddypress' ),
 403              );
 404          } else {
 405  
 406              /**
 407               * Use this filter to include specific BuddyPress params for your object.
 408               * e.g. Blavatar.
 409               *
 410               * @since 2.3.0
 411               *
 412               * @param array $value The avatar specific BuddyPress parameters.
 413               */
 414              $script_data['bp_params'] = apply_filters( 'bp_attachment_avatar_params', array() );
 415          }
 416  
 417          // Include the specific css.
 418          $script_data['extra_css'] = array( 'bp-avatar' );
 419  
 420          // Include the specific css.
 421          $script_data['extra_js']  = $js_scripts;
 422  
 423          // Set the object to contextualize the filter.
 424          if ( isset( $script_data['bp_params']['object'] ) ) {
 425              $object = $script_data['bp_params']['object'];
 426          }
 427  
 428          /**
 429           * Use this filter to override/extend the avatar script data.
 430           *
 431           * @since 2.3.0
 432           *
 433           * @param array  $script_data The avatar script data.
 434           * @param string $object      The object the avatar belongs to (eg: user or group).
 435           */
 436          return apply_filters( 'bp_attachment_avatar_script_data', $script_data, $object );
 437      }
 438  }


Generated: Thu Jul 9 01:01:31 2020 Cross-referenced by PHPXref 0.7.1