Skip to:
Content

BuddyPress.org

Ticket #265: bp-core-avatars.php

File bp-core-avatars.php, 17.9 KB (added by williamsba1, 18 years ago)

updated bp-core-avatars.php

Line 
1<?php
2/*
3Based on contributions from: Beau Lebens - http://www.dentedreality.com.au/
4Modified for BuddyPress by: Andy Peatling - http://apeatling.wordpress.com/
5*/
6
7/* Make sure we have the core WordPress files we need */
8require_once( ABSPATH . '/wp-admin/includes/image.php' );
9require_once( ABSPATH . '/wp-admin/includes/file.php' );
10
11/* Define settings for avatars. [TODO] This will eventually end up as admin configurable settings */
12define( 'CORE_AVATAR_V1_W', 50 );
13define( 'CORE_AVATAR_V1_H', 50 );
14define( 'CORE_AVATAR_V2_W', 150 );
15define( 'CORE_AVATAR_V2_H', 150 );
16define( 'CORE_CROPPING_CANVAS_MAX', 450 );
17define( 'CORE_MAX_FILE_SIZE', get_site_option('fileupload_maxk') * 1024 );
18define( 'CORE_DEFAULT_AVATAR', site_url( MUPLUGINDIR . '/bp-xprofile/images/none.gif' ) );
19define( 'CORE_DEFAULT_AVATAR_THUMB', site_url( MUPLUGINDIR . '/bp-xprofile/images/none-thumbnail.gif' ) );
20
21function bp_core_get_avatar( $user, $version = 1, $width = null, $height = null, $no_tag = false ) {
22 global $bp, $current_blog;
23
24 if ( !is_int($version) )
25 $version = (int) $version;
26
27 if ( CORE_AVATAR_V2_W == false && CORE_AVATAR_V2_H == false )
28 $version = 1;
29
30 if ( !$width )
31 $width = constant('CORE_AVATAR_V' . $version . '_W');
32
33 if ( !$height )
34 $height = constant('CORE_AVATAR_V' . $version . '_H');
35
36 $avatar_file = get_usermeta( $user, "bp_core_avatar_v$version" );
37 $url = $bp['root_domain'] . '/' . $avatar_file;
38
39 if ( strlen($avatar_file) ) {
40 if ( $no_tag )
41 return $url;
42 else
43 return '<img src="' . $url . '" alt="" class="avatar photo" width="' . $width . '" height="' . $height . '" />';
44 } else {
45 $ud = get_userdata($user);
46 $grav_option = get_site_option('user-avatar-default');
47
48 if ( $grav_option == '' ) {
49 $default_grav = 'wavatar';
50 } else if ( $grav_option == 'mystery' ) {
51 $default_grav = site_url( MUPLUGINDIR . '/bp-core/images/mystery-man.jpg');
52 } else {
53 $default_grav = $grav_option;
54 }
55
56 $gravatar = 'http://www.gravatar.com/avatar/' . md5( $ud->user_email ) . '?d=' . $default_grav . '&amp;s=';
57 if ( $no_tag )
58 return $gravatar . constant('CORE_AVATAR_V' . $version . '_W');
59 else
60 return '<img src="' . $gravatar . constant('CORE_AVATAR_V' . $version . '_W') . '" alt="" class="avatar" width="' . $width . '" height="' . $height . '" />';
61 }
62}
63
64// Override internal "get_avatar()" function to use our own where possible
65// WARNING: Does NOT apply size restrictions
66function bp_core_get_avatar_filter( $avatar, $id_or_email, $size, $default ) {
67 $str = '';
68 $ver = ( $size == 1 || $size == 2 ) ? $size : 1;
69
70 if ( CORE_AVATAR_V2_W == false && CORE_AVATAR_V2_H == false )
71 $ver = 1;
72
73 if ( is_numeric($id_or_email) ) {
74 $str = bp_core_get_avatar( $id_or_email, $ver );
75 } elseif ( is_object($id_or_email) ) {
76 if ( !empty($id_or_email->user_id) ) {
77 $str = bp_core_get_avatar( $id_or_email->user_id, $ver );
78 }
79 }
80
81 return empty($str) ? $avatar : $str;
82}
83add_filter( 'get_avatar', 'bp_core_get_avatar_filter', 10, 4 );
84
85
86// Main UI Rendering
87function bp_core_avatar_admin( $message = null, $action, $delete_action) {
88 global $wp_upload_error;
89 ?>
90 <?php if ( !isset($_POST['slick_avatars_action']) && !isset($_GET['slick_avatars_action']) ) { ?>
91 <?php if ( $message ) { ?>
92 <br />
93 <div id="message" class="updated fade">
94 <p><?php echo $message; ?></p>
95 </div>
96 <?php } ?>
97
98 <p><?php _e('Your avatar will be used on your profile and throughout the site.', 'buddypress') ?></p>
99 <p><?php _e('Click below to select a JPG, GIF or PNG format photo from your computer and then click \'Upload Photo\' to proceed.', 'buddypress') ?></p>
100
101 <?php
102
103 bp_core_render_avatar_upload_form($action);
104
105 $str = bp_core_get_avatar( get_current_user_id(), 1 );
106 if ( strlen($str) ) {
107 echo '<h3>' . __('This is your current avatar', 'buddypress') . '</h3>';
108 echo '<span class="crop-img avatar">' . bp_core_get_avatar(get_current_user_id(), 1) . '</span>';
109 echo '<span class="crop-img avatar">' . bp_core_get_avatar(get_current_user_id(), 2) . '</span>';
110 echo '<a href="' . $delete_action . '">Delete</a>';
111 }
112
113 } else if ( isset($_POST['slick_avatars_action']) && $_POST['slick_avatars_action'] == 'upload' ) {
114
115 // Confirm that the nonce is valid
116 if ( !isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'slick_avatars') )
117 bp_core_ap_die( 'Security error.' );
118
119 // Set friendly error feedback.
120 $uploadErrors = array(
121 0 => __("There is no error, the file uploaded with success", 'buddypress'),
122 1 => __("Your image was bigger than the maximum allowed file size of: ", 'buddypress') . size_format(CORE_MAX_FILE_SIZE),
123 2 => __("Your image was bigger than the maximum allowed file size of: ", 'buddypress') . size_format(CORE_MAX_FILE_SIZE),
124 3 => __("The uploaded file was only partially uploaded", 'buddypress'),
125 4 => __("No file was uploaded", 'buddypress'),
126 6 => __("Missing a temporary folder", 'buddypress')
127 );
128
129 if ( !bp_core_check_avatar_upload($_FILES) )
130 bp_core_ap_die( 'Your upload failed, please try again. Error was: ' . $uploadErrors[$_FILES['file']['error']] );
131
132 if ( !bp_core_check_avatar_size($_FILES) )
133 bp_core_ap_die( 'The file you uploaded is too big. Please upload a file under ' . size_format(CORE_MAX_FILE_SIZE) );
134
135 if ( !bp_core_check_avatar_type($_FILES) )
136 bp_core_ap_die( 'Please upload only JPG, GIF or PNG photos.' );
137
138 // "Handle" upload into temporary location
139 if ( !$original = bp_core_handle_avatar_upload($_FILES) )
140 bp_core_ap_die( 'Upload Failed! Error was: ' . $wp_upload_error );
141
142 // Resize down to something we can display on the page or use original if its small enough already.
143 if ( !$canvas = bp_core_resize_avatar($original) )
144 $canvas = $original;
145
146 // Render the cropper UI
147 bp_core_render_avatar_cropper($original, $canvas, $action);
148
149 } else if ( isset($_POST['slick_avatars_action']) && $_POST['slick_avatars_action'] == 'crop' ) {
150 // Crop, save, store
151
152 // Confirm that the nonce is valid
153 if ( !isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'slick_avatars') )
154 bp_core_ap_die( 'Security error.' );
155
156 if ( !bp_core_check_crop( $_POST['orig'], $_POST['canvas'] ) )
157 bp_core_ap_die('Error when cropping, please go back and try again');
158
159 if ( !$result = bp_core_avatar_cropstore( stripslashes($_POST['orig']), $_POST['canvas'], $_POST['v1_x1'], $_POST['v1_y1'], $_POST['v1_w'], $_POST['v1_h'], $_POST['v2_x1'], $_POST['v2_y1'], $_POST['v2_w'], $_POST['v2_h'] ) )
160 bp_core_ap_die('Error when saving avatars, please go back and try again.');
161
162 // Store details to the DB and we're done
163 echo '<p>' . __('Your new avatar was successfully created!', 'buddypress') . '</p>';
164
165 bp_core_avatar_save($result);
166
167 echo '<span class="crop-img">' . bp_core_get_avatar( get_current_user_id(), 1 ) . '</span>';
168
169 if ( CORE_AVATAR_V2_W !== false && CORE_AVATAR_V2_H !== false ) {
170 echo '<span class="crop-img">' . bp_core_get_avatar( get_current_user_id(), 2 ) . '</span>';
171 }
172
173 } else if ( isset($_GET['slick_avatars_action']) && $_GET['slick_avatars_action'] == 'delete' ) {
174 // Delete an avatar
175
176 bp_core_delete_avatar();
177
178 unset($_GET['slick_avatars_action']);
179 $message = __('Avatar successfully removed.', 'buddypress');
180 bp_core_avatar_admin($message);
181
182 }
183 ?>
184 <?php
185}
186
187function bp_core_check_avatar_upload($file) {
188 if ( $file['error'] )
189 return false;
190
191 return true;
192}
193
194function bp_core_check_avatar_size($file) {
195 if ( $file['file']['size'] > CORE_MAX_FILE_SIZE )
196 return false;
197
198 return true;
199}
200
201function bp_core_check_avatar_type($file) {
202 if ( ( strlen($file['file']['type']) && !preg_match('/(jpe?g|gif|png)$/', $file['file']['type'] ) ) && !preg_match( '/(jpe?g|gif|png)$/', $file['file']['name'] ) )
203 return false;
204
205 return true;
206}
207
208function bp_core_handle_avatar_upload($file) {
209 global $wp_upload_error;
210
211 // Change the upload file location to /avatars/user_id
212
213 add_filter( 'upload_dir', 'bp_core_avatar_upload_dir' );
214
215 $res = wp_handle_upload( $file['file'], array('action'=>'slick_avatars') );
216
217 if ( !in_array('error', array_keys($res) ) ) {
218 return $res['file'];
219 } else {
220 $wp_upload_error = $res['error'];
221 return false;
222 }
223}
224
225function bp_core_avatar_upload_dir( $upload, $user_id = false ) {
226 global $bp;
227
228 if ( !$user_id )
229 $user_id = $bp['loggedin_userid'];
230
231 // Switch to the root blog, so all avatars are stored in the root blog upload dir.
232 switch_to_blog(1);
233
234 $path = get_option('upload_path');
235 $newdir = path_join( ABSPATH, $path );
236 $newdir .= '/avatars/' . $user_id . '/';
237
238 $newbdir = $newdir;
239
240 @wp_mkdir_p( $newdir );
241
242 $newurl = trailingslashit( get_option('siteurl') ) . '/avatars/' . $user_id . '/';
243 $newburl = $newurl;
244 $newsubdir = '/avatars/' . $user_id . '/';
245
246 // Switch back to the current blog
247 restore_current_blog();
248
249 return array( 'path' => $newdir, 'url' => $newurl, 'subdir' => $newsubdir, 'basedir' => $newbdir, 'baseurl' => $newburl, 'error' => false );
250}
251
252function bp_core_check_avatar_dimensions($file) {
253 $size = getimagesize($file);
254
255 if ( $size[0] < (int)CORE_AVATAR_V2_W || $size[1] < (int)CORE_CROPPING_CANVAS_MAX )
256 return false;
257
258 return true;
259}
260
261function bp_core_resize_avatar( $file, $size = false ) {
262
263 if ( !$size )
264 $size = CORE_CROPPING_CANVAS_MAX;
265
266 $canvas = wp_create_thumbnail( $file, $size );
267
268 if ( $canvas->errors )
269 return false;
270
271 return $canvas = str_replace( '//', '/', $canvas );
272}
273
274function bp_core_render_avatar_cropper($original, $new, $action, $user_id = null, $no_form_tag = false, $url = false) {
275 global $bp;
276
277 $size = getimagesize($new);
278
279 if ( !$user_id )
280 $user_id = $bp['loggedin_userid'];
281
282 $src = str_replace( array(ABSPATH), array(site_url() . '/'), $new );
283
284 // Load cropper details
285
286 // V1 UI
287 if ( !$no_form_tag )
288 echo '<form action="' . $action . '" method="post" id="avatar-cropper">';
289
290 echo '<input type="hidden" name="slick_avatars_action" value="crop" />';
291 echo '<input type="hidden" name="action" value="slick_avatars" />';
292 echo '<input type="hidden" name="nonce" value="' . wp_create_nonce('slick_avatars') . '" />';
293 echo '<input type="hidden" name="orig" value="' . $original . '" />';
294 echo '<input type="hidden" name="canvas" value="' . $new . '" />';
295
296 echo '<div id="avatar_v1">';
297 echo '<h3>' . __( 'Please Crop Your Avatar!', 'buddypress' ) . '</h3>';
298 echo '<h4>' . __('Thumbnail Avatar', 'buddypress') . '</h4>';
299 echo '<p>' . __('Please crop a small version of your avatar to use for thumbnails.', 'buddypress') . '</p>';
300
301 // Canvas
302 echo '<div id="crop-v1" class="crop-img"><img src="' . $src . '" ' . $size[3] . ' border="0" alt="Select the area to crop" id="crop-v1-img" /></div>';
303
304 // Preview
305 echo '<p class="crop-preview"><strong>' . __('Crop Preview', 'buddypress') . '</strong></p>';
306 echo '<div id="crop-preview-v1" class="crop-preview"></div>';
307
308 // Hidden form fields
309 echo '<input type="hidden" id="v1_x1" name="v1_x1" value="" />';
310 echo '<input type="hidden" id="v1_y1" name="v1_y1" value="" />';
311 echo '<input type="hidden" id="v1_x2" name="v1_x2" value="" />';
312 echo '<input type="hidden" id="v1_y2" name="v1_y2" value="" />';
313 echo '<input type="hidden" id="v1_w" name="v1_w" value="" />';
314 echo '<input type="hidden" id="v1_h" name="v1_h" value="" />';
315
316 // V2 UI (optional)
317 if (CORE_AVATAR_V2_W !== false && CORE_AVATAR_V2_H !== false) {
318 // Continue button (v1 => v2)
319 echo '<p class="submit"><input type="button" name="avatar_continue" id="avatar_continue" value="' . __('Crop Thumbnail &amp; Continue', 'buddypress') . '" onclick="cropAndContinue();" /></p>';
320 echo '</div>';
321
322 echo '<div id="avatar_v2" style="display: none">';
323 echo '<h4>' . __('Full Size Avatar', 'buddypress') . '</h4>';
324 echo '<p>' . __('Please crop a full size version of your avatar.', 'buddypress') . '</p>';
325
326 // Canvas
327 echo '<div id="crop-v2" class="crop-img"><img src="' . $src . '" ' . $size[3] . ' border="0" alt="Select the area to crop" id="crop-v2-img" /></div>';
328
329 // Preview
330 echo '<p class="crop-preview"><strong>' . __('Crop Preview', 'buddypress') . '</strong></p>';
331 echo '<div id="crop-preview-v2" class="crop-preview"></div>';
332
333 // Hidden form fields
334 echo '<input type="hidden" id="v2_x1" name="v2_x1" value="" />';
335 echo '<input type="hidden" id="v2_y1" name="v2_y1" value="" />';
336 echo '<input type="hidden" id="v2_x2"name="v2_x2" value="" />';
337 echo '<input type="hidden" id="v2_y2"name="v2_y2" value="" />';
338 echo '<input type="hidden" id="v2_w" name="v2_w" value="" />';
339 echo '<input type="hidden" id="v2_h" name="v2_h" value="" />';
340
341 // Final button to process everything
342 echo '<p class="submit"><input type="submit" id="crop-complete" name="save" value="' . __('Crop Full Size &amp; Save', 'buddypress') . '" /></p>';
343 echo '</div>';
344 } else {
345 // Close out v1 DIV
346 echo '</div>';
347
348 // Final button to process everything
349 echo '<p class="submit"><input type="submit" name="save" value="' . __('Crop Full Size &amp; Save', 'buddypress') . '" /></p>';
350 }
351
352 if ( !$no_form_tag )
353 echo '</form>';
354 ?>
355 <script type="text/javascript" charset="utf-8">
356 jQuery(document).ready(function(){
357 v1Cropper();
358 });
359 </script>
360 <?php
361}
362
363function bp_core_check_crop( $original, $canvas ) {
364 if ( is_file($original) && is_readable($original) && is_file($canvas) && is_readable($canvas) )
365 return true;
366
367 return false;
368}
369
370function bp_core_avatar_cropstore( $source, $canvas, $v1_x1, $v1_y1, $v1_w, $v1_h, $v2_x1, $v2_y1, $v2_w, $v2_h, $from_signup = false, $filename = 'avatar', $item_id = null ) {
371 $size = getimagesize($source);
372 $dims = getimagesize($canvas);
373
374 // Figure out multiplier for scaling
375 $multi = $size[0] / $dims[0];
376
377 if ( $item_id )
378 $filename_item_id = $item_id . '-';
379
380 if ( $filename != 'avatar' ) {
381 $v1_filename = '-' . $filename_item_id . $filename . '-thumb';
382 $v2_filename = '-' . $filename_item_id . $filename . '-full';
383 } else {
384 $v1_filename = '-avatar1';
385 $v2_filename = '-avatar2';
386 }
387
388 // Perform v1 crop
389 $v1_dest = dirname($source) . '/' . preg_replace('!(\.[^.]+)?$!', $v1_filename . '$1', basename($source), 1);
390
391 if ( $from_signup )
392 $v1_out = wp_crop_image( $source, $v1_x1, $v1_y1, $v1_w, $v1_h, CORE_AVATAR_V1_W, CORE_AVATAR_V1_H, false, $v1_dest );
393 else
394 $v1_out = wp_crop_image( $source, ($v1_x1 * $multi), ($v1_y1 * $multi), ($v1_w * $multi), ($v1_h * $multi), CORE_AVATAR_V1_W, CORE_AVATAR_V1_H, false, $v1_dest );
395
396 // Perform v2 crop
397 if ( CORE_AVATAR_V2_W !== false && CORE_AVATAR_V2_H !== false ) {
398 $v2_dest = dirname($source) . '/' . preg_replace('!(\.[^.]+)?$!', $v2_filename . '$1', basename($source), 1);
399
400 if ( $from_signup )
401 $v2_out = wp_crop_image( $source, $v2_x1, $v2_y1, $v2_w, $v2_h, CORE_AVATAR_V2_W, CORE_AVATAR_V2_H, false, $v2_dest );
402 else
403 $v2_out = wp_crop_image( $source, ($v2_x1 * $multi), ($v2_y1 * $multi), ($v2_w * $multi), ($v2_h * $multi), CORE_AVATAR_V2_W, CORE_AVATAR_V2_H, false, $v2_dest );
404 }
405
406 // Clean up canvas and original images used during cropping
407 foreach ( array( str_replace( '..', '', $source ), str_replace( '..', '', $canvas) ) as $f ) {
408 @unlink($f);
409 }
410
411 $dir = $source;
412
413 do {
414 $dir = dirname($dir);
415 @rmdir($dir); // will fail on non-empty directories
416 } while ( substr_count($dir, '/') >= 2 && stristr($dir, ABSPATH) );
417
418 return array('v1_out' => $v1_out, 'v2_out' => $v2_out);
419}
420
421function bp_core_avatar_save( $vars, $user_id = false ) {
422 if ( !$user_id )
423 $user_id = get_current_user_id();
424
425 $old = get_usermeta( $user_id, 'bp_core_avatar_v1_path' );
426 $v1_href = str_replace( array(ABSPATH), array($src), $vars['v1_out'] );
427 update_usermeta( $user_id, 'bp_core_avatar_v1', $v1_href );
428 update_usermeta( $user_id, 'bp_core_avatar_v1_path', $vars['v1_out'] );
429 @unlink($old); // Removing old avatar
430
431 if ( CORE_AVATAR_V2_W !== false && CORE_AVATAR_V2_H !== false ) {
432 $old = get_usermeta( $user_id, 'bp_core_avatar_v2_path' );
433 $v2_href = str_replace( array(ABSPATH), array($src), $vars['v2_out'] );
434 update_usermeta( $user_id, 'bp_core_avatar_v2', $v2_href );
435 update_usermeta( $user_id, 'bp_core_avatar_v2_path', $vars['v2_out'] );
436 @unlink($old); // Removing old avatar
437 }
438}
439
440function bp_core_render_avatar_upload_form($action, $no_form_tag = false) {
441 if ( !$no_form_tag ) { ?>
442 <form method="post" action="<?php echo $action ?>" enctype="multipart/form-data" id="avatar-upload">
443<?php } ?>
444 <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo CORE_MAX_FILE_SIZE; ?>" />
445 <input type="hidden" name="slick_avatars_action" value="upload" />
446 <input type="hidden" name="action" value="slick_avatars" />
447 <input type="hidden" name="nonce" value="<?php echo wp_create_nonce('slick_avatars'); ?>" />
448 <input type="file" name="file" id="file" />
449 <input type="submit" name="upload" id="upload" value="Upload Photo"/>
450<?php if ( !$no_form_tag ) { ?>
451 </form>
452<?php
453 }
454}
455
456function bp_core_delete_avatar() {
457 $old_v1 = get_usermeta( get_current_user_id(), 'bp_core_avatar_v1_path' );
458 $old_v2 = get_usermeta( get_current_user_id(), 'bp_core_avatar_v2_path' );
459
460 delete_usermeta( get_current_user_id(), 'bp_core_avatar_v1_path' );
461 delete_usermeta( get_current_user_id(), 'bp_core_avatar_v2_path' );
462
463 delete_usermeta( get_current_user_id(), 'bp_core_avatar_v1' );
464 delete_usermeta( get_current_user_id(), 'bp_core_avatar_v2' );
465
466 // Remove the actual images
467 @unlink($old_v1);
468 @unlink($old_v2);
469}
470
471function bp_core_ap_die( $msg ) {
472 global $bp;
473 echo '<p><strong>' . $msg . '</strong></p>';
474 echo '<p><a href="' . $bp['loggedin_domain'] . $bp['profile']['slug'] . '/change-avatar">' . __('Try Again', 'buddypress') . '</a></p>';
475 echo '</div>';
476 exit;
477}
478
479function bp_core_thumb_error( $str ) {
480 if ( !is_string($str) ) {
481 return false;
482 } else {
483 return preg_match( '/(filetype|invalid|not found)/is', $str );
484 }
485}
486
487?>