Simple Local Avatars - Version 2.0

Version Description

  • Choose or upload an avatar from the media library (for user's with appropriate capabilities)!
  • Local avatars are rated for appropriateness, just like Gravatar
  • A new setting under Discussion enables administrators to turn off Gravatar (only use local avatars)
  • Delete the local avatar with a single button click (like everywhere else in WordPress)
  • Uploaded avatar file names are appended with the timestamp, addressing browser image caching issues
  • New developer filter for preventing automatic rescaling: simple_local_avatars_dynamic_resize
  • New developer filter for limiting upload size: simple_local_avatars_upload_limit
  • Upgraded functions deprecated since WordPress 3.5
  • Fixed translations not working on front end (although translations are now a bit out of date...)
  • Hungarian translation added (needs further updating again with new version)
  • Assorted refactoring / improvements under the hood
Download this release

Release Info

Developer jakemgold
Plugin Icon 128x128 Simple Local Avatars
Version 2.0
Comparing to
See all releases

Code changes from version 1.3.1 to 2.0

localization/simple-local-avatars-hu_HU.mo ADDED
Binary file
localization/simple-local-avatars-hu_HU.po ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2010 Simple Local Avatars
2
+ # This file is distributed under the same license as the Simple Local Avatars package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Simple Local Avatars 1.1\n"
6
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/simple-local-avatars\n"
7
+ "POT-Creation-Date: 2011-01-18 16:36:12+00:00\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2013-02-04 22:13+0100\n"
12
+ "Last-Translator: Zahalka Bence <bence.zahalka@invitel.hu>\n"
13
+ "Language-Team: Bence Zahalka\n"
14
+ "Language: magyar\n"
15
+ "X-Generator: Poedit 1.5.4\n"
16
+ "X-Poedit-Basepath: ..\n"
17
+
18
+ #: simple-local-avatars.php:104
19
+ msgid "Local Avatar Permissions"
20
+ msgstr "Lokális profilkép engedélyek"
21
+
22
+ #: simple-local-avatars.php:120
23
+ msgid ""
24
+ "Only allow users with file upload capabilities to upload local avatars "
25
+ "(Authors and above)"
26
+ msgstr ""
27
+ "Csak azok a felhasználók tölthessenek fel saját avatárt, akik fájlokat is "
28
+ "tölthetnek fel (Szerzők, vagy magasabb jogosultsági szintűek)"
29
+
30
+ #: simple-local-avatars.php:128
31
+ msgid "Avatar"
32
+ msgstr "Profilkép"
33
+
34
+ #: simple-local-avatars.php:132
35
+ msgid "Upload Avatar"
36
+ msgstr "Profilkép feltöltése"
37
+
38
+ #: simple-local-avatars.php:148
39
+ msgid "No local avatar is set. Use the upload field to add a local avatar."
40
+ msgstr ""
41
+ "Még nincs profilkép feltöltve. Saját profilkép hozzáadásához használd a "
42
+ "feltöltés mezőt!"
43
+
44
+ #: simple-local-avatars.php:151
45
+ msgid "Delete local avatar"
46
+ msgstr "Profilkép törlése"
47
+
48
+ #: simple-local-avatars.php:152
49
+ msgid ""
50
+ "Replace the local avatar by uploading a new avatar, or erase the local "
51
+ "avatar (falling back to a gravatar) by checking the delete option."
52
+ msgstr ""
53
+ "A meglévő profilkép lecserélhető egy új profilkép feltöltésével, vagy a "
54
+ "meglévő törlésével (ekkor a gravatar képed lesz használva), ha bepipálod a "
55
+ "törlés mezőt."
56
+
57
+ #: simple-local-avatars.php:158
58
+ msgid "No local avatar is set. Set up your avatar at Gravatar.com."
59
+ msgstr ""
60
+ "Nincs lokális profilképed. Állíts be magadnak egy profilképet a Gravatar.com "
61
+ "oldalon!"
62
+
63
+ #: simple-local-avatars.php:161
64
+ msgid ""
65
+ "You do not have media management permissions. To change your local avatar, "
66
+ "contact the blog administrator."
67
+ msgstr ""
68
+ "Nincs médiafájl-kezelési jogosultságod! A profilképed megváltoztatásához meg "
69
+ "kell keresned az oldal valamelyik adminisztrátorát."
70
+
71
+ #. Plugin Name of the plugin/theme
72
+ msgid "Simple Local Avatars"
73
+ msgstr "Egyszerű helyi profilképek"
74
+
75
+ #. Description of the plugin/theme
76
+ msgid ""
77
+ "Adds an avatar upload field to user profiles if the current user has media "
78
+ "permissions. Generates requested sizes on demand just like Gravatar! Simple "
79
+ "and lightweight."
80
+ msgstr ""
81
+ "A felhasználói profilhoz hozzáad egy profilkép feltöltése mezőt, ha a "
82
+ "felhasználónak van médiakezelési jogosultsága. A szükséges képméreteket "
83
+ "éppúgy legenerálja, mint a Gravatar. Egyszerű és pehelykönnyű."
readme.txt CHANGED
@@ -1,12 +1,12 @@
1
  === Simple Local Avatars ===
2
  Contributors: jakemgold, 10up, thinkoomph
3
- Donate link: http://get10up.com/plugins/simple-local-avatars-wordpress/
4
  Tags: avatar, gravatar, user photos, users, profile
5
- Requires at least: 3.2
6
- Tested up to: 3.3
7
- Stable tag: 1.3.1
8
 
9
- Adds an avatar upload field to user profiles if the current user has media permissions. Generates requested sizes on demand just like Gravatar!
10
 
11
 
12
  == Description ==
@@ -15,13 +15,12 @@ Adds an avatar upload field to user profiles if the current user has media permi
15
 
16
  Just edit a user profile, and scroll down to the new "Avatar" field. The plug-in will take care of cropping and sizing!
17
 
18
- Unlike other avatar plug-ins, Simple Local Avatars:
19
-
20
  1. Stores avatars in the "uploads" folder where all of your other media is kept
21
  1. Has a simple, native interface
22
- 1. Fully supports Gravatar and default avatars if no local avatar is set for the user
23
  1. Generates the requested avatar size on demand (and stores the new size for efficiency), so it looks great, just like Gravatar!
24
  1. Let's you decide whether lower privilege users (subscribers, contributors) can upload their own avatar
 
25
 
26
 
27
  == Installation ==
@@ -43,6 +42,19 @@ You can also use `get_simple_local_avatar()` (with the same arguments) to retrei
43
 
44
  == Changelog ==
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  = 1.3.1 =
47
  * Brazilian Portuguese and Belarusian translations
48
  * Bug fixes (most notably correct naming of image files based on user display name)
@@ -89,5 +101,8 @@ You can also use `get_simple_local_avatar()` (with the same arguments) to retrei
89
 
90
  == Upgrade Notice ==
91
 
 
 
 
92
  = 1.3.1 =
93
  Like WordPress 3.2, now *REQUIRES* PHP 5.2 or newer.
1
  === Simple Local Avatars ===
2
  Contributors: jakemgold, 10up, thinkoomph
3
+ Donate link: http://10up.com/plugins/simple-local-avatars-wordpress/
4
  Tags: avatar, gravatar, user photos, users, profile
5
+ Requires at least: 3.5
6
+ Tested up to: 3.6
7
+ Stable tag: 2.0
8
 
9
+ Adds an avatar upload field to user profiles. Generates requested sizes on demand just like Gravatar!
10
 
11
 
12
  == Description ==
15
 
16
  Just edit a user profile, and scroll down to the new "Avatar" field. The plug-in will take care of cropping and sizing!
17
 
 
 
18
  1. Stores avatars in the "uploads" folder where all of your other media is kept
19
  1. Has a simple, native interface
20
+ 1. Fully supports Gravatar and default avatars if no local avatar is set for the user - but also allows you turn off Gravatar
21
  1. Generates the requested avatar size on demand (and stores the new size for efficiency), so it looks great, just like Gravatar!
22
  1. Let's you decide whether lower privilege users (subscribers, contributors) can upload their own avatar
23
+ 1. Enables rating of local avatars, just like Gravatar
24
 
25
 
26
  == Installation ==
42
 
43
  == Changelog ==
44
 
45
+ = 2.0 =
46
+ * Choose or upload an avatar from the media library (for user's with appropriate capabilities)!
47
+ * Local avatars are rated for appropriateness, just like Gravatar
48
+ * A new setting under Discussion enables administrators to turn off Gravatar (only use local avatars)
49
+ * Delete the local avatar with a single button click (like everywhere else in WordPress)
50
+ * Uploaded avatar file names are appended with the timestamp, addressing browser image caching issues
51
+ * New developer filter for preventing automatic rescaling: simple_local_avatars_dynamic_resize
52
+ * New developer filter for limiting upload size: simple_local_avatars_upload_limit
53
+ * Upgraded functions deprecated since WordPress 3.5
54
+ * Fixed translations not working on front end (although translations are now a bit out of date...)
55
+ * Hungarian translation added (needs further updating again with new version)
56
+ * Assorted refactoring / improvements under the hood
57
+
58
  = 1.3.1 =
59
  * Brazilian Portuguese and Belarusian translations
60
  * Bug fixes (most notably correct naming of image files based on user display name)
101
 
102
  == Upgrade Notice ==
103
 
104
+ = 2.0 =
105
+ Upgraded to take advantage of *WordPress 3.5 and newer*. Does not support older versions! This has also *not* been tested with front end profile plug-ins - feedback welcome. Note that several language strings have been added or modified - revised translations would be welcome!
106
+
107
  = 1.3.1 =
108
  Like WordPress 3.2, now *REQUIRES* PHP 5.2 or newer.
screenshot-1.png CHANGED
Binary file
simple-local-avatars.dev.js ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var simple_local_avatar_frame, avatar_spinner, avatar_ratings, avatar_container, avatar_form_button;
2
+ var avatar_working = false;
3
+
4
+ jQuery(document).ready(function($){
5
+ $( document.getElementById('simple-local-avatar-media') ).on( 'click', function(event) {
6
+ event.preventDefault();
7
+
8
+ if ( avatar_working )
9
+ return;
10
+
11
+ if ( simple_local_avatar_frame ) {
12
+ simple_local_avatar_frame.open();
13
+ return;
14
+ }
15
+
16
+ simple_local_avatar_frame = wp.media.frames.simple_local_avatar_frame = wp.media({
17
+ title: i10n_SimpleLocalAvatars.insertMediaTitle,
18
+ button: { text: i10n_SimpleLocalAvatars.insertIntoPost },
19
+ library : { type : 'image'},
20
+ multiple: false
21
+ });
22
+
23
+ simple_local_avatar_frame.on( 'select', function() {
24
+ // We set multiple to false so only get one image from the uploader
25
+ avatar_lock('lock');
26
+ var avatar_url = simple_local_avatar_frame.state().get('selection').first().toJSON().id;
27
+ jQuery.post( ajaxurl, { action: 'assign_simple_local_avatar_media', media_id: avatar_url, user_id: i10n_SimpleLocalAvatars.user_id, _wpnonce: i10n_SimpleLocalAvatars.mediaNonce }, function(data) {
28
+ if ( data != '' ) {
29
+ avatar_container.innerHTML = data;
30
+ $( document.getElementById('simple-local-avatar-remove') ).show();
31
+ avatar_ratings.disabled = false;
32
+ avatar_lock('unlock');
33
+ }
34
+ });
35
+ });
36
+
37
+ simple_local_avatar_frame.open();
38
+ });
39
+
40
+ $( document.getElementById('simple-local-avatar-remove') ).on('click',function(event){
41
+ event.preventDefault();
42
+
43
+ if ( avatar_working )
44
+ return;
45
+
46
+ avatar_lock('lock');
47
+ $.get( ajaxurl, { action: 'remove_simple_local_avatar', user_id: i10n_SimpleLocalAvatars.user_id, _wpnonce: i10n_SimpleLocalAvatars.deleteNonce })
48
+ .done(function(data) {
49
+ if ( data != '' ) {
50
+ avatar_container.innerHTML = data;
51
+ $( document.getElementById('simple-local-avatar-remove') ).hide();
52
+ avatar_ratings.disabled = true;
53
+ avatar_lock('unlock');
54
+ }
55
+ });
56
+ });
57
+ });
58
+
59
+ function avatar_lock( lock_or_unlock ) {
60
+ if ( undefined == avatar_spinner ) {
61
+ avatar_ratings = document.getElementById('simple-local-avatar-ratings');
62
+ avatar_spinner = jQuery( document.getElementById('simple-local-avatar-spinner') );
63
+ avatar_container = document.getElementById('simple-local-avatar-photo');
64
+ avatar_form_button = jQuery(avatar_ratings).closest('form').find('input[type=submit]');
65
+ }
66
+
67
+ if ( lock_or_unlock == 'unlock' ) {
68
+ avatar_working = false;
69
+ avatar_form_button.removeAttr('disabled');
70
+ avatar_spinner.hide();
71
+ } else {
72
+ avatar_working = true;
73
+ avatar_form_button.attr('disabled','disabled');
74
+ avatar_spinner.show();
75
+ }
76
+ }
simple-local-avatars.js ADDED
@@ -0,0 +1 @@
 
1
+ function avatar_lock(e){if(undefined==avatar_spinner){avatar_ratings=document.getElementById("simple-local-avatar-ratings");avatar_spinner=jQuery(document.getElementById("simple-local-avatar-spinner"));avatar_container=document.getElementById("simple-local-avatar-photo");avatar_form_button=jQuery(avatar_ratings).closest("form").find("input[type=submit]")}if(e=="unlock"){avatar_working=false;avatar_form_button.removeAttr("disabled");avatar_spinner.hide()}else{avatar_working=true;avatar_form_button.attr("disabled","disabled");avatar_spinner.show()}}var simple_local_avatar_frame,avatar_spinner,avatar_ratings,avatar_container,avatar_form_button;var avatar_working=false;jQuery(document).ready(function(e){e(document.getElementById("simple-local-avatar-media")).on("click",function(t){t.preventDefault();if(avatar_working)return;if(simple_local_avatar_frame){simple_local_avatar_frame.open();return}simple_local_avatar_frame=wp.media.frames.simple_local_avatar_frame=wp.media({title:i10n_SimpleLocalAvatars.insertMediaTitle,button:{text:i10n_SimpleLocalAvatars.insertIntoPost},library:{type:"image"},multiple:false});simple_local_avatar_frame.on("select",function(){avatar_lock("lock");var t=simple_local_avatar_frame.state().get("selection").first().toJSON().id;jQuery.post(ajaxurl,{action:"assign_simple_local_avatar_media",media_id:t,user_id:i10n_SimpleLocalAvatars.user_id,_wpnonce:i10n_SimpleLocalAvatars.mediaNonce},function(t){if(t!=""){avatar_container.innerHTML=t;e(document.getElementById("simple-local-avatar-remove")).show();avatar_ratings.disabled=false;avatar_lock("unlock")}})});simple_local_avatar_frame.open()});e(document.getElementById("simple-local-avatar-remove")).on("click",function(t){t.preventDefault();if(avatar_working)return;avatar_lock("lock");e.get(ajaxurl,{action:"remove_simple_local_avatar",user_id:i10n_SimpleLocalAvatars.user_id,_wpnonce:i10n_SimpleLocalAvatars.deleteNonce}).done(function(t){if(t!=""){avatar_container.innerHTML=t;e(document.getElementById("simple-local-avatar-remove")).hide();avatar_ratings.disabled=true;avatar_lock("unlock")}})})})
simple-local-avatars.php CHANGED
@@ -1,32 +1,12 @@
1
  <?php
2
  /**
3
  Plugin Name: Simple Local Avatars
4
- Plugin URI: http://get10up.com/plugins/simple-local-avatars-wordpress/
5
- Description: Adds an avatar upload field to user profiles if the current user has media permissions. Generates requested sizes on demand just like Gravatar! Simple and lightweight.
6
- Version: 1.3.1
7
- Author: Jake Goldman (10up LLC), Oomph Inc
8
- Author URI: http://get10up.com
9
-
10
- Plugin: Copyright 2011 Jake Goldman (email : jake@get10up.com)
11
-
12
- This program is free software; you can redistribute it and/or modify
13
- it under the terms of the GNU General Public License as published by
14
- the Free Software Foundation; either version 2 of the License, or
15
- (at your option) any later version.
16
-
17
- This program is distributed in the hope that it will be useful,
18
- but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
- GNU General Public License for more details.
21
-
22
- You should have received a copy of the GNU General Public License
23
- along with this program; if not, write to the Free Software
24
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
-
26
- NOTE: Previous versions may have accidentally and incorrectly attributed the
27
- copyright to employers of Mr. Goldman. While credit is given to all contributors
28
- to the current version, including Mr. Goldman's employers, the copyright belongs
29
- - and has always belonged - to Mr. Goldman, personally.
30
  */
31
 
32
  /**
@@ -34,25 +14,55 @@
34
  */
35
 
36
  class Simple_Local_Avatars {
37
- private $user_id_being_edited;
38
-
 
 
 
 
39
  public function __construct() {
40
- add_filter( 'get_avatar', array( $this, 'get_avatar' ), 10, 5 );
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  add_action( 'admin_init', array( $this, 'admin_init' ) );
43
-
 
44
  add_action( 'show_user_profile', array( $this, 'edit_user_profile' ) );
45
  add_action( 'edit_user_profile', array( $this, 'edit_user_profile' ) );
46
 
47
  add_action( 'personal_options_update', array( $this, 'edit_user_profile_update' ) );
48
  add_action( 'edit_user_profile_update', array( $this, 'edit_user_profile_update' ) );
 
 
 
 
49
 
50
  add_filter( 'avatar_defaults', array( $this, 'avatar_defaults' ) );
51
  }
52
-
53
- public function get_avatar( $avatar = '', $id_or_email, $size = 96, $default = '', $alt = false ) {
54
-
55
- if ( is_numeric($id_or_email) )
 
 
 
 
 
 
 
 
 
56
  $user_id = (int) $id_or_email;
57
  elseif ( is_string( $id_or_email ) && ( $user = get_user_by( 'email', $id_or_email ) ) )
58
  $user_id = $user->ID;
@@ -61,86 +71,197 @@ class Simple_Local_Avatars {
61
 
62
  if ( empty( $user_id ) )
63
  return $avatar;
64
-
 
65
  $local_avatars = get_user_meta( $user_id, 'simple_local_avatar', true );
66
-
67
- if ( empty( $local_avatars ) || empty( $local_avatars['full'] ) )
68
  return $avatar;
69
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  $size = (int) $size;
71
 
72
  if ( empty( $alt ) )
73
  $alt = get_the_author_meta( 'display_name', $user_id );
74
 
75
  // generate a new size
76
- if ( empty( $local_avatars[$size] ) ) {
77
- $upload_path = wp_upload_dir();
78
- $avatar_full_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $local_avatars['full'] );
79
- $image_sized = image_resize( $avatar_full_path, $size, $size, true );
80
- // deal with original being >= to original image (or lack of sizing ability)
81
- $local_avatars[$size] = is_wp_error($image_sized) ? $local_avatars[$size] = $local_avatars['full'] : str_replace( $upload_path['basedir'], $upload_path['baseurl'], $image_sized );
82
- // save updated avatar sizes
83
- update_user_meta( $user_id, 'simple_local_avatar', $local_avatars );
84
- } elseif ( substr( $local_avatars[$size], 0, 4 ) != 'http' ) {
85
- $local_avatars[$size] = home_url( $local_avatars[$size] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  }
 
 
 
87
 
88
  $author_class = is_author( $user_id ) ? ' current-author' : '' ;
89
- $avatar = "<img alt='" . esc_attr( $alt ) . "' src='" . $local_avatars[$size] . "' class='avatar avatar-{$size}{$author_class} photo' height='{$size}' width='{$size}' />";
90
 
91
  return apply_filters( 'simple_local_avatar', $avatar );
92
  }
93
 
94
  public function admin_init() {
95
- load_plugin_textdomain( 'simple-local-avatars', false, dirname( plugin_basename( __FILE__ ) ) . '/localization/' );
96
-
97
- register_setting( 'discussion', 'simple_local_avatars_caps', array( $this, 'sanitize_options' ) );
98
- add_settings_field( 'simple-local-avatars-caps', __('Local Avatar Permissions','simple-local-avatars'), array( $this, 'avatar_settings_field' ), 'discussion', 'avatars' );
 
 
 
 
 
 
 
99
  }
100
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  public function sanitize_options( $input ) {
102
- $new_input['simple_local_avatars_caps'] = empty( $input['simple_local_avatars_caps'] ) ? 0 : 1;
 
103
  return $new_input;
104
  }
105
-
106
- public function avatar_settings_field( $args ) {
107
- $options = get_option('simple_local_avatars_caps');
 
 
 
 
 
 
 
 
 
 
 
108
 
109
  echo '
110
- <label for="simple_local_avatars_caps">
111
- <input type="checkbox" name="simple_local_avatars_caps" id="simple_local_avatars_caps" value="1" ' . @checked( $options['simple_local_avatars_caps'], 1, false ) . ' />
112
- ' . __('Only allow users with file upload capabilities to upload local avatars (Authors and above)','simple-local-avatars') . '
113
  </label>
114
  ';
115
  }
116
-
 
 
 
 
 
117
  public function edit_user_profile( $profileuser ) {
118
  ?>
119
  <h3><?php _e( 'Avatar','simple-local-avatars' ); ?></h3>
120
 
121
  <table class="form-table">
122
  <tr>
123
- <th><label for="simple-local-avatar"><?php _e('Upload Avatar','simple-local-avatars'); ?></label></th>
124
- <td style="width: 50px;" valign="top">
125
- <?php echo get_avatar( $profileuser->ID ); ?>
 
 
 
 
126
  </td>
127
  <td>
128
  <?php
129
- $options = get_option('simple_local_avatars_caps');
 
130
 
131
- if ( empty($options['simple_local_avatars_caps']) || current_user_can('upload_files') ) {
132
  do_action( 'simple_local_avatar_notices' );
133
- wp_nonce_field( 'simple_local_avatar_nonce', '_simple_local_avatar_nonce', false );
 
 
 
 
 
134
  ?>
135
- <input type="file" name="simple-local-avatar" id="simple-local-avatar" /><br />
 
 
 
 
 
 
 
 
136
  <?php
137
- if ( empty( $profileuser->simple_local_avatar ) )
138
- echo '<span class="description">' . __('No local avatar is set. Use the upload field to add a local avatar.','simple-local-avatars') . '</span>';
139
- else
140
- echo '
141
- <input type="checkbox" name="simple-local-avatar-erase" value="1" /> ' . __('Delete local avatar','simple-local-avatars') . '<br />
142
- <span class="description">' . __('Replace the local avatar by uploading a new avatar, or erase the local avatar (falling back to a gravatar) by checking the delete option.','simple-local-avatars') . '</span>
143
- ';
144
  } else {
145
  if ( empty( $profileuser->simple_local_avatar ) )
146
  echo '<span class="description">' . __('No local avatar is set. Set up your avatar at Gravatar.com.','simple-local-avatars') . '</span>';
@@ -150,53 +271,171 @@ class Simple_Local_Avatars {
150
  ?>
151
  </td>
152
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  </table>
154
- <script type="text/javascript">var form = document.getElementById('your-profile');form.encoding = 'multipart/form-data';form.setAttribute('enctype', 'multipart/form-data');</script>
155
- <?php
156
  }
157
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  public function edit_user_profile_update( $user_id ) {
159
- if ( ! isset( $_POST['_simple_local_avatar_nonce'] ) || ! wp_verify_nonce( $_POST['_simple_local_avatar_nonce'], 'simple_local_avatar_nonce' ) ) //security
 
160
  return;
161
-
162
- if ( ! empty( $_FILES['simple-local-avatar']['name'] ) ) {
163
- $mimes = array(
164
- 'jpg|jpeg|jpe' => 'image/jpeg',
165
- 'gif' => 'image/gif',
166
- 'png' => 'image/png',
167
- 'bmp' => 'image/bmp',
168
- 'tif|tiff' => 'image/tiff'
169
- );
170
-
 
171
  // front end (theme my profile etc) support
172
  if ( ! function_exists( 'wp_handle_upload' ) )
173
  require_once( ABSPATH . 'wp-admin/includes/file.php' );
174
-
175
- $this->avatar_delete( $user_id ); // delete old images if successful
176
-
177
- // need to be more secure since low privelege users can upload
178
- if ( strstr( $_FILES['simple-local-avatar']['name'], '.php' ) )
179
- wp_die('For security reasons, the extension ".php" cannot be in your file name.');
180
-
181
  $this->user_id_being_edited = $user_id; // make user_id known to unique_filename_callback function
182
- $avatar = wp_handle_upload( $_FILES['simple-local-avatar'], array( 'mimes' => $mimes, 'test_form' => false, 'unique_filename_callback' => array( $this, 'unique_filename_callback' ) ) );
183
-
 
 
 
 
 
 
 
 
 
 
184
  if ( empty($avatar['file']) ) { // handle failures
185
  switch ( $avatar['error'] ) {
186
  case 'File type does not meet security guidelines. Try another.' :
187
- add_action( 'user_profile_update_errors', create_function('$a','$a->add("avatar_error",__("Please upload a valid image file for the avatar.","simple-local-avatars"));') );
188
  break;
189
  default :
190
- add_action( 'user_profile_update_errors', create_function('$a','$a->add("avatar_error","<strong>".__("There was an error uploading the avatar:","simple-local-avatars")."</strong> ' . esc_attr( $avatar['error'] ) . '");') );
191
  }
192
-
 
 
193
  return;
194
  }
195
-
196
- update_user_meta( $user_id, 'simple_local_avatar', array( 'full' => $avatar['url'] ) ); // save user information (overwriting old)
197
- } elseif ( ! empty( $_POST['simple-local-avatar-erase'] ) ) {
198
- $this->avatar_delete( $user_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  }
201
 
202
  /**
@@ -206,29 +445,51 @@ class Simple_Local_Avatars {
206
  remove_action( 'get_avatar', array( $this, 'get_avatar' ) );
207
  return $avatar_defaults;
208
  }
209
-
210
  /**
211
- * delete avatars based on user_id
 
 
212
  */
213
  public function avatar_delete( $user_id ) {
214
- $old_avatars = get_user_meta( $user_id, 'simple_local_avatar', true );
215
- $upload_path = wp_upload_dir();
216
-
217
- if ( is_array($old_avatars) ) {
 
 
 
 
 
 
 
 
218
  foreach ($old_avatars as $old_avatar ) {
 
219
  $old_avatar_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $old_avatar );
220
- @unlink( $old_avatar_path );
 
221
  }
222
  }
223
-
224
  delete_user_meta( $user_id, 'simple_local_avatar' );
 
225
  }
226
-
 
 
 
 
 
 
 
 
227
  public function unique_filename_callback( $dir, $name, $ext ) {
228
  $user = get_user_by( 'id', (int) $this->user_id_being_edited );
229
- $name = $base_name = sanitize_file_name( $user->display_name . '_avatar' );
 
 
230
  $number = 1;
231
-
232
  while ( file_exists( $dir . "/$name$ext" ) ) {
233
  $name = $base_name . '_' . $number;
234
  $number++;
@@ -236,6 +497,15 @@ class Simple_Local_Avatars {
236
 
237
  return $name . $ext;
238
  }
 
 
 
 
 
 
 
 
 
239
  }
240
 
241
  $simple_local_avatars = new Simple_Local_Avatars;
@@ -249,16 +519,71 @@ $simple_local_avatars = new Simple_Local_Avatars;
249
  * @param string $alt Alternate text to use in image tag. Defaults to blank
250
  * @return string <img> tag for the user's avatar
251
  */
252
- function get_simple_local_avatar( $id_or_email, $size = '96', $default = '', $alt = false ) {
253
  global $simple_local_avatars;
254
  $avatar = $simple_local_avatars->get_avatar( '', $id_or_email, $size, $default, $alt );
255
 
256
- if ( empty ( $avatar ) )
 
257
  $avatar = get_avatar( $id_or_email, $size, $default, $alt );
 
 
258
 
259
  return $avatar;
260
  }
261
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
  /**
263
  * on uninstallation, remove the custom field from the users and delete the local avatars
264
  */
@@ -267,10 +592,14 @@ register_uninstall_hook( __FILE__, 'simple_local_avatars_uninstall' );
267
 
268
  function simple_local_avatars_uninstall() {
269
  $simple_local_avatars = new Simple_Local_Avatars;
270
- $users = get_users_of_blog();
271
-
272
- foreach ( $users as $user )
273
- $simple_local_avatars->avatar_delete( $user->user_id );
 
 
 
 
274
 
275
- delete_option('simple_local_avatars_caps');
276
  }
1
  <?php
2
  /**
3
  Plugin Name: Simple Local Avatars
4
+ Plugin URI: http://10up.com/plugins/simple-local-avatars-wordpress/
5
+ Description: Adds an avatar upload field to user profiles. Generates requested sizes on demand, just like Gravatar! Simple and lightweight.
6
+ Version: 2.0
7
+ Author: Jake Goldman, 10up
8
+ Author URI: http://10up.com
9
+ License: GPLv2 or later
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  */
11
 
12
  /**
14
  */
15
 
16
  class Simple_Local_Avatars {
17
+ private $user_id_being_edited, $avatar_upload_error, $remove_nonce, $avatar_ratings;
18
+ public $options;
19
+
20
+ /**
21
+ * Set up the hooks and default values
22
+ */
23
  public function __construct() {
24
+ load_plugin_textdomain( 'simple-local-avatars', false, dirname( plugin_basename( __FILE__ ) ) . '/localization/' );
25
+
26
+ $this->options = (array) get_option( 'simple_local_avatars' );
27
+ $this->avatar_ratings = array(
28
+ 'G' => __('G &#8212; Suitable for all audiences'),
29
+ 'PG' => __('PG &#8212; Possibly offensive, usually for audiences 13 and above'),
30
+ 'R' => __('R &#8212; Intended for adult audiences above 17'),
31
+ 'X' => __('X &#8212; Even more mature than above')
32
+ );
33
+
34
+ // supplement remote avatars, but not if inside "local only" mode
35
+ if ( empty( $this->options['only'] ) )
36
+ add_filter( 'get_avatar', array( $this, 'get_avatar' ), 10, 5 );
37
 
38
  add_action( 'admin_init', array( $this, 'admin_init' ) );
39
+
40
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
41
  add_action( 'show_user_profile', array( $this, 'edit_user_profile' ) );
42
  add_action( 'edit_user_profile', array( $this, 'edit_user_profile' ) );
43
 
44
  add_action( 'personal_options_update', array( $this, 'edit_user_profile_update' ) );
45
  add_action( 'edit_user_profile_update', array( $this, 'edit_user_profile_update' ) );
46
+ add_action( 'admin_action_remove-simple-local-avatar', array( $this, 'action_remove_simple_local_avatar' ) );
47
+ add_action( 'wp_ajax_assign_simple_local_avatar_media', array( $this, 'ajax_assign_simple_local_avatar_media' ) );
48
+ add_action( 'wp_ajax_remove_simple_local_avatar', array( $this, 'action_remove_simple_local_avatar' ) );
49
+ add_action( 'user_edit_form_tag', array( $this, 'user_edit_form_tag' ) );
50
 
51
  add_filter( 'avatar_defaults', array( $this, 'avatar_defaults' ) );
52
  }
53
+
54
+ /**
55
+ * Retrieve the local avatar for a user who provided a user ID or email address.
56
+ *
57
+ * @param string $avatar Avatar return by original function
58
+ * @param int|string|object $id_or_email A user ID, email address, or comment object
59
+ * @param int $size Size of the avatar image
60
+ * @param string $default URL to a default image to use if no avatar is available
61
+ * @param string $alt Alternative text to use in image tag. Defaults to blank
62
+ * @return string <img> tag for the user's avatar
63
+ */
64
+ public function get_avatar( $avatar = '', $id_or_email, $size = 96, $default = '', $alt = '' ) {
65
+ if ( is_numeric( $id_or_email ) )
66
  $user_id = (int) $id_or_email;
67
  elseif ( is_string( $id_or_email ) && ( $user = get_user_by( 'email', $id_or_email ) ) )
68
  $user_id = $user->ID;
71
 
72
  if ( empty( $user_id ) )
73
  return $avatar;
74
+
75
+ // fetch local avatar from meta and make sure it's properly ste
76
  $local_avatars = get_user_meta( $user_id, 'simple_local_avatar', true );
77
+ if ( empty( $local_avatars['full'] ) )
 
78
  return $avatar;
79
+
80
+ // check rating
81
+ $avatar_rating = get_user_meta( $user_id, 'simple_local_avatar_rating', true );
82
+ if ( ! empty( $avatar_rating ) && 'G' != $avatar_rating && ( $site_rating = get_option( 'avatar_rating' ) ) ) {
83
+ $ratings = array_keys( $this->avatar_ratings );
84
+ $site_rating_weight = array_search( $site_rating, $ratings );
85
+ $avatar_rating_weight = array_search( $avatar_rating, $ratings );
86
+ if ( false !== $avatar_rating_weight && $avatar_rating_weight > $site_rating_weight )
87
+ return $avatar;
88
+ }
89
+
90
+ // handle "real" media
91
+ if ( ! empty( $local_avatars['media_id'] ) ) {
92
+ // has the media been deleted?
93
+ if ( ! $avatar_full_path = get_attached_file( $local_avatars['media_id'] ) ) {
94
+ // only allowed logged in users to delete bad data to mitigate performance issues
95
+ if ( is_user_logged_in() )
96
+ $this->avatar_delete( $user_id );
97
+
98
+ return $avatar;
99
+ }
100
+ }
101
+
102
  $size = (int) $size;
103
 
104
  if ( empty( $alt ) )
105
  $alt = get_the_author_meta( 'display_name', $user_id );
106
 
107
  // generate a new size
108
+ if ( ! array_key_exists( $size, $local_avatars ) ) {
109
+ $local_avatars[$size] = $local_avatars['full']; // just in case of failure elsewhere
110
+
111
+ // allow automatic rescaling to be turned off
112
+ if ( $allow_dynamic_resizing = apply_filters( 'simple_local_avatars_dynamic_resize', true ) ) :
113
+
114
+ $upload_path = wp_upload_dir();
115
+
116
+ // get path for image by converting URL, unless its already been set, thanks to using media library approach
117
+ if ( ! isset( $avatar_full_path ) )
118
+ $avatar_full_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $local_avatars['full'] );
119
+
120
+ // generate the new size
121
+ $editor = wp_get_image_editor( $avatar_full_path );
122
+ if ( ! is_wp_error( $editor ) ) {
123
+ $resized = $editor->resize( $size, $size, true );
124
+ if ( ! is_wp_error( $resized ) ) {
125
+ $dest_file = $editor->generate_filename();
126
+ $saved = $editor->save( $dest_file );
127
+ if ( ! is_wp_error( $saved ) )
128
+ $local_avatars[$size] = str_replace( $upload_path['basedir'], $upload_path['baseurl'], $dest_file );
129
+ }
130
+ }
131
+
132
+ // save updated avatar sizes
133
+ update_user_meta( $user_id, 'simple_local_avatar', $local_avatars );
134
+
135
+ endif;
136
  }
137
+
138
+ if ( 'http' != substr( $local_avatars[$size], 0, 4 ) )
139
+ $local_avatars[$size] = home_url( $local_avatars[$size] );
140
 
141
  $author_class = is_author( $user_id ) ? ' current-author' : '' ;
142
+ $avatar = "<img alt='" . esc_attr( $alt ) . "' src='" . esc_url( $local_avatars[$size] ) . "' class='avatar avatar-{$size}{$author_class} photo' height='{$size}' width='{$size}' />";
143
 
144
  return apply_filters( 'simple_local_avatar', $avatar );
145
  }
146
 
147
  public function admin_init() {
148
+ // upgrade pre 2.0 option
149
+ if ( $old_ops = get_option( 'simple_local_avatars_caps' ) ) {
150
+ if ( ! empty( $old_ops['simple_local_avatars_caps'] ) )
151
+ update_option( 'simple_local_avatars', array( 'caps' => 1 ) );
152
+
153
+ delete_option( 'simple_local_avatar_caps' );
154
+ }
155
+
156
+ register_setting( 'discussion', 'simple_local_avatars', array( $this, 'sanitize_options' ) );
157
+ add_settings_field( 'simple-local-avatars-only', __('Local Avatars Only','simple-local-avatars'), array( $this, 'avatar_settings_field' ), 'discussion', 'avatars', array( 'key' => 'only', 'desc' => 'Only allow local avatars (still uses Gravatar for default avatars)' ) );
158
+ add_settings_field( 'simple-local-avatars-caps', __('Local Upload Permissions','simple-local-avatars'), array( $this, 'avatar_settings_field' ), 'discussion', 'avatars', array( 'key' => 'caps', 'desc' => 'Only allow users with file upload capabilities to upload local avatars (Authors and above)' ) );
159
  }
160
+
161
+ /**
162
+ * Add scripts to the profile editing page
163
+ *
164
+ * @param string $hook_suffix Page hook
165
+ */
166
+ public function admin_enqueue_scripts( $hook_suffix ) {
167
+ if ( 'profile.php' != $hook_suffix && 'user-edit.php' != $hook_suffix )
168
+ return;
169
+
170
+ if ( current_user_can( 'upload_files' ) )
171
+ wp_enqueue_media();
172
+
173
+ $user_id = ( 'profile.php' == $hook_suffix ) ? get_current_user_id() : (int) $_GET['user_id'];
174
+
175
+ $this->remove_nonce = wp_create_nonce( 'remove_simple_local_avatar_nonce' );
176
+
177
+ $script_name_append = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.dev' : '';
178
+ wp_enqueue_script( 'simple-local-avatars', plugins_url( '', __FILE__ ) . '/simple-local-avatars' . $script_name_append . '.js', array('jquery'), false, true );
179
+ wp_localize_script( 'simple-local-avatars', 'i10n_SimpleLocalAvatars', array(
180
+ 'user_id' => $user_id,
181
+ 'insertMediaTitle' => __('Choose an Avatar','simple-local-avatars'),
182
+ 'insertIntoPost' => __('Set as avatar','simple-local-avatars'),
183
+ 'deleteNonce' => $this->remove_nonce,
184
+ 'mediaNonce' => wp_create_nonce( 'assign_simple_local_avatar_nonce' ),
185
+ ) );
186
+ }
187
+
188
+ /**
189
+ * Sanitize new settings field before saving
190
+ *
191
+ * @param array|string $input Passed input values to sanitize
192
+ * @return array|string Sanitized input fields
193
+ */
194
  public function sanitize_options( $input ) {
195
+ $new_input['caps'] = empty( $input['caps'] ) ? 0 : 1;
196
+ $new_input['only'] = empty( $input['only'] ) ? 0 : 1;
197
  return $new_input;
198
  }
199
+
200
+ /**
201
+ * Settings field for avatar upload capabilities
202
+ *
203
+ * @param array $args Field arguments
204
+ */
205
+ public function avatar_settings_field( $args ) {
206
+ $args = wp_parse_args( $args, array(
207
+ 'key' => '',
208
+ 'desc' => '',
209
+ ) );
210
+
211
+ if ( empty( $this->options[$args['key']] ) )
212
+ $this->options[$args['key']] = 0;
213
 
214
  echo '
215
+ <label for="simple-local-avatars-' . $args['key'] . '">
216
+ <input type="checkbox" name="simple_local_avatars[' . $args['key'] . ']" id="simple-local-avatars-' . $args['key'] . '" value="1" ' . checked( $this->options[$args['key']], 1, false ) . ' />
217
+ ' . __($args['desc'],'simple-local-avatars') . '
218
  </label>
219
  ';
220
  }
221
+
222
+ /**
223
+ * Output new Avatar fields to user editing / profile screen
224
+ *
225
+ * @param object $profileuser User object
226
+ */
227
  public function edit_user_profile( $profileuser ) {
228
  ?>
229
  <h3><?php _e( 'Avatar','simple-local-avatars' ); ?></h3>
230
 
231
  <table class="form-table">
232
  <tr>
233
+ <th scope="row"><label for="simple-local-avatar"><?php _e('Upload Avatar','simple-local-avatars'); ?></label></th>
234
+ <td style="width: 50px;" id="simple-local-avatar-photo">
235
+ <?php
236
+ add_filter( 'pre_option_avatar_rating', '__return_null' ); // ignore ratings here
237
+ echo get_simple_local_avatar( $profileuser->ID );
238
+ remove_filter( 'pre_option_avatar_rating', '__return_null' );
239
+ ?>
240
  </td>
241
  <td>
242
  <?php
243
+ if ( ! $upload_rights = current_user_can('upload_files') )
244
+ $upload_rights = empty( $this->options['caps'] );
245
 
246
+ if ( $upload_rights ) {
247
  do_action( 'simple_local_avatar_notices' );
248
+ wp_nonce_field( 'simple_local_avatar_nonce', '_simple_local_avatar_nonce', false );
249
+ $remove_url = add_query_arg(array(
250
+ 'action' => 'remove-simple-local-avatar',
251
+ 'user_id' => $profileuser->ID,
252
+ '_wpnonce' => $this->remove_nonce,
253
+ ) );
254
  ?>
255
+ <p style="display: inline-block; width: 26em;">
256
+ <span class="description"><?php _e( 'Choose an image from your computer:' ); ?></span><br />
257
+ <input type="file" name="simple-local-avatar" id="simple-local-avatar" class="standard-text" />
258
+ <span class="spinner" id="simple-local-avatar-spinner"></span>
259
+ </p>
260
+ <p>
261
+ <?php if ( current_user_can( 'upload_files' ) && did_action( 'wp_enqueue_media' ) ) : ?><a href="#" class="button hide-if-no-js" id="simple-local-avatar-media"><?php _e( 'Choose from Media Library', 'simple-local-avatars' ); ?></a> &nbsp;<?php endif; ?>
262
+ <a href="<?php echo $remove_url; ?>" class="button item-delete submitdelete deletion" id="simple-local-avatar-remove"<?php if ( empty( $profileuser->simple_local_avatar ) ) echo ' style="display:none;"'; ?>><?php _e('Delete local avatar','simple-local-avatars'); ?></a>
263
+ </p>
264
  <?php
 
 
 
 
 
 
 
265
  } else {
266
  if ( empty( $profileuser->simple_local_avatar ) )
267
  echo '<span class="description">' . __('No local avatar is set. Set up your avatar at Gravatar.com.','simple-local-avatars') . '</span>';
271
  ?>
272
  </td>
273
  </tr>
274
+ <tr>
275
+ <th scope="row"><?php _e('Rating'); ?></th>
276
+ <td colspan="2">
277
+ <fieldset id="simple-local-avatar-ratings" <?php disabled( empty( $profileuser->simple_local_avatar ) ); ?>>
278
+ <legend class="screen-reader-text"><span><?php _e('Rating'); ?></span></legend>
279
+ <?php
280
+ if ( empty( $profileuser->simple_local_avatar_rating ) || ! array_key_exists( $profileuser->simple_local_avatar_rating, $this->avatar_ratings ) )
281
+ $profileuser->simple_local_avatar_rating = 'G';
282
+
283
+ foreach ( $this->avatar_ratings as $key => $rating ) :
284
+ echo "\n\t<label><input type='radio' name='simple_local_avatar_rating' value='" . esc_attr( $key ) . "' " . checked( $profileuser->simple_local_avatar_rating, $key, false ) . "/> $rating</label><br />";
285
+ endforeach;
286
+ ?>
287
+ <p class="description"><?php _e( 'If the local avatar is inappropriate for this site, Gravatar will be attempted.' ); ?></p>
288
+ </fieldset></td>
289
+ </tr>
290
  </table>
291
+ <?php
 
292
  }
293
+
294
+ /**
295
+ * Ensure that the profile form has proper encoding type
296
+ */
297
+ public function user_edit_form_tag() {
298
+ echo 'enctype="multipart/form-data"';
299
+ }
300
+
301
+ /**
302
+ * Saves avatar image to a user
303
+ *
304
+ * @param int|string $url_or_media_id Local URL for avatar or ID of attachment
305
+ * @param int $user_id ID of user to assign image to
306
+ */
307
+ private function assign_new_user_avatar( $url_or_media_id, $user_id ) {
308
+ // delete the old avatar
309
+ $this->avatar_delete( $user_id ); // delete old images if successful
310
+
311
+ $meta_value = array();
312
+
313
+ // set the new avatar
314
+ if ( is_int( $url_or_media_id ) ) {
315
+ $meta_value['media_id'] = $url_or_media_id;
316
+ $url_or_media_id = wp_get_attachment_url( $url_or_media_id );
317
+ }
318
+
319
+ $meta_value['full'] = $url_or_media_id;
320
+
321
+ update_user_meta( $user_id, 'simple_local_avatar', $meta_value ); // save user information (overwriting old)
322
+ }
323
+
324
+ /**
325
+ * Save any changes to the user profile
326
+ *
327
+ * @param int $user_id ID of user being updated
328
+ */
329
  public function edit_user_profile_update( $user_id ) {
330
+ // check nonces
331
+ if( empty( $_POST['_simple_local_avatar_nonce'] ) || ! wp_verify_nonce( $_POST['_simple_local_avatar_nonce'], 'simple_local_avatar_nonce' ) )
332
  return;
333
+
334
+ // check for uploaded files
335
+ if ( ! empty( $_FILES['simple-local-avatar']['name'] ) ) :
336
+
337
+ // need to be more secure since low privelege users can upload
338
+ if ( false !== strpos( $_FILES['simple-local-avatar']['name'], '.php' ) ) {
339
+ $this->avatar_upload_error = __('For security reasons, the extension ".php" cannot be in your file name.','simple-local-avatars');
340
+ add_action( 'user_profile_update_errors', array( $this, 'user_profile_update_errors' ) );
341
+ return;
342
+ }
343
+
344
  // front end (theme my profile etc) support
345
  if ( ! function_exists( 'wp_handle_upload' ) )
346
  require_once( ABSPATH . 'wp-admin/includes/file.php' );
347
+
348
+ // allow developers to override file size upload limit for avatars
349
+ add_filter( 'upload_size_limit', array( $this, 'upload_size_limit' ) );
350
+
 
 
 
351
  $this->user_id_being_edited = $user_id; // make user_id known to unique_filename_callback function
352
+ $avatar = wp_handle_upload( $_FILES['simple-local-avatar'], array(
353
+ 'mimes' => array(
354
+ 'jpg|jpeg|jpe' => 'image/jpeg',
355
+ 'gif' => 'image/gif',
356
+ 'png' => 'image/png',
357
+ ),
358
+ 'test_form' => false,
359
+ 'unique_filename_callback' => array( $this, 'unique_filename_callback' )
360
+ ) );
361
+
362
+ remove_filter( 'upload_size_limit', array( $this, 'upload_size_limit' ) );
363
+
364
  if ( empty($avatar['file']) ) { // handle failures
365
  switch ( $avatar['error'] ) {
366
  case 'File type does not meet security guidelines. Try another.' :
367
+ $this->avatar_upload_error = __('Please upload a valid image file for the avatar.','simple-local-avatars');
368
  break;
369
  default :
370
+ $this->avatar_upload_error = '<strong>' . __('There was an error uploading the avatar:','simple-local-avatars') . '</strong> ' . esc_html( $avatar['error'] );
371
  }
372
+
373
+ add_action( 'user_profile_update_errors', array( $this, 'user_profile_update_errors' ) );
374
+
375
  return;
376
  }
377
+
378
+ $this->assign_new_user_avatar( $avatar['url'], $user_id );
379
+
380
+ endif;
381
+
382
+ // handle rating
383
+ if ( isset( $avatar['url'] ) || $avatar = get_user_meta( $user_id, 'simple_local_avatar', true ) ) {
384
+ if ( empty( $_POST['simple_local_avatar_rating'] ) || ! array_key_exists( $_POST['simple_local_avatar_rating'], $this->avatar_ratings ) )
385
+ $_POST['simple_local_avatar_rating'] = key( $this->avatar_ratings );
386
+
387
+ update_user_meta( $user_id, 'simple_local_avatar_rating', $_POST['simple_local_avatar_rating'] );
388
+ }
389
+ }
390
+
391
+ /**
392
+ * Allow developers to override the maximum allowable file size for avatar uploads
393
+ *
394
+ * @param int $bytes WordPress default byte size check
395
+ * @return int Maximum byte size
396
+ */
397
+ public function upload_size_limit( $bytes ) {
398
+ return apply_filters( 'simple_local_avatars_upload_limit', $bytes );
399
+ }
400
+
401
+ /**
402
+ * Runs when a user clicks the Remove button for the avatar
403
+ */
404
+ public function action_remove_simple_local_avatar() {
405
+ if ( ! empty( $_GET['user_id'] ) && ! empty( $_GET['_wpnonce'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'remove_simple_local_avatar_nonce' ) ) {
406
+ $user_id = (int) $_GET['user_id'];
407
+
408
+ if ( ! current_user_can('edit_user', $user_id) )
409
+ wp_die( __('You do not have permission to edit this user.') );
410
+
411
+ $this->avatar_delete( $user_id ); // delete old images if successful
412
+
413
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
414
+ echo get_simple_local_avatar( $user_id );
415
  }
416
+
417
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
418
+ die;
419
+ }
420
+
421
+ /**
422
+ * AJAX callback for assigning media ID fetched from media library to user
423
+ */
424
+ public function ajax_assign_simple_local_avatar_media() {
425
+ // check required information and permissions
426
+ if ( empty( $_POST['user_id'] ) || empty( $_POST['media_id'] ) || ! current_user_can( 'upload_files' ) || ! current_user_can( 'edit_user', $_POST['user_id'] ) || empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'assign_simple_local_avatar_nonce' ) )
427
+ die;
428
+
429
+ $media_id = (int) $_POST['media_id'];
430
+ $user_id = (int) $_POST['user_id'];
431
+
432
+ // ensure the media is real is an image
433
+ if ( wp_attachment_is_image( $media_id ) )
434
+ $this->assign_new_user_avatar( $media_id, $user_id );
435
+
436
+ echo get_simple_local_avatar( $user_id );
437
+
438
+ die;
439
  }
440
 
441
  /**
445
  remove_action( 'get_avatar', array( $this, 'get_avatar' ) );
446
  return $avatar_defaults;
447
  }
448
+
449
  /**
450
+ * Delete avatars based on a user_id
451
+ *
452
+ * @param int $user_id
453
  */
454
  public function avatar_delete( $user_id ) {
455
+ $old_avatars = (array) get_user_meta( $user_id, 'simple_local_avatar', true );
456
+
457
+ if ( empty( $old_avatars ) )
458
+ return;
459
+
460
+ // if it was uploaded media, don't erase the full size or try to erase an the ID
461
+ if ( array_key_exists( 'media_id', $old_avatars ) )
462
+ unset( $old_avatars['media_id'], $old_avatars['full'] );
463
+
464
+ if ( ! empty( $old_avatars ) ) {
465
+ $upload_path = wp_upload_dir();
466
+
467
  foreach ($old_avatars as $old_avatar ) {
468
+ // derive the path for the file based on the upload directory
469
  $old_avatar_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $old_avatar );
470
+ if ( file_exists( $old_avatar_path ) )
471
+ unlink( $old_avatar_path );
472
  }
473
  }
474
+
475
  delete_user_meta( $user_id, 'simple_local_avatar' );
476
+ delete_user_meta( $user_id, 'simple_local_avatar_rating' );
477
  }
478
+
479
+ /**
480
+ * Creates a unique, meaningful file name for uploaded avatars.
481
+ *
482
+ * @param string $dir Path for file
483
+ * @param string $name Filename
484
+ * @param string $ext File extension (e.g. ".jpg")
485
+ * @return string Final filename
486
+ */
487
  public function unique_filename_callback( $dir, $name, $ext ) {
488
  $user = get_user_by( 'id', (int) $this->user_id_being_edited );
489
+ $name = $base_name = sanitize_file_name( $user->display_name . '_avatar_' . time() );
490
+
491
+ // ensure no conflicts with existing file names
492
  $number = 1;
 
493
  while ( file_exists( $dir . "/$name$ext" ) ) {
494
  $name = $base_name . '_' . $number;
495
  $number++;
497
 
498
  return $name . $ext;
499
  }
500
+
501
+ /**
502
+ * Adds errors based on avatar upload problems.
503
+ *
504
+ * @param WP_Error $errors Error messages for user profile screen.
505
+ */
506
+ public function user_profile_update_errors( WP_Error $errors ) {
507
+ $errors->add( 'avatar_error', $this->avatar_upload_error );
508
+ }
509
  }
510
 
511
  $simple_local_avatars = new Simple_Local_Avatars;
519
  * @param string $alt Alternate text to use in image tag. Defaults to blank
520
  * @return string <img> tag for the user's avatar
521
  */
522
+ function get_simple_local_avatar( $id_or_email, $size = 96, $default = '', $alt = '' ) {
523
  global $simple_local_avatars;
524
  $avatar = $simple_local_avatars->get_avatar( '', $id_or_email, $size, $default, $alt );
525
 
526
+ if ( empty ( $avatar ) ) {
527
+ remove_action( 'get_avatar', array( $simple_local_avatars, 'get_avatar' ) );
528
  $avatar = get_avatar( $id_or_email, $size, $default, $alt );
529
+ add_action( 'get_avatar', array( $simple_local_avatars, 'get_avatar' ) );
530
+ }
531
 
532
  return $avatar;
533
  }
534
 
535
+ if ( ! function_exists( 'get_avatar' ) && ( $simple_local_avatars_options = get_option('simple_local_avatars') ) && ! empty( $simple_local_avatars_options['only'] ) ) :
536
+
537
+ /**
538
+ * Retrieve the avatar for a user who provided a user ID or email address.
539
+ *
540
+ * @param int|string|object $id_or_email A user ID, email address, or comment object
541
+ * @param int $size Size of the avatar image
542
+ * @param string $default URL to a default image to use if no avatar is available
543
+ * @param string $alt Alternative text to use in image tag. Defaults to blank
544
+ * @return string <img> tag for the user's avatar
545
+ */
546
+ function get_avatar( $id_or_email, $size = 96, $default = '', $alt = '' ) {
547
+ global $simple_local_avatars;
548
+
549
+ if ( ! get_option('show_avatars') )
550
+ return false;
551
+
552
+ $safe_alt = empty( $alt ) ? '' : esc_attr( $alt );
553
+
554
+ if ( !is_numeric($size) )
555
+ $size = 96;
556
+
557
+ if ( ! $avatar = $simple_local_avatars->get_avatar( '', $id_or_email, $size, $default, $alt ) ) :
558
+
559
+ if ( empty($default) ) {
560
+ $avatar_default = get_option('avatar_default');
561
+ if ( empty($avatar_default) )
562
+ $default = 'mystery';
563
+ else
564
+ $default = $avatar_default;
565
+ }
566
+
567
+ $host = is_ssl() ? 'https://secure.gravatar.com' : 'http://0.gravatar.com';
568
+
569
+ if ( 'mystery' == $default )
570
+ $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}"; // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com')
571
+ elseif ( 'blank' == $default )
572
+ $default = includes_url( 'images/blank.gif' );
573
+ elseif ( 'gravatar_default' == $default )
574
+ $default = "$host/avatar/?s={$size}";
575
+ else
576
+ $default = "$host/avatar/?d=$default&amp;s={$size}";
577
+
578
+ $avatar = "<img alt='{$safe_alt}' src='" . $default . "' class='avatar avatar-{$size} photo avatar-default' height='{$size}' width='{$size}' />";
579
+
580
+ endif;
581
+
582
+ return apply_filters('get_avatar', $avatar, $id_or_email, $size, $default, $alt);
583
+ }
584
+
585
+ endif;
586
+
587
  /**
588
  * on uninstallation, remove the custom field from the users and delete the local avatars
589
  */
592
 
593
  function simple_local_avatars_uninstall() {
594
  $simple_local_avatars = new Simple_Local_Avatars;
595
+ $users = get_users(array(
596
+ 'meta_key' => 'simple_local_avatar',
597
+ 'fields' => 'ids',
598
+ ));
599
+
600
+ foreach ( $users as $user_id ):
601
+ $simple_local_avatars->avatar_delete( $user_id );
602
+ endforeach;
603
 
604
+ delete_option('simple_local_avatars');
605
  }