BP_Attachment_Avatar

BP Attachment Avatar class.

Defined (1)

The class is defined in the following location(s).

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