Skip to:
Content

BuddyPress.org

Ticket #6634: class-bp-attachment-avatar.php

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