Simple Local Avatars - Version 2.2.0

Version Description

  • Added: $args parameter to get_simple_local_avatar function (props @dinhtungdu, @heyjones, @dkotter, @sumnercreations, @dshanske)
  • Added: Simple_Local_Avatars::get_avatar_data(), Simple_Local_Avatars::get_simple_local_avatar_url(), and Simple_Local_Avatars::get_default_avatar_url() methods (props @dinhtungdu, @heyjones, @dkotter, @sumnercreations, @dshanske)
  • Added: Ability to retrieve avatar with WP_Post object (props @oscarssanchez, @blobaugh)
  • Added: class and ID to Avatar section on Profile Page to allow easier styling (props @dinhtungdu)
  • Added: WP Acceptance test coverage (props @dinhtungdu)
  • Changed: Switched to pre_get_avatar_data filter (props @dinhtungdu, @heyjones, @dkotter, @sumnercreations, @dshanske)
  • Changed: assign_new_user_avatar function to public (props @tripflex)
  • Changed: Split the main class into its own file, added unit tests, and set up testing GitHub action (props @dinhtungdu, @helen, @stevegrunwell)
  • Changed: New plugin banner and icon (props @JackieKjome)
  • Changed: Bump WordPress version "tested up to" 5.5 (props @Waka867, @tmoorewp, @jeffpaul, @dinhtungdu)
  • Changed: GitHub Actions from HCL to YAML workflow syntax (props @jeffpaul)
  • Changed: Documentation updates (props @jeffpaul)
  • Fixed: Initialize Simple_Local_Avatars on the $simple_local_avatars global, enabling bundling plugin with composer (props @pauldewouters, @adamsilverstein)
  • Removed: get_avatar function that overrides the core function (props @dinhtungdu, @heyjones, @dkotter, @sumnercreations, @dshanske)
Download this release

Release Info

Developer 10upbot
Plugin Icon 128x128 Simple Local Avatars
Version 2.2.0
Comparing to
See all releases

Code changes from version 2.1.1 to 2.2.0

includes/class-simple-local-avatars.php ADDED
@@ -0,0 +1,681 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class: Simple_Local_Avatars
4
+ * Adds an avatar upload field to user profiles.
5
+ */
6
+ class Simple_Local_Avatars {
7
+ private $user_id_being_edited, $avatar_upload_error, $remove_nonce, $avatar_ratings;
8
+ public $options;
9
+
10
+ /**
11
+ * Set up the hooks and default values
12
+ */
13
+ public function __construct() {
14
+ $this->options = (array) get_option( 'simple_local_avatars' );
15
+ $this->avatar_ratings = array(
16
+ 'G' => __( 'G &#8212; Suitable for all audiences', 'simple-local-avatars' ),
17
+ 'PG' => __( 'PG &#8212; Possibly offensive, usually for audiences 13 and above', 'simple-local-avatars' ),
18
+ 'R' => __( 'R &#8212; Intended for adult audiences above 17', 'simple-local-avatars' ),
19
+ 'X' => __( 'X &#8212; Even more mature than above', 'simple-local-avatars' ),
20
+ );
21
+
22
+ $this->add_hooks();
23
+ }
24
+
25
+ /**
26
+ * Register actions and filters.
27
+ */
28
+ public function add_hooks() {
29
+ add_filter( 'pre_get_avatar_data', array( $this, 'get_avatar_data' ), 10, 2 );
30
+
31
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
32
+
33
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
34
+ add_action( 'show_user_profile', array( $this, 'edit_user_profile' ) );
35
+ add_action( 'edit_user_profile', array( $this, 'edit_user_profile' ) );
36
+
37
+ add_action( 'personal_options_update', array( $this, 'edit_user_profile_update' ) );
38
+ add_action( 'edit_user_profile_update', array( $this, 'edit_user_profile_update' ) );
39
+ add_action( 'admin_action_remove-simple-local-avatar', array( $this, 'action_remove_simple_local_avatar' ) );
40
+ add_action( 'wp_ajax_assign_simple_local_avatar_media', array( $this, 'ajax_assign_simple_local_avatar_media' ) );
41
+ add_action( 'wp_ajax_remove_simple_local_avatar', array( $this, 'action_remove_simple_local_avatar' ) );
42
+ add_action( 'user_edit_form_tag', array( $this, 'user_edit_form_tag' ) );
43
+
44
+ add_action( 'rest_api_init', array( $this, 'register_rest_fields' ) );
45
+ }
46
+
47
+ /**
48
+ * Retrieve the local avatar for a user who provided a user ID, email address or post/comment object.
49
+ *
50
+ * @param string $avatar Avatar return by original function
51
+ * @param int|string|object $id_or_email A user ID, email address, or post/comment object
52
+ * @param int $size Size of the avatar image
53
+ * @param string $default URL to a default image to use if no avatar is available
54
+ * @param string $alt Alternative text to use in image tag. Defaults to blank
55
+ * @param array $args Optional. Extra arguments to retrieve the avatar.
56
+ *
57
+ * @return string <img> tag for the user's avatar
58
+ */
59
+ public function get_avatar( $avatar = '', $id_or_email = '', $size = 96, $default = '', $alt = '', $args = array() ) {
60
+ return apply_filters( 'simple_local_avatar', get_avatar( $id_or_email, $size, $default, $alt, $args ) );
61
+ }
62
+
63
+ /**
64
+ * Filter avatar data early to add avatar url if needed. This filter hooks
65
+ * before Gravatar setup to prevent wasted requests.
66
+ *
67
+ * @since 2.2.0
68
+ *
69
+ * @param array $args Arguments passed to get_avatar_data(), after processing.
70
+ * @param mixed $id_or_email The Gravatar to retrieve. Accepts a user ID, Gravatar MD5 hash,
71
+ * user email, WP_User object, WP_Post object, or WP_Comment object.
72
+ */
73
+ public function get_avatar_data( $args, $id_or_email ) {
74
+ if ( ! empty( $args['force_default'] ) ) {
75
+ return $args;
76
+ }
77
+
78
+ $simple_local_avatar_url = $this->get_simple_local_avatar_url( $id_or_email, $args['size'] );
79
+ if ( $simple_local_avatar_url ) {
80
+ $args['url'] = $simple_local_avatar_url;
81
+ }
82
+
83
+ // Local only mode
84
+ if ( ! $simple_local_avatar_url && ! empty( $this->options['only'] ) ) {
85
+ $args['url'] = $this->get_default_avatar_url( $args['size'] );
86
+ }
87
+
88
+ if ( ! empty( $args['url'] ) ) {
89
+ $args['found_avatar'] = true;
90
+ }
91
+
92
+ return $args;
93
+ }
94
+
95
+ /**
96
+ * Get local avatar url.
97
+ *
98
+ * @since 2.2.0
99
+ *
100
+ * @param mixed $id_or_email The Gravatar to retrieve. Accepts a user ID, Gravatar MD5 hash,
101
+ * user email, WP_User object, WP_Post object, or WP_Comment object.
102
+ * @param int $size Requested avatar size.
103
+ */
104
+ public function get_simple_local_avatar_url( $id_or_email, $size ) {
105
+ if ( is_numeric( $id_or_email ) ) {
106
+ $user_id = (int) $id_or_email;
107
+ } elseif ( is_string( $id_or_email ) && ( $user = get_user_by( 'email', $id_or_email ) ) ) {
108
+ $user_id = $user->ID;
109
+ } elseif ( is_object( $id_or_email ) && ! empty( $id_or_email->user_id ) ) {
110
+ $user_id = (int) $id_or_email->user_id;
111
+ } elseif ( $id_or_email instanceof WP_Post && ! empty( $id_or_email->post_author ) ) {
112
+ $user_id = (int) $id_or_email->post_author;
113
+ }
114
+
115
+ if ( empty( $user_id ) ) {
116
+ return '';
117
+ }
118
+
119
+ // Fetch local avatar from meta and make sure it's properly set.
120
+ $local_avatars = get_user_meta( $user_id, 'simple_local_avatar', true );
121
+ if ( empty( $local_avatars['full'] ) ) {
122
+ return '';
123
+ }
124
+
125
+ // check rating
126
+ $avatar_rating = get_user_meta( $user_id, 'simple_local_avatar_rating', true );
127
+ if ( ! empty( $avatar_rating ) && 'G' !== $avatar_rating && ( $site_rating = get_option( 'avatar_rating' ) ) ) {
128
+ $ratings = array_keys( $this->avatar_ratings );
129
+ $site_rating_weight = array_search( $site_rating, $ratings );
130
+ $avatar_rating_weight = array_search( $avatar_rating, $ratings );
131
+ if ( false !== $avatar_rating_weight && $avatar_rating_weight > $site_rating_weight ) {
132
+ return '';
133
+ }
134
+ }
135
+
136
+ // handle "real" media
137
+ if ( ! empty( $local_avatars['media_id'] ) ) {
138
+ // has the media been deleted?
139
+ if ( ! $avatar_full_path = get_attached_file( $local_avatars['media_id'] ) ) {
140
+ return '';
141
+ }
142
+ }
143
+
144
+ $size = (int) $size;
145
+
146
+ // Generate a new size.
147
+ if ( ! array_key_exists( $size, $local_avatars ) ) {
148
+ $local_avatars[ $size ] = $local_avatars['full']; // just in case of failure elsewhere
149
+
150
+ // allow automatic rescaling to be turned off
151
+ if ( apply_filters( 'simple_local_avatars_dynamic_resize', true ) ) :
152
+
153
+ $upload_path = wp_upload_dir();
154
+
155
+ // get path for image by converting URL, unless its already been set, thanks to using media library approach
156
+ if ( ! isset( $avatar_full_path ) ) {
157
+ $avatar_full_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $local_avatars['full'] );
158
+ }
159
+
160
+ // generate the new size
161
+ $editor = wp_get_image_editor( $avatar_full_path );
162
+ if ( ! is_wp_error( $editor ) ) {
163
+ $resized = $editor->resize( $size, $size, true );
164
+ if ( ! is_wp_error( $resized ) ) {
165
+ $dest_file = $editor->generate_filename();
166
+ $saved = $editor->save( $dest_file );
167
+ if ( ! is_wp_error( $saved ) ) {
168
+ $local_avatars[ $size ] = str_replace( $upload_path['basedir'], $upload_path['baseurl'], $dest_file );
169
+ }
170
+ }
171
+ }
172
+
173
+ // save updated avatar sizes
174
+ update_user_meta( $user_id, 'simple_local_avatar', $local_avatars );
175
+
176
+ endif;
177
+ }
178
+
179
+ if ( 'http' !== substr( $local_avatars[ $size ], 0, 4 ) ) {
180
+ $local_avatars[ $size ] = home_url( $local_avatars[ $size ] );
181
+ }
182
+
183
+ return esc_url( $local_avatars[ $size ] );
184
+ }
185
+
186
+ /**
187
+ * Get default avatar url
188
+ *
189
+ * @since 2.2.0
190
+ *
191
+ * @param int $size Requested avatar size.
192
+ */
193
+ public function get_default_avatar_url( $size ) {
194
+ if ( empty( $default ) ) {
195
+ $avatar_default = get_option( 'avatar_default' );
196
+ if ( empty( $avatar_default ) ) {
197
+ $default = 'mystery';
198
+ } else {
199
+ $default = $avatar_default;
200
+ }
201
+ }
202
+
203
+ $host = is_ssl() ? 'https://secure.gravatar.com' : 'http://0.gravatar.com';
204
+
205
+ if ( 'mystery' === $default ) {
206
+ $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}"; // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com')
207
+ } elseif ( 'blank' === $default ) {
208
+ $default = includes_url( 'images/blank.gif' );
209
+ } elseif ( 'gravatar_default' === $default ) {
210
+ $default = "$host/avatar/?s={$size}";
211
+ } else {
212
+ $default = "$host/avatar/?d=$default&amp;s={$size}";
213
+ }
214
+
215
+ return $default;
216
+ }
217
+
218
+ /**
219
+ * Register admin settings.
220
+ */
221
+ public function admin_init() {
222
+ // upgrade pre 2.0 option
223
+ if ( $old_ops = get_option( 'simple_local_avatars_caps' ) ) {
224
+ if ( ! empty( $old_ops['simple_local_avatars_caps'] ) ) {
225
+ update_option( 'simple_local_avatars', array( 'caps' => 1 ) );
226
+ }
227
+
228
+ delete_option( 'simple_local_avatar_caps' );
229
+ }
230
+
231
+ register_setting( 'discussion', 'simple_local_avatars', array( $this, 'sanitize_options' ) );
232
+ add_settings_field(
233
+ 'simple-local-avatars-only',
234
+ __( 'Local Avatars Only', 'simple-local-avatars' ),
235
+ array( $this, 'avatar_settings_field' ),
236
+ 'discussion',
237
+ 'avatars',
238
+ array(
239
+ 'key' => 'only',
240
+ 'desc' => __( 'Only allow local avatars (still uses Gravatar for default avatars)', 'simple-local-avatars' ),
241
+ )
242
+ );
243
+ add_settings_field(
244
+ 'simple-local-avatars-caps',
245
+ __( 'Local Upload Permissions', 'simple-local-avatars' ),
246
+ array( $this, 'avatar_settings_field' ),
247
+ 'discussion',
248
+ 'avatars',
249
+ array(
250
+ 'key' => 'caps',
251
+ 'desc' => __( 'Only allow users with file upload capabilities to upload local avatars (Authors and above)', 'simple-local-avatars' ),
252
+ )
253
+ );
254
+ }
255
+
256
+ /**
257
+ * Add scripts to the profile editing page
258
+ *
259
+ * @param string $hook_suffix Page hook
260
+ */
261
+ public function admin_enqueue_scripts( $hook_suffix ) {
262
+ if ( 'profile.php' !== $hook_suffix && 'user-edit.php' !== $hook_suffix ) {
263
+ return;
264
+ }
265
+
266
+ if ( current_user_can( 'upload_files' ) ) {
267
+ wp_enqueue_media();
268
+ }
269
+
270
+ $user_id = ( 'profile.php' === $hook_suffix ) ? get_current_user_id() : (int) $_GET['user_id'];
271
+
272
+ $this->remove_nonce = wp_create_nonce( 'remove_simple_local_avatar_nonce' );
273
+
274
+ $script_name_append = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.dev' : '';
275
+ wp_enqueue_script( 'simple-local-avatars', plugins_url( '', dirname( __FILE__ ) ) . '/simple-local-avatars' . $script_name_append . '.js', array( 'jquery' ), false, true );
276
+ wp_localize_script(
277
+ 'simple-local-avatars',
278
+ 'i10n_SimpleLocalAvatars',
279
+ array(
280
+ 'user_id' => $user_id,
281
+ 'insertMediaTitle' => __( 'Choose an Avatar', 'simple-local-avatars' ),
282
+ 'insertIntoPost' => __( 'Set as avatar', 'simple-local-avatars' ),
283
+ 'deleteNonce' => $this->remove_nonce,
284
+ 'mediaNonce' => wp_create_nonce( 'assign_simple_local_avatar_nonce' ),
285
+ )
286
+ );
287
+ }
288
+
289
+ /**
290
+ * Sanitize new settings field before saving
291
+ *
292
+ * @param array|string $input Passed input values to sanitize
293
+ * @return array|string Sanitized input fields
294
+ */
295
+ public function sanitize_options( $input ) {
296
+ $new_input['caps'] = empty( $input['caps'] ) ? 0 : 1;
297
+ $new_input['only'] = empty( $input['only'] ) ? 0 : 1;
298
+ return $new_input;
299
+ }
300
+
301
+ /**
302
+ * Settings field for avatar upload capabilities
303
+ *
304
+ * @param array $args Field arguments
305
+ */
306
+ public function avatar_settings_field( $args ) {
307
+ $args = wp_parse_args(
308
+ $args,
309
+ array(
310
+ 'key' => '',
311
+ 'desc' => '',
312
+ )
313
+ );
314
+
315
+ if ( empty( $this->options[ $args['key'] ] ) ) {
316
+ $this->options[ $args['key'] ] = 0;
317
+ }
318
+
319
+ echo '
320
+ <label for="simple-local-avatars-' . esc_attr( $args['key'] ) . '">
321
+ <input type="checkbox" name="simple_local_avatars[' . esc_attr( $args['key'] ) . ']" id="simple-local-avatars-' . esc_attr( $args['key'] ) . '" value="1" ' . checked( $this->options[ $args['key'] ], 1, false ) . ' />
322
+ ' . esc_html( $args['desc'] ) . '
323
+ </label>
324
+ ';
325
+ }
326
+
327
+ /**
328
+ * Output new Avatar fields to user editing / profile screen
329
+ *
330
+ * @param object $profileuser User object
331
+ */
332
+ public function edit_user_profile( $profileuser ) {
333
+ ?>
334
+ <div id="simple-local-avatar-section">
335
+ <h3><?php esc_html_e( 'Avatar', 'simple-local-avatars' ); ?></h3>
336
+
337
+ <table class="form-table">
338
+ <tr class="upload-avatar-row">
339
+ <th scope="row"><label for="simple-local-avatar"><?php esc_html_e( 'Upload Avatar', 'simple-local-avatars' ); ?></label></th>
340
+ <td style="width: 50px;" id="simple-local-avatar-photo">
341
+ <?php
342
+ add_filter( 'pre_option_avatar_rating', '__return_null' ); // ignore ratings here
343
+ echo get_simple_local_avatar( $profileuser->ID );
344
+ remove_filter( 'pre_option_avatar_rating', '__return_null' );
345
+ ?>
346
+ </td>
347
+ <td>
348
+ <?php
349
+ if ( ! $upload_rights = current_user_can( 'upload_files' ) ) {
350
+ $upload_rights = empty( $this->options['caps'] );
351
+ }
352
+
353
+ if ( $upload_rights ) {
354
+ do_action( 'simple_local_avatar_notices' );
355
+ wp_nonce_field( 'simple_local_avatar_nonce', '_simple_local_avatar_nonce', false );
356
+ $remove_url = add_query_arg(
357
+ array(
358
+ 'action' => 'remove-simple-local-avatar',
359
+ 'user_id' => $profileuser->ID,
360
+ '_wpnonce' => $this->remove_nonce,
361
+ )
362
+ );
363
+ ?>
364
+ <?php
365
+ // if user is author and above hide the choose file option
366
+ // force them to use the WP Media Selector
367
+ if ( ! current_user_can( 'upload_files' ) ) {
368
+ ?>
369
+ <p style="display: inline-block; width: 26em;">
370
+ <span class="description"><?php esc_html_e( 'Choose an image from your computer:' ); ?></span><br />
371
+ <input type="file" name="simple-local-avatar" id="simple-local-avatar" class="standard-text" />
372
+ <span class="spinner" id="simple-local-avatar-spinner"></span>
373
+ </p>
374
+ <?php } ?>
375
+ <p>
376
+ <?php if ( current_user_can( 'upload_files' ) && did_action( 'wp_enqueue_media' ) ) : ?>
377
+ <a href="#" class="button hide-if-no-js" id="simple-local-avatar-media"><?php esc_html_e( 'Choose from Media Library', 'simple-local-avatars' ); ?></a> &nbsp;
378
+ <?php endif; ?>
379
+ <a
380
+ href="<?php echo esc_url( $remove_url ); ?>"
381
+ class="button item-delete submitdelete deletion"
382
+ id="simple-local-avatar-remove"
383
+ <?php echo empty( $profileuser->simple_local_avatar ) ? ' style="display:none;"' : ''; ?>
384
+ >
385
+ <?php esc_html_e( 'Delete local avatar', 'simple-local-avatars' ); ?>
386
+ </a>
387
+ </p>
388
+ <?php
389
+ } else {
390
+ if ( empty( $profileuser->simple_local_avatar ) ) {
391
+ echo '<span class="description">' . esc_html__( 'No local avatar is set. Set up your avatar at Gravatar.com.', 'simple-local-avatars' ) . '</span>';
392
+ } else {
393
+ echo '<span class="description">' . esc_html__( 'You do not have media management permissions. To change your local avatar, contact the blog administrator.', 'simple-local-avatars' ) . '</span>';
394
+ }
395
+ }
396
+ ?>
397
+ </td>
398
+ </tr>
399
+ <tr class="ratings-row">
400
+ <th scope="row"><?php esc_html_e( 'Rating' ); ?></th>
401
+ <td colspan="2">
402
+ <fieldset id="simple-local-avatar-ratings" <?php disabled( empty( $profileuser->simple_local_avatar ) ); ?>>
403
+ <legend class="screen-reader-text"><span><?php esc_html_e( 'Rating' ); ?></span></legend>
404
+ <?php
405
+ if ( empty( $profileuser->simple_local_avatar_rating ) || ! array_key_exists( $profileuser->simple_local_avatar_rating, $this->avatar_ratings ) ) {
406
+ $profileuser->simple_local_avatar_rating = 'G';
407
+ }
408
+
409
+ foreach ( $this->avatar_ratings as $key => $rating ) :
410
+ 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 />";
411
+ endforeach;
412
+ ?>
413
+ <p class="description"><?php esc_html_e( 'If the local avatar is inappropriate for this site, Gravatar will be attempted.', 'simple-local-avatars' ); ?></p>
414
+ </fieldset></td>
415
+ </tr>
416
+ </table>
417
+ </div>
418
+ <?php
419
+ }
420
+
421
+ /**
422
+ * Ensure that the profile form has proper encoding type
423
+ */
424
+ public function user_edit_form_tag() {
425
+ echo 'enctype="multipart/form-data"';
426
+ }
427
+
428
+ /**
429
+ * Saves avatar image to a user
430
+ *
431
+ * @param int|string $url_or_media_id Local URL for avatar or ID of attachment
432
+ * @param int $user_id ID of user to assign image to
433
+ */
434
+ public function assign_new_user_avatar( $url_or_media_id, $user_id ) {
435
+ // delete the old avatar
436
+ $this->avatar_delete( $user_id ); // delete old images if successful
437
+
438
+ $meta_value = array();
439
+
440
+ // set the new avatar
441
+ if ( is_int( $url_or_media_id ) ) {
442
+ $meta_value['media_id'] = $url_or_media_id;
443
+ $url_or_media_id = wp_get_attachment_url( $url_or_media_id );
444
+ }
445
+
446
+ $meta_value['full'] = $url_or_media_id;
447
+
448
+ update_user_meta( $user_id, 'simple_local_avatar', $meta_value ); // save user information (overwriting old)
449
+ }
450
+
451
+ /**
452
+ * Save any changes to the user profile
453
+ *
454
+ * @param int $user_id ID of user being updated
455
+ */
456
+ public function edit_user_profile_update( $user_id ) {
457
+ // check nonces
458
+ if ( empty( $_POST['_simple_local_avatar_nonce'] ) || ! wp_verify_nonce( $_POST['_simple_local_avatar_nonce'], 'simple_local_avatar_nonce' ) ) {
459
+ return;
460
+ }
461
+
462
+ // check for uploaded files
463
+ if ( ! empty( $_FILES['simple-local-avatar']['name'] ) ) :
464
+
465
+ // need to be more secure since low privelege users can upload
466
+ if ( false !== strpos( $_FILES['simple-local-avatar']['name'], '.php' ) ) {
467
+ $this->avatar_upload_error = __( 'For security reasons, the extension ".php" cannot be in your file name.', 'simple-local-avatars' );
468
+ add_action( 'user_profile_update_errors', array( $this, 'user_profile_update_errors' ) );
469
+ return;
470
+ }
471
+
472
+ // front end (theme my profile etc) support
473
+ if ( ! function_exists( 'media_handle_upload' ) ) {
474
+ include_once ABSPATH . 'wp-admin/includes/media.php';
475
+ }
476
+
477
+ // allow developers to override file size upload limit for avatars
478
+ add_filter( 'upload_size_limit', array( $this, 'upload_size_limit' ) );
479
+
480
+ $this->user_id_being_edited = $user_id; // make user_id known to unique_filename_callback function
481
+ $avatar_id = media_handle_upload(
482
+ 'simple-local-avatar',
483
+ 0,
484
+ array(),
485
+ array(
486
+ 'mimes' => array(
487
+ 'jpg|jpeg|jpe' => 'image/jpeg',
488
+ 'gif' => 'image/gif',
489
+ 'png' => 'image/png',
490
+ ),
491
+ 'test_form' => false,
492
+ 'unique_filename_callback' => array( $this, 'unique_filename_callback' ),
493
+ )
494
+ );
495
+
496
+ remove_filter( 'upload_size_limit', array( $this, 'upload_size_limit' ) );
497
+
498
+ if ( is_wp_error( $avatar_id ) ) { // handle failures.
499
+ $this->avatar_upload_error = '<strong>' . __( 'There was an error uploading the avatar:', 'simple-local-avatars' ) . '</strong> ' . esc_html( $avatar_id->get_error_message() );
500
+ add_action( 'user_profile_update_errors', array( $this, 'user_profile_update_errors' ) );
501
+ return;
502
+ }
503
+
504
+ $this->assign_new_user_avatar( $avatar_id, $user_id );
505
+
506
+ endif;
507
+
508
+ // Handle ratings
509
+ if ( isset( $avatar_id ) || $avatar = get_user_meta( $user_id, 'simple_local_avatar', true ) ) {
510
+ if ( empty( $_POST['simple_local_avatar_rating'] ) || ! array_key_exists( $_POST['simple_local_avatar_rating'], $this->avatar_ratings ) ) {
511
+ $_POST['simple_local_avatar_rating'] = key( $this->avatar_ratings );
512
+ }
513
+
514
+ update_user_meta( $user_id, 'simple_local_avatar_rating', $_POST['simple_local_avatar_rating'] );
515
+ }
516
+ }
517
+
518
+ /**
519
+ * Allow developers to override the maximum allowable file size for avatar uploads
520
+ *
521
+ * @param int $bytes WordPress default byte size check
522
+ * @return int Maximum byte size
523
+ */
524
+ public function upload_size_limit( $bytes ) {
525
+ return apply_filters( 'simple_local_avatars_upload_limit', $bytes );
526
+ }
527
+
528
+ /**
529
+ * Runs when a user clicks the Remove button for the avatar
530
+ */
531
+ public function action_remove_simple_local_avatar() {
532
+ if ( ! empty( $_GET['user_id'] ) && ! empty( $_GET['_wpnonce'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'remove_simple_local_avatar_nonce' ) ) {
533
+ $user_id = (int) $_GET['user_id'];
534
+
535
+ if ( ! current_user_can( 'edit_user', $user_id ) ) {
536
+ wp_die( esc_html__( 'You do not have permission to edit this user.', 'simple-local-avatars' ) );
537
+ }
538
+
539
+ $this->avatar_delete( $user_id ); // delete old images if successful
540
+
541
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
542
+ echo get_simple_local_avatar( $user_id );
543
+ }
544
+ }
545
+
546
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
547
+ die;
548
+ }
549
+ }
550
+
551
+ /**
552
+ * AJAX callback for assigning media ID fetched from media library to user
553
+ */
554
+ public function ajax_assign_simple_local_avatar_media() {
555
+ // check required information and permissions
556
+ 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' ) ) {
557
+ die;
558
+ }
559
+
560
+ $media_id = (int) $_POST['media_id'];
561
+ $user_id = (int) $_POST['user_id'];
562
+
563
+ // ensure the media is real is an image
564
+ if ( wp_attachment_is_image( $media_id ) ) {
565
+ $this->assign_new_user_avatar( $media_id, $user_id );
566
+ }
567
+
568
+ echo get_simple_local_avatar( $user_id );
569
+
570
+ die;
571
+ }
572
+
573
+ /**
574
+ * Delete avatars based on a user_id
575
+ *
576
+ * @param int $user_id User ID.
577
+ */
578
+ public function avatar_delete( $user_id ) {
579
+ $old_avatars = (array) get_user_meta( $user_id, 'simple_local_avatar', true );
580
+
581
+ if ( empty( $old_avatars ) ) {
582
+ return;
583
+ }
584
+
585
+ // if it was uploaded media, don't erase the full size or try to erase an the ID
586
+ if ( array_key_exists( 'media_id', $old_avatars ) ) {
587
+ unset( $old_avatars['media_id'], $old_avatars['full'] );
588
+ }
589
+
590
+ if ( ! empty( $old_avatars ) ) {
591
+ $upload_path = wp_upload_dir();
592
+
593
+ foreach ( $old_avatars as $old_avatar ) {
594
+ // derive the path for the file based on the upload directory
595
+ $old_avatar_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $old_avatar );
596
+ if ( file_exists( $old_avatar_path ) ) {
597
+ unlink( $old_avatar_path );
598
+ }
599
+ }
600
+ }
601
+
602
+ delete_user_meta( $user_id, 'simple_local_avatar' );
603
+ delete_user_meta( $user_id, 'simple_local_avatar_rating' );
604
+ }
605
+
606
+ /**
607
+ * Creates a unique, meaningful file name for uploaded avatars.
608
+ *
609
+ * @param string $dir Path for file
610
+ * @param string $name Filename
611
+ * @param string $ext File extension (e.g. ".jpg")
612
+ * @return string Final filename
613
+ */
614
+ public function unique_filename_callback( $dir, $name, $ext ) {
615
+ $user = get_user_by( 'id', (int) $this->user_id_being_edited );
616
+ $name = $base_name = sanitize_file_name( $user->display_name . '_avatar_' . time() );
617
+
618
+ // ensure no conflicts with existing file names
619
+ $number = 1;
620
+ while ( file_exists( $dir . "/$name$ext" ) ) {
621
+ $name = $base_name . '_' . $number;
622
+ $number++;
623
+ }
624
+
625
+ return $name . $ext;
626
+ }
627
+
628
+ /**
629
+ * Adds errors based on avatar upload problems.
630
+ *
631
+ * @param WP_Error $errors Error messages for user profile screen.
632
+ */
633
+ public function user_profile_update_errors( WP_Error $errors ) {
634
+ $errors->add( 'avatar_error', $this->avatar_upload_error );
635
+ }
636
+
637
+ /**
638
+ * Registers the simple_local_avatar field in the REST API.
639
+ */
640
+ public function register_rest_fields() {
641
+ register_rest_field(
642
+ 'user',
643
+ 'simple_local_avatar',
644
+ array(
645
+ 'get_callback' => array( $this, 'get_avatar_rest' ),
646
+ 'update_callback' => array( $this, 'set_avatar_rest' ),
647
+ 'schema' => array(
648
+ 'description' => 'The users simple local avatar',
649
+ 'type' => 'object',
650
+ ),
651
+ )
652
+ );
653
+ }
654
+
655
+ /**
656
+ * Returns the simple_local_avatar meta key for the given user.
657
+ *
658
+ * @param object $user User object
659
+ */
660
+ public function get_avatar_rest( $user ) {
661
+ $local_avatar = get_user_meta( $user['id'], 'simple_local_avatar', true );
662
+ if ( empty( $local_avatar ) ) {
663
+ return;
664
+ }
665
+ return $local_avatar;
666
+ }
667
+
668
+ /**
669
+ * Updates the simple local avatar from a REST request.
670
+ *
671
+ * Since we are just adding a field to the existing user endpoint
672
+ * we don't need to worry about ensuring the calling user has proper permissions.
673
+ * Only the user or an administrator would be able to change the avatar.
674
+ *
675
+ * @param array $input Input submitted via REST request.
676
+ * @param object $user The user making the request.
677
+ */
678
+ public function set_avatar_rest( $input, $user ) {
679
+ $this->assign_new_user_avatar( $input['media_id'], $user->ID );
680
+ }
681
+ }
readme.txt CHANGED
@@ -3,13 +3,14 @@ Contributors: jakemgold, 10up, thinkoomph
3
  Donate link: https://10up.com/plugins/simple-local-avatars-wordpress/
4
  Tags: avatar, gravatar, user photos, users, profile
5
  Requires at least: 4.6
6
- Tested up to: 5.2
7
- Stable tag: 2.1.1
8
- Text Domain: simple-local-avatars
 
 
9
 
10
  Adds an avatar upload field to user profiles. Generates requested sizes on demand just like Gravatar!
11
 
12
-
13
  == Description ==
14
 
15
  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.
@@ -23,7 +24,6 @@ Just edit a user profile, and scroll down to the new "Avatar" field. The plug-in
23
  1. Let's you decide whether lower privilege users (subscribers, contributors) can upload their own avatar
24
  1. Enables rating of local avatars, just like Gravatar
25
 
26
-
27
  == Installation ==
28
 
29
  1. Install easily with the WordPress plugin control panel or manually download the plugin and upload the extracted folder to the `/wp-content/plugins/` directory
@@ -35,14 +35,28 @@ Use avatars in your theme using WordPress' built in `get_avatar()` function: [ht
35
 
36
  You can also use `get_simple_local_avatar()` (with the same arguments) to retreive local avatars a bit faster, but this will make your theme dependent on this plug-in.
37
 
38
-
39
  == Screenshots ==
40
 
41
  1. Avatar upload field on a user profile page
42
 
43
-
44
  == Changelog ==
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  = 2.1.1 =
47
  * Fixed: Do not delete avatars just because they don't exist on the local filesystem. This was occasionally dumping avatars when WordPress uploads were stored elsewhere, e.g. a cloud service.
48
 
@@ -72,7 +86,7 @@ You can also use `get_simple_local_avatar()` (with the same arguments) to retrei
72
  * Optimization for WordPress 3.2 / 3.3 (substitutes deprecated function)
73
 
74
  = 1.3 =
75
- * Avatar file name saved as "user-display-name_avatar" (or other image extension)
76
  * Russian localization added
77
  * Assorted minor code optimizations
78
 
@@ -109,7 +123,6 @@ You can also use `get_simple_local_avatar()` (with the same arguments) to retrei
109
  * All users (regardless of capabilities) can upload avatars by default. To limit avatar uploading to users with upload files capabilities (Authors and above), check the applicable option under Settings > Discussion. This was the default behavior in 1.0.
110
  * Localization support; German included
111
 
112
-
113
  == Upgrade Notice ==
114
 
115
  = 2.1 =
3
  Donate link: https://10up.com/plugins/simple-local-avatars-wordpress/
4
  Tags: avatar, gravatar, user photos, users, profile
5
  Requires at least: 4.6
6
+ Tested up to: 5.8
7
+ Requires PHP: 5.3
8
+ Stable tag: 2.2.0
9
+ License: GPLv2 or later
10
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
12
  Adds an avatar upload field to user profiles. Generates requested sizes on demand just like Gravatar!
13
 
 
14
  == Description ==
15
 
16
  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.
24
  1. Let's you decide whether lower privilege users (subscribers, contributors) can upload their own avatar
25
  1. Enables rating of local avatars, just like Gravatar
26
 
 
27
  == Installation ==
28
 
29
  1. Install easily with the WordPress plugin control panel or manually download the plugin and upload the extracted folder to the `/wp-content/plugins/` directory
35
 
36
  You can also use `get_simple_local_avatar()` (with the same arguments) to retreive local avatars a bit faster, but this will make your theme dependent on this plug-in.
37
 
 
38
  == Screenshots ==
39
 
40
  1. Avatar upload field on a user profile page
41
 
 
42
  == Changelog ==
43
 
44
+ = 2.2.0 =
45
+ * **Added:** `$args` parameter to `get_simple_local_avatar` function (props [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/), [@heyjones](https://github.com/heyjones), [@dkotter](https://profiles.wordpress.org/dkotter/), [@sumnercreations](https://github.com/sumnercreations), [@dshanske](https://profiles.wordpress.org/dshanske/))
46
+ * **Added:** `Simple_Local_Avatars::get_avatar_data()`, `Simple_Local_Avatars::get_simple_local_avatar_url()`, and `Simple_Local_Avatars::get_default_avatar_url()` methods (props [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/), [@heyjones](https://github.com/heyjones), [@dkotter](https://profiles.wordpress.org/dkotter/), [@sumnercreations](https://github.com/sumnercreations), [@dshanske](https://profiles.wordpress.org/dshanske/))
47
+ * **Added:** Ability to retrieve avatar with `WP_Post` object (props [@oscarssanchez](https://profiles.wordpress.org/oscarssanchez), [@blobaugh](https://profiles.wordpress.org/blobaugh))
48
+ * **Added:** class and ID to Avatar section on Profile Page to allow easier styling (props [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/))
49
+ * **Added:** [WP Acceptance](https://github.com/10up/wpacceptance/) test coverage (props [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/))
50
+ * **Changed:** Switched to `pre_get_avatar_data` filter (props [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/), [@heyjones](https://github.com/heyjones), [@dkotter](https://profiles.wordpress.org/dkotter/), [@sumnercreations](https://github.com/sumnercreations), [@dshanske](https://profiles.wordpress.org/dshanske/))
51
+ * **Changed:** `assign_new_user_avatar` function to public (props [@tripflex](https://profiles.wordpress.org/tripflex/))
52
+ * **Changed:** Split the main class into its own file, added unit tests, and set up testing GitHub action (props [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/), [@helen](https://profiles.wordpress.org/helen/), [@stevegrunwell](https://profiles.wordpress.org/stevegrunwell/))
53
+ * **Changed:** New plugin banner and icon (props [@JackieKjome](https://profiles.wordpress.org/jackiekjome/))
54
+ * **Changed:** Bump WordPress version "tested up to" 5.5 (props [@Waka867](https://github.com/Waka867), [@tmoorewp](https://profiles.wordpress.org/tmoorewp), [@jeffpaul](https://profiles.wordpress.org/jeffpaul), [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/))
55
+ * **Changed:** GitHub Actions from HCL to YAML workflow syntax (props [@jeffpaul](https://profiles.wordpress.org/jeffpaul))
56
+ * **Changed:** Documentation updates (props [@jeffpaul](https://profiles.wordpress.org/jeffpaul))
57
+ * **Fixed:** Initialize `Simple_Local_Avatars` on the `$simple_local_avatars` global, enabling bundling plugin with composer (props [@pauldewouters](https://profiles.wordpress.org/pauldewouters/), [@adamsilverstein](https://profiles.wordpress.org/adamsilverstein))
58
+ * **Removed:** `get_avatar` function that overrides the core function (props [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/), [@heyjones](https://github.com/heyjones), [@dkotter](https://profiles.wordpress.org/dkotter/), [@sumnercreations](https://github.com/sumnercreations), [@dshanske](https://profiles.wordpress.org/dshanske/))
59
+
60
  = 2.1.1 =
61
  * Fixed: Do not delete avatars just because they don't exist on the local filesystem. This was occasionally dumping avatars when WordPress uploads were stored elsewhere, e.g. a cloud service.
62
 
86
  * Optimization for WordPress 3.2 / 3.3 (substitutes deprecated function)
87
 
88
  = 1.3 =
89
+ * Avatar file name saved as "user-display-name_avatar" (or other image extension)
90
  * Russian localization added
91
  * Assorted minor code optimizations
92
 
123
  * All users (regardless of capabilities) can upload avatars by default. To limit avatar uploading to users with upload files capabilities (Authors and above), check the applicable option under Settings > Discussion. This was the default behavior in 1.0.
124
  * Localization support; German included
125
 
 
126
  == Upgrade Notice ==
127
 
128
  = 2.1 =
screenshot-1.png DELETED
Binary file
simple-local-avatars.php CHANGED
@@ -1,661 +1,60 @@
1
- <?php
2
- /**
3
- * Plugin Name: Simple Local Avatars
4
- * Plugin URI: https://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.1.1
7
- * Author: Jake Goldman, 10up
8
- * Author URI: https://10up.com
9
- * License: GPLv2 or later
10
- * Text Domain: simple-local-avatars
11
- */
12
-
13
- /**
14
- * add field to user profiles
15
- */
16
-
17
- class Simple_Local_Avatars {
18
- private $user_id_being_edited, $avatar_upload_error, $remove_nonce, $avatar_ratings;
19
- public $options;
20
-
21
- /**
22
- * Set up the hooks and default values
23
- */
24
- public function __construct() {
25
- $this->options = (array) get_option( 'simple_local_avatars' );
26
- $this->avatar_ratings = array(
27
- 'G' => __('G &#8212; Suitable for all audiences'),
28
- 'PG' => __('PG &#8212; Possibly offensive, usually for audiences 13 and above'),
29
- 'R' => __('R &#8212; Intended for adult audiences above 17'),
30
- 'X' => __('X &#8212; Even more mature than above')
31
- );
32
-
33
- // supplement remote avatars, but not if inside "local only" mode
34
- if ( empty( $this->options['only'] ) )
35
- add_filter( 'get_avatar', array( $this, 'get_avatar' ), 10, 5 );
36
-
37
- add_action( 'admin_init', array( $this, 'admin_init' ) );
38
-
39
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
40
- add_action( 'show_user_profile', array( $this, 'edit_user_profile' ) );
41
- add_action( 'edit_user_profile', array( $this, 'edit_user_profile' ) );
42
-
43
- add_action( 'personal_options_update', array( $this, 'edit_user_profile_update' ) );
44
- add_action( 'edit_user_profile_update', array( $this, 'edit_user_profile_update' ) );
45
- add_action( 'admin_action_remove-simple-local-avatar', array( $this, 'action_remove_simple_local_avatar' ) );
46
- add_action( 'wp_ajax_assign_simple_local_avatar_media', array( $this, 'ajax_assign_simple_local_avatar_media' ) );
47
- add_action( 'wp_ajax_remove_simple_local_avatar', array( $this, 'action_remove_simple_local_avatar' ) );
48
- add_action( 'user_edit_form_tag', array( $this, 'user_edit_form_tag' ) );
49
-
50
- add_filter( 'avatar_defaults', array( $this, 'avatar_defaults' ) );
51
-
52
- add_action( 'rest_api_init', array( $this, 'register_rest_fields' ) );
53
- }
54
-
55
- /**
56
- * Retrieve the local avatar for a user who provided a user ID or email address.
57
- *
58
- * @param string $avatar Avatar return by original function
59
- * @param int|string|object $id_or_email A user ID, email address, or comment object
60
- * @param int $size Size of the avatar image
61
- * @param string $default URL to a default image to use if no avatar is available
62
- * @param string $alt Alternative text to use in image tag. Defaults to blank
63
- * @return string <img> tag for the user's avatar
64
- */
65
- public function get_avatar( $avatar = '', $id_or_email = '', $size = 96, $default = '', $alt = '' ) {
66
- if ( is_numeric( $id_or_email ) )
67
- $user_id = (int) $id_or_email;
68
- elseif ( is_string( $id_or_email ) && ( $user = get_user_by( 'email', $id_or_email ) ) )
69
- $user_id = $user->ID;
70
- elseif ( is_object( $id_or_email ) && ! empty( $id_or_email->user_id ) )
71
- $user_id = (int) $id_or_email->user_id;
72
-
73
- if ( empty( $user_id ) )
74
- return $avatar;
75
-
76
- // fetch local avatar from meta and make sure it's properly ste
77
- $local_avatars = get_user_meta( $user_id, 'simple_local_avatar', true );
78
- if ( empty( $local_avatars['full'] ) )
79
- return $avatar;
80
-
81
- // check rating
82
- $avatar_rating = get_user_meta( $user_id, 'simple_local_avatar_rating', true );
83
- if ( ! empty( $avatar_rating ) && 'G' != $avatar_rating && ( $site_rating = get_option( 'avatar_rating' ) ) ) {
84
- $ratings = array_keys( $this->avatar_ratings );
85
- $site_rating_weight = array_search( $site_rating, $ratings );
86
- $avatar_rating_weight = array_search( $avatar_rating, $ratings );
87
- if ( false !== $avatar_rating_weight && $avatar_rating_weight > $site_rating_weight )
88
- return $avatar;
89
- }
90
-
91
- // handle "real" media
92
- if ( ! empty( $local_avatars['media_id'] ) ) {
93
- // has the media been deleted?
94
- if ( ! $avatar_full_path = get_attached_file( $local_avatars['media_id'] ) ) {
95
- return $avatar;
96
- }
97
- }
98
-
99
- $size = (int) $size;
100
-
101
- if ( empty( $alt ) )
102
- $alt = get_the_author_meta( 'display_name', $user_id );
103
-
104
- // generate a new size
105
- if ( ! array_key_exists( $size, $local_avatars ) ) {
106
- $local_avatars[$size] = $local_avatars['full']; // just in case of failure elsewhere
107
-
108
- // allow automatic rescaling to be turned off
109
- if ( $allow_dynamic_resizing = apply_filters( 'simple_local_avatars_dynamic_resize', true ) ) :
110
-
111
- $upload_path = wp_upload_dir();
112
-
113
- // get path for image by converting URL, unless its already been set, thanks to using media library approach
114
- if ( ! isset( $avatar_full_path ) )
115
- $avatar_full_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $local_avatars['full'] );
116
-
117
- // generate the new size
118
- $editor = wp_get_image_editor( $avatar_full_path );
119
- if ( ! is_wp_error( $editor ) ) {
120
- $resized = $editor->resize( $size, $size, true );
121
- if ( ! is_wp_error( $resized ) ) {
122
- $dest_file = $editor->generate_filename();
123
- $saved = $editor->save( $dest_file );
124
- if ( ! is_wp_error( $saved ) )
125
- $local_avatars[$size] = str_replace( $upload_path['basedir'], $upload_path['baseurl'], $dest_file );
126
- }
127
- }
128
-
129
- // save updated avatar sizes
130
- update_user_meta( $user_id, 'simple_local_avatar', $local_avatars );
131
-
132
- endif;
133
- }
134
-
135
- if ( 'http' != substr( $local_avatars[$size], 0, 4 ) )
136
- $local_avatars[$size] = home_url( $local_avatars[$size] );
137
-
138
- $author_class = is_author( $user_id ) ? ' current-author' : '' ;
139
- $avatar = "<img alt='" . esc_attr( $alt ) . "' src='" . esc_url( $local_avatars[$size] ) . "' class='avatar avatar-{$size}{$author_class} photo' height='{$size}' width='{$size}' />";
140
-
141
- return apply_filters( 'simple_local_avatar', $avatar );
142
- }
143
-
144
- public function admin_init() {
145
- // upgrade pre 2.0 option
146
- if ( $old_ops = get_option( 'simple_local_avatars_caps' ) ) {
147
- if ( ! empty( $old_ops['simple_local_avatars_caps'] ) )
148
- update_option( 'simple_local_avatars', array( 'caps' => 1 ) );
149
-
150
- delete_option( 'simple_local_avatar_caps' );
151
- }
152
-
153
- register_setting( 'discussion', 'simple_local_avatars', array( $this, 'sanitize_options' ) );
154
- add_settings_field(
155
- 'simple-local-avatars-only',
156
- __('Local Avatars Only','simple-local-avatars'),
157
- array( $this, 'avatar_settings_field' ),
158
- 'discussion',
159
- 'avatars',
160
- array(
161
- 'key' => 'only',
162
- 'desc' => __( 'Only allow local avatars (still uses Gravatar for default avatars)', 'simple-local-avatars' )
163
- )
164
- );
165
- add_settings_field(
166
- 'simple-local-avatars-caps',
167
- __('Local Upload Permissions','simple-local-avatars'),
168
- array( $this, 'avatar_settings_field' ),
169
- 'discussion',
170
- 'avatars',
171
- array(
172
- 'key' => 'caps',
173
- 'desc' => __( 'Only allow users with file upload capabilities to upload local avatars (Authors and above)', 'simple-local-avatars' )
174
- )
175
- );
176
- }
177
-
178
- /**
179
- * Add scripts to the profile editing page
180
- *
181
- * @param string $hook_suffix Page hook
182
- */
183
- public function admin_enqueue_scripts( $hook_suffix ) {
184
- if ( 'profile.php' != $hook_suffix && 'user-edit.php' != $hook_suffix )
185
- return;
186
-
187
- if ( current_user_can( 'upload_files' ) )
188
- wp_enqueue_media();
189
-
190
- $user_id = ( 'profile.php' == $hook_suffix ) ? get_current_user_id() : (int) $_GET['user_id'];
191
-
192
- $this->remove_nonce = wp_create_nonce( 'remove_simple_local_avatar_nonce' );
193
-
194
- $script_name_append = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.dev' : '';
195
- wp_enqueue_script( 'simple-local-avatars', plugins_url( '', __FILE__ ) . '/simple-local-avatars' . $script_name_append . '.js', array('jquery'), false, true );
196
- wp_localize_script( 'simple-local-avatars', 'i10n_SimpleLocalAvatars', array(
197
- 'user_id' => $user_id,
198
- 'insertMediaTitle' => __('Choose an Avatar','simple-local-avatars'),
199
- 'insertIntoPost' => __('Set as avatar','simple-local-avatars'),
200
- 'deleteNonce' => $this->remove_nonce,
201
- 'mediaNonce' => wp_create_nonce( 'assign_simple_local_avatar_nonce' ),
202
- ) );
203
- }
204
-
205
- /**
206
- * Sanitize new settings field before saving
207
- *
208
- * @param array|string $input Passed input values to sanitize
209
- * @return array|string Sanitized input fields
210
- */
211
- public function sanitize_options( $input ) {
212
- $new_input['caps'] = empty( $input['caps'] ) ? 0 : 1;
213
- $new_input['only'] = empty( $input['only'] ) ? 0 : 1;
214
- return $new_input;
215
- }
216
-
217
- /**
218
- * Settings field for avatar upload capabilities
219
- *
220
- * @param array $args Field arguments
221
- */
222
- public function avatar_settings_field( $args ) {
223
- $args = wp_parse_args( $args, array(
224
- 'key' => '',
225
- 'desc' => '',
226
- ) );
227
-
228
- if ( empty( $this->options[$args['key']] ) )
229
- $this->options[$args['key']] = 0;
230
-
231
- echo '
232
- <label for="simple-local-avatars-' . $args['key'] . '">
233
- <input type="checkbox" name="simple_local_avatars[' . $args['key'] . ']" id="simple-local-avatars-' . $args['key'] . '" value="1" ' . checked( $this->options[$args['key']], 1, false ) . ' />
234
- ' . $args['desc'] . '
235
- </label>
236
- ';
237
- }
238
-
239
- /**
240
- * Output new Avatar fields to user editing / profile screen
241
- *
242
- * @param object $profileuser User object
243
- */
244
- public function edit_user_profile( $profileuser ) {
245
- ?>
246
- <h3><?php _e( 'Avatar','simple-local-avatars' ); ?></h3>
247
-
248
- <table class="form-table">
249
- <tr>
250
- <th scope="row"><label for="simple-local-avatar"><?php _e('Upload Avatar','simple-local-avatars'); ?></label></th>
251
- <td style="width: 50px;" id="simple-local-avatar-photo">
252
- <?php
253
- add_filter( 'pre_option_avatar_rating', '__return_null' ); // ignore ratings here
254
- echo get_simple_local_avatar( $profileuser->ID );
255
- remove_filter( 'pre_option_avatar_rating', '__return_null' );
256
- ?>
257
- </td>
258
- <td>
259
- <?php
260
- if ( ! $upload_rights = current_user_can('upload_files') )
261
- $upload_rights = empty( $this->options['caps'] );
262
-
263
- if ( $upload_rights ) {
264
- do_action( 'simple_local_avatar_notices' );
265
- wp_nonce_field( 'simple_local_avatar_nonce', '_simple_local_avatar_nonce', false );
266
- $remove_url = add_query_arg(array(
267
- 'action' => 'remove-simple-local-avatar',
268
- 'user_id' => $profileuser->ID,
269
- '_wpnonce' => $this->remove_nonce,
270
- ) );
271
- ?>
272
- <?php
273
- // if user is author and above hide the choose file option
274
- // force them to use the WP Media Selector
275
- if ( ! current_user_can( 'upload_files' ) ) { ?>
276
- <p style="display: inline-block; width: 26em;">
277
- <span class="description"><?php _e( 'Choose an image from your computer:' ); ?></span><br />
278
- <input type="file" name="simple-local-avatar" id="simple-local-avatar" class="standard-text" />
279
- <span class="spinner" id="simple-local-avatar-spinner"></span>
280
- </p>
281
- <?php } ?>
282
- <p>
283
- <?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; ?>
284
- <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>
285
- </p>
286
- <?php
287
- } else {
288
- if ( empty( $profileuser->simple_local_avatar ) )
289
- echo '<span class="description">' . __('No local avatar is set. Set up your avatar at Gravatar.com.','simple-local-avatars') . '</span>';
290
- else
291
- echo '<span class="description">' . __('You do not have media management permissions. To change your local avatar, contact the blog administrator.','simple-local-avatars') . '</span>';
292
- }
293
- ?>
294
- </td>
295
- </tr>
296
- <tr>
297
- <th scope="row"><?php _e('Rating'); ?></th>
298
- <td colspan="2">
299
- <fieldset id="simple-local-avatar-ratings" <?php disabled( empty( $profileuser->simple_local_avatar ) ); ?>>
300
- <legend class="screen-reader-text"><span><?php _e('Rating'); ?></span></legend>
301
- <?php
302
- if ( empty( $profileuser->simple_local_avatar_rating ) || ! array_key_exists( $profileuser->simple_local_avatar_rating, $this->avatar_ratings ) )
303
- $profileuser->simple_local_avatar_rating = 'G';
304
-
305
- foreach ( $this->avatar_ratings as $key => $rating ) :
306
- 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 />";
307
- endforeach;
308
- ?>
309
- <p class="description"><?php _e( 'If the local avatar is inappropriate for this site, Gravatar will be attempted.', 'simple-local-avatars' ); ?></p>
310
- </fieldset></td>
311
- </tr>
312
- </table>
313
- <?php
314
- }
315
-
316
- /**
317
- * Ensure that the profile form has proper encoding type
318
- */
319
- public function user_edit_form_tag() {
320
- echo 'enctype="multipart/form-data"';
321
- }
322
-
323
- /**
324
- * Saves avatar image to a user
325
- *
326
- * @param int|string $url_or_media_id Local URL for avatar or ID of attachment
327
- * @param int $user_id ID of user to assign image to
328
- */
329
- private function assign_new_user_avatar( $url_or_media_id, $user_id ) {
330
- // delete the old avatar
331
- $this->avatar_delete( $user_id ); // delete old images if successful
332
-
333
- $meta_value = array();
334
-
335
- // set the new avatar
336
- if ( is_int( $url_or_media_id ) ) {
337
- $meta_value['media_id'] = $url_or_media_id;
338
- $url_or_media_id = wp_get_attachment_url( $url_or_media_id );
339
- }
340
-
341
- $meta_value['full'] = $url_or_media_id;
342
-
343
- update_user_meta( $user_id, 'simple_local_avatar', $meta_value ); // save user information (overwriting old)
344
- }
345
-
346
- /**
347
- * Save any changes to the user profile
348
- *
349
- * @param int $user_id ID of user being updated
350
- */
351
- public function edit_user_profile_update( $user_id ) {
352
- // check nonces
353
- if( empty( $_POST['_simple_local_avatar_nonce'] ) || ! wp_verify_nonce( $_POST['_simple_local_avatar_nonce'], 'simple_local_avatar_nonce' ) )
354
- return;
355
-
356
- // check for uploaded files
357
- if ( ! empty( $_FILES['simple-local-avatar']['name'] ) ) :
358
-
359
- // need to be more secure since low privelege users can upload
360
- if ( false !== strpos( $_FILES['simple-local-avatar']['name'], '.php' ) ) {
361
- $this->avatar_upload_error = __('For security reasons, the extension ".php" cannot be in your file name.','simple-local-avatars');
362
- add_action( 'user_profile_update_errors', array( $this, 'user_profile_update_errors' ) );
363
- return;
364
- }
365
-
366
- // front end (theme my profile etc) support
367
- if ( ! function_exists( 'media_handle_upload' ) )
368
- require_once( ABSPATH . 'wp-admin/includes/media.php' );
369
-
370
- // allow developers to override file size upload limit for avatars
371
- add_filter( 'upload_size_limit', array( $this, 'upload_size_limit' ) );
372
-
373
- $this->user_id_being_edited = $user_id; // make user_id known to unique_filename_callback function
374
- $avatar_id = media_handle_upload( 'simple-local-avatar', 0, array(), array(
375
- 'mimes' => array(
376
- 'jpg|jpeg|jpe' => 'image/jpeg',
377
- 'gif' => 'image/gif',
378
- 'png' => 'image/png',
379
- ),
380
- 'test_form' => false,
381
- 'unique_filename_callback' => array( $this, 'unique_filename_callback' )
382
- ) );
383
-
384
- remove_filter( 'upload_size_limit', array( $this, 'upload_size_limit' ) );
385
-
386
- if ( is_wp_error( $avatar_id ) ) { // handle failures.
387
- $this->avatar_upload_error = '<strong>' . __( 'There was an error uploading the avatar:', 'simple-local-avatars' ) . '</strong> ' . esc_html( $avatar_id->get_error_message() );
388
- add_action( 'user_profile_update_errors', array( $this, 'user_profile_update_errors' ) );
389
- return;
390
- }
391
-
392
- $this->assign_new_user_avatar( $avatar_id, $user_id );
393
-
394
- endif;
395
-
396
- // handle rating
397
- if ( isset( $avatar_id ) || $avatar = get_user_meta( $user_id, 'simple_local_avatar', true ) ) {
398
- if ( empty( $_POST['simple_local_avatar_rating'] ) || ! array_key_exists( $_POST['simple_local_avatar_rating'], $this->avatar_ratings ) )
399
- $_POST['simple_local_avatar_rating'] = key( $this->avatar_ratings );
400
-
401
- update_user_meta( $user_id, 'simple_local_avatar_rating', $_POST['simple_local_avatar_rating'] );
402
- }
403
- }
404
-
405
- /**
406
- * Allow developers to override the maximum allowable file size for avatar uploads
407
- *
408
- * @param int $bytes WordPress default byte size check
409
- * @return int Maximum byte size
410
- */
411
- public function upload_size_limit( $bytes ) {
412
- return apply_filters( 'simple_local_avatars_upload_limit', $bytes );
413
- }
414
-
415
- /**
416
- * Runs when a user clicks the Remove button for the avatar
417
- */
418
- public function action_remove_simple_local_avatar() {
419
- if ( ! empty( $_GET['user_id'] ) && ! empty( $_GET['_wpnonce'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'remove_simple_local_avatar_nonce' ) ) {
420
- $user_id = (int) $_GET['user_id'];
421
-
422
- if ( ! current_user_can('edit_user', $user_id) )
423
- wp_die( __('You do not have permission to edit this user.') );
424
-
425
- $this->avatar_delete( $user_id ); // delete old images if successful
426
-
427
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
428
- echo get_simple_local_avatar( $user_id );
429
- }
430
-
431
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
432
- die;
433
- }
434
-
435
- /**
436
- * AJAX callback for assigning media ID fetched from media library to user
437
- */
438
- public function ajax_assign_simple_local_avatar_media() {
439
- // check required information and permissions
440
- 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' ) )
441
- die;
442
-
443
- $media_id = (int) $_POST['media_id'];
444
- $user_id = (int) $_POST['user_id'];
445
-
446
- // ensure the media is real is an image
447
- if ( wp_attachment_is_image( $media_id ) )
448
- $this->assign_new_user_avatar( $media_id, $user_id );
449
-
450
- echo get_simple_local_avatar( $user_id );
451
-
452
- die;
453
- }
454
-
455
- /**
456
- * remove the custom get_avatar hook for the default avatar list output on options-discussion.php
457
- */
458
- public function avatar_defaults( $avatar_defaults ) {
459
- remove_action( 'get_avatar', array( $this, 'get_avatar' ) );
460
- return $avatar_defaults;
461
- }
462
-
463
- /**
464
- * Delete avatars based on a user_id
465
- *
466
- * @param int $user_id
467
- */
468
- public function avatar_delete( $user_id ) {
469
- $old_avatars = (array) get_user_meta( $user_id, 'simple_local_avatar', true );
470
-
471
- if ( empty( $old_avatars ) )
472
- return;
473
-
474
- // if it was uploaded media, don't erase the full size or try to erase an the ID
475
- if ( array_key_exists( 'media_id', $old_avatars ) )
476
- unset( $old_avatars['media_id'], $old_avatars['full'] );
477
-
478
- if ( ! empty( $old_avatars ) ) {
479
- $upload_path = wp_upload_dir();
480
-
481
- foreach ($old_avatars as $old_avatar ) {
482
- // derive the path for the file based on the upload directory
483
- $old_avatar_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $old_avatar );
484
- if ( file_exists( $old_avatar_path ) )
485
- unlink( $old_avatar_path );
486
- }
487
- }
488
-
489
- delete_user_meta( $user_id, 'simple_local_avatar' );
490
- delete_user_meta( $user_id, 'simple_local_avatar_rating' );
491
- }
492
-
493
- /**
494
- * Creates a unique, meaningful file name for uploaded avatars.
495
- *
496
- * @param string $dir Path for file
497
- * @param string $name Filename
498
- * @param string $ext File extension (e.g. ".jpg")
499
- * @return string Final filename
500
- */
501
- public function unique_filename_callback( $dir, $name, $ext ) {
502
- $user = get_user_by( 'id', (int) $this->user_id_being_edited );
503
- $name = $base_name = sanitize_file_name( $user->display_name . '_avatar_' . time() );
504
-
505
- // ensure no conflicts with existing file names
506
- $number = 1;
507
- while ( file_exists( $dir . "/$name$ext" ) ) {
508
- $name = $base_name . '_' . $number;
509
- $number++;
510
- }
511
-
512
- return $name . $ext;
513
- }
514
-
515
- /**
516
- * Adds errors based on avatar upload problems.
517
- *
518
- * @param WP_Error $errors Error messages for user profile screen.
519
- */
520
- public function user_profile_update_errors( WP_Error $errors ) {
521
- $errors->add( 'avatar_error', $this->avatar_upload_error );
522
- }
523
-
524
- /**
525
- * Registers the simple_local_avatar field in the REST API.
526
- */
527
- public function register_rest_fields() {
528
- register_rest_field( 'user', 'simple_local_avatar', array(
529
- 'get_callback' => array( $this, 'get_avatar_rest' ),
530
- 'update_callback' => array( $this, 'set_avatar_rest' ),
531
- 'schema' => array(
532
- 'description' => 'The users simple local avatar',
533
- 'type' => 'object',
534
- )
535
- ));
536
- }
537
-
538
- /**
539
- * Returns the simple_local_avatar meta key for the given user.
540
- *
541
- * @param object $user User object
542
- */
543
- public function get_avatar_rest( $user ) {
544
- $local_avatar = get_user_meta( $user['id'], 'simple_local_avatar', true );
545
- if ( empty( $local_avatar ) ) {
546
- return;
547
- }
548
- return $local_avatar;
549
- }
550
-
551
- /**
552
- * Updates the simple local avatar from a REST request.
553
- *
554
- * Since we are just adding a field to the existing user endpoint
555
- * we don't need to worry about ensuring the calling user has proper permissions.
556
- * Only the user or an administrator would be able to change the avatar.
557
- *
558
- * @param array $input Input submitted via REST request.
559
- * @param object $user The user making the request.
560
- */
561
- public function set_avatar_rest( $input, $user ) {
562
- $this->assign_new_user_avatar($input['media_id'], $user->ID);
563
- }
564
-
565
- }
566
-
567
- $simple_local_avatars = new Simple_Local_Avatars;
568
-
569
- /**
570
- * more efficient to call simple local avatar directly in theme and avoid gravatar setup
571
- *
572
- * @param int|string|object $id_or_email A user ID, email address, or comment object
573
- * @param int $size Size of the avatar image
574
- * @param string $default URL to a default image to use if no avatar is available
575
- * @param string $alt Alternate text to use in image tag. Defaults to blank
576
- * @return string <img> tag for the user's avatar
577
- */
578
- function get_simple_local_avatar( $id_or_email, $size = 96, $default = '', $alt = '' ) {
579
- global $simple_local_avatars;
580
- $avatar = $simple_local_avatars->get_avatar( '', $id_or_email, $size, $default, $alt );
581
-
582
- if ( empty ( $avatar ) ) {
583
- remove_action( 'get_avatar', array( $simple_local_avatars, 'get_avatar' ) );
584
- $avatar = get_avatar( $id_or_email, $size, $default, $alt );
585
- add_action( 'get_avatar', array( $simple_local_avatars, 'get_avatar' ), 10, 5 );
586
- }
587
-
588
- return $avatar;
589
- }
590
-
591
- if ( ! function_exists( 'get_avatar' ) && ( $simple_local_avatars_options = get_option('simple_local_avatars') ) && ! empty( $simple_local_avatars_options['only'] ) ) :
592
-
593
- /**
594
- * Retrieve the avatar for a user who provided a user ID or email address.
595
- *
596
- * @param int|string|object $id_or_email A user ID, email address, or comment object
597
- * @param int $size Size of the avatar image
598
- * @param string $default URL to a default image to use if no avatar is available
599
- * @param string $alt Alternative text to use in image tag. Defaults to blank
600
- * @return string <img> tag for the user's avatar
601
- */
602
- function get_avatar( $id_or_email, $size = 96, $default = '', $alt = '' ) {
603
- global $simple_local_avatars;
604
-
605
- if ( ! get_option('show_avatars') )
606
- return false;
607
-
608
- $safe_alt = empty( $alt ) ? '' : esc_attr( $alt );
609
-
610
- if ( !is_numeric($size) )
611
- $size = 96;
612
-
613
- if ( ! $avatar = $simple_local_avatars->get_avatar( '', $id_or_email, $size, $default, $alt ) ) :
614
-
615
- if ( empty($default) ) {
616
- $avatar_default = get_option('avatar_default');
617
- if ( empty($avatar_default) )
618
- $default = 'mystery';
619
- else
620
- $default = $avatar_default;
621
- }
622
-
623
- $host = is_ssl() ? 'https://secure.gravatar.com' : 'http://0.gravatar.com';
624
-
625
- if ( 'mystery' == $default )
626
- $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}"; // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com')
627
- elseif ( 'blank' == $default )
628
- $default = includes_url( 'images/blank.gif' );
629
- elseif ( 'gravatar_default' == $default )
630
- $default = "$host/avatar/?s={$size}";
631
- else
632
- $default = "$host/avatar/?d=$default&amp;s={$size}";
633
-
634
- $avatar = "<img alt='{$safe_alt}' src='" . $default . "' class='avatar avatar-{$size} photo avatar-default' height='{$size}' width='{$size}' />";
635
-
636
- endif;
637
-
638
- return apply_filters('get_avatar', $avatar, $id_or_email, $size, $default, $alt);
639
- }
640
-
641
- endif;
642
-
643
- /**
644
- * on uninstallation, remove the custom field from the users and delete the local avatars
645
- */
646
-
647
- register_uninstall_hook( __FILE__, 'simple_local_avatars_uninstall' );
648
-
649
- function simple_local_avatars_uninstall() {
650
- $simple_local_avatars = new Simple_Local_Avatars;
651
- $users = get_users(array(
652
- 'meta_key' => 'simple_local_avatar',
653
- 'fields' => 'ids',
654
- ));
655
-
656
- foreach ( $users as $user_id ):
657
- $simple_local_avatars->avatar_delete( $user_id );
658
- endforeach;
659
-
660
- delete_option('simple_local_avatars');
661
- }
1
+ <?php
2
+ /**
3
+ * Plugin Name: Simple Local Avatars
4
+ * Plugin URI: https://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.2.0
7
+ * Requires at least: 4.6
8
+ * Requires PHP: 5.3
9
+ * Author: Jake Goldman, 10up
10
+ * Author URI: https://10up.com
11
+ * License: GPLv2 or later
12
+ * License URI: https://www.gnu.org/licenses/gpl-2.0.html
13
+ * Text Domain: simple-local-avatars
14
+ */
15
+
16
+ require_once dirname( __FILE__ ) . '/includes/class-simple-local-avatars.php';
17
+
18
+ /**
19
+ * Init the plugin.
20
+ */
21
+ global $simple_local_avatars;
22
+ $simple_local_avatars = new Simple_Local_Avatars();
23
+
24
+ /**
25
+ * More efficient to call simple local avatar directly in theme and avoid
26
+ * gravatar setup.
27
+ *
28
+ * Since 2.2, This function is only a proxy for get_avatar due to internal changes.
29
+ *
30
+ * @param int|string|object $id_or_email A user ID, email address, or comment object
31
+ * @param int $size Size of the avatar image
32
+ * @param string $default URL to a default image to use if no avatar is available
33
+ * @param string $alt Alternate text to use in image tag. Defaults to blank
34
+ * @param array $args Optional. Extra arguments to retrieve the avatar.
35
+ *
36
+ * @return string <img> tag for the user's avatar
37
+ */
38
+ function get_simple_local_avatar( $id_or_email, $size = 96, $default = '', $alt = '', $args = array() ) {
39
+ return apply_filters( 'simple_local_avatar', get_avatar( $id_or_email, $size, $default, $alt, $args ) );
40
+ }
41
+
42
+ register_uninstall_hook( __FILE__, 'simple_local_avatars_uninstall' );
43
+ /**
44
+ * On uninstallation, remove the custom field from the users and delete the local avatars
45
+ */
46
+ function simple_local_avatars_uninstall() {
47
+ $simple_local_avatars = new Simple_Local_Avatars();
48
+ $users = get_users(
49
+ array(
50
+ 'meta_key' => 'simple_local_avatar',
51
+ 'fields' => 'ids',
52
+ )
53
+ );
54
+
55
+ foreach ( $users as $user_id ) :
56
+ $simple_local_avatars->avatar_delete( $user_id );
57
+ endforeach;
58
+
59
+ delete_option( 'simple_local_avatars' );
60
+ }