From 05056595069af67309547213e4f8d6c8dc8958ba Mon Sep 17 00:00:00 2001 From: Lai Power Date: Sat, 31 Oct 2020 15:29:50 +0000 Subject: [PATCH] updated plugin `Simple Local Avatars` version 2.2.0 --- .../includes/class-simple-local-avatars.php | 681 +++++++++++++++++ .../plugins/simple-local-avatars/readme.txt | 31 +- .../simple-local-avatars/screenshot-1.png | Bin 76478 -> 0 bytes .../simple-local-avatars.php | 721 ++---------------- 4 files changed, 763 insertions(+), 670 deletions(-) create mode 100644 wp-content/plugins/simple-local-avatars/includes/class-simple-local-avatars.php delete mode 100644 wp-content/plugins/simple-local-avatars/screenshot-1.png diff --git a/wp-content/plugins/simple-local-avatars/includes/class-simple-local-avatars.php b/wp-content/plugins/simple-local-avatars/includes/class-simple-local-avatars.php new file mode 100644 index 00000000..d5856284 --- /dev/null +++ b/wp-content/plugins/simple-local-avatars/includes/class-simple-local-avatars.php @@ -0,0 +1,681 @@ +options = (array) get_option( 'simple_local_avatars' ); + $this->avatar_ratings = array( + 'G' => __( 'G — Suitable for all audiences', 'simple-local-avatars' ), + 'PG' => __( 'PG — Possibly offensive, usually for audiences 13 and above', 'simple-local-avatars' ), + 'R' => __( 'R — Intended for adult audiences above 17', 'simple-local-avatars' ), + 'X' => __( 'X — Even more mature than above', 'simple-local-avatars' ), + ); + + $this->add_hooks(); + } + + /** + * Register actions and filters. + */ + public function add_hooks() { + add_filter( 'pre_get_avatar_data', array( $this, 'get_avatar_data' ), 10, 2 ); + + add_action( 'admin_init', array( $this, 'admin_init' ) ); + + add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); + add_action( 'show_user_profile', array( $this, 'edit_user_profile' ) ); + add_action( 'edit_user_profile', array( $this, 'edit_user_profile' ) ); + + add_action( 'personal_options_update', array( $this, 'edit_user_profile_update' ) ); + add_action( 'edit_user_profile_update', array( $this, 'edit_user_profile_update' ) ); + add_action( 'admin_action_remove-simple-local-avatar', array( $this, 'action_remove_simple_local_avatar' ) ); + add_action( 'wp_ajax_assign_simple_local_avatar_media', array( $this, 'ajax_assign_simple_local_avatar_media' ) ); + add_action( 'wp_ajax_remove_simple_local_avatar', array( $this, 'action_remove_simple_local_avatar' ) ); + add_action( 'user_edit_form_tag', array( $this, 'user_edit_form_tag' ) ); + + add_action( 'rest_api_init', array( $this, 'register_rest_fields' ) ); + } + + /** + * Retrieve the local avatar for a user who provided a user ID, email address or post/comment object. + * + * @param string $avatar Avatar return by original function + * @param int|string|object $id_or_email A user ID, email address, or post/comment object + * @param int $size Size of the avatar image + * @param string $default URL to a default image to use if no avatar is available + * @param string $alt Alternative text to use in image tag. Defaults to blank + * @param array $args Optional. Extra arguments to retrieve the avatar. + * + * @return string tag for the user's avatar + */ + public function get_avatar( $avatar = '', $id_or_email = '', $size = 96, $default = '', $alt = '', $args = array() ) { + return apply_filters( 'simple_local_avatar', get_avatar( $id_or_email, $size, $default, $alt, $args ) ); + } + + /** + * Filter avatar data early to add avatar url if needed. This filter hooks + * before Gravatar setup to prevent wasted requests. + * + * @since 2.2.0 + * + * @param array $args Arguments passed to get_avatar_data(), after processing. + * @param mixed $id_or_email The Gravatar to retrieve. Accepts a user ID, Gravatar MD5 hash, + * user email, WP_User object, WP_Post object, or WP_Comment object. + */ + public function get_avatar_data( $args, $id_or_email ) { + if ( ! empty( $args['force_default'] ) ) { + return $args; + } + + $simple_local_avatar_url = $this->get_simple_local_avatar_url( $id_or_email, $args['size'] ); + if ( $simple_local_avatar_url ) { + $args['url'] = $simple_local_avatar_url; + } + + // Local only mode + if ( ! $simple_local_avatar_url && ! empty( $this->options['only'] ) ) { + $args['url'] = $this->get_default_avatar_url( $args['size'] ); + } + + if ( ! empty( $args['url'] ) ) { + $args['found_avatar'] = true; + } + + return $args; + } + + /** + * Get local avatar url. + * + * @since 2.2.0 + * + * @param mixed $id_or_email The Gravatar to retrieve. Accepts a user ID, Gravatar MD5 hash, + * user email, WP_User object, WP_Post object, or WP_Comment object. + * @param int $size Requested avatar size. + */ + public function get_simple_local_avatar_url( $id_or_email, $size ) { + if ( is_numeric( $id_or_email ) ) { + $user_id = (int) $id_or_email; + } elseif ( is_string( $id_or_email ) && ( $user = get_user_by( 'email', $id_or_email ) ) ) { + $user_id = $user->ID; + } elseif ( is_object( $id_or_email ) && ! empty( $id_or_email->user_id ) ) { + $user_id = (int) $id_or_email->user_id; + } elseif ( $id_or_email instanceof WP_Post && ! empty( $id_or_email->post_author ) ) { + $user_id = (int) $id_or_email->post_author; + } + + if ( empty( $user_id ) ) { + return ''; + } + + // Fetch local avatar from meta and make sure it's properly set. + $local_avatars = get_user_meta( $user_id, 'simple_local_avatar', true ); + if ( empty( $local_avatars['full'] ) ) { + return ''; + } + + // check rating + $avatar_rating = get_user_meta( $user_id, 'simple_local_avatar_rating', true ); + if ( ! empty( $avatar_rating ) && 'G' !== $avatar_rating && ( $site_rating = get_option( 'avatar_rating' ) ) ) { + $ratings = array_keys( $this->avatar_ratings ); + $site_rating_weight = array_search( $site_rating, $ratings ); + $avatar_rating_weight = array_search( $avatar_rating, $ratings ); + if ( false !== $avatar_rating_weight && $avatar_rating_weight > $site_rating_weight ) { + return ''; + } + } + + // handle "real" media + if ( ! empty( $local_avatars['media_id'] ) ) { + // has the media been deleted? + if ( ! $avatar_full_path = get_attached_file( $local_avatars['media_id'] ) ) { + return ''; + } + } + + $size = (int) $size; + + // Generate a new size. + if ( ! array_key_exists( $size, $local_avatars ) ) { + $local_avatars[ $size ] = $local_avatars['full']; // just in case of failure elsewhere + + // allow automatic rescaling to be turned off + if ( apply_filters( 'simple_local_avatars_dynamic_resize', true ) ) : + + $upload_path = wp_upload_dir(); + + // get path for image by converting URL, unless its already been set, thanks to using media library approach + if ( ! isset( $avatar_full_path ) ) { + $avatar_full_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $local_avatars['full'] ); + } + + // generate the new size + $editor = wp_get_image_editor( $avatar_full_path ); + if ( ! is_wp_error( $editor ) ) { + $resized = $editor->resize( $size, $size, true ); + if ( ! is_wp_error( $resized ) ) { + $dest_file = $editor->generate_filename(); + $saved = $editor->save( $dest_file ); + if ( ! is_wp_error( $saved ) ) { + $local_avatars[ $size ] = str_replace( $upload_path['basedir'], $upload_path['baseurl'], $dest_file ); + } + } + } + + // save updated avatar sizes + update_user_meta( $user_id, 'simple_local_avatar', $local_avatars ); + + endif; + } + + if ( 'http' !== substr( $local_avatars[ $size ], 0, 4 ) ) { + $local_avatars[ $size ] = home_url( $local_avatars[ $size ] ); + } + + return esc_url( $local_avatars[ $size ] ); + } + + /** + * Get default avatar url + * + * @since 2.2.0 + * + * @param int $size Requested avatar size. + */ + public function get_default_avatar_url( $size ) { + if ( empty( $default ) ) { + $avatar_default = get_option( 'avatar_default' ); + if ( empty( $avatar_default ) ) { + $default = 'mystery'; + } else { + $default = $avatar_default; + } + } + + $host = is_ssl() ? 'https://secure.gravatar.com' : 'http://0.gravatar.com'; + + if ( 'mystery' === $default ) { + $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}"; // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com') + } elseif ( 'blank' === $default ) { + $default = includes_url( 'images/blank.gif' ); + } elseif ( 'gravatar_default' === $default ) { + $default = "$host/avatar/?s={$size}"; + } else { + $default = "$host/avatar/?d=$default&s={$size}"; + } + + return $default; + } + + /** + * Register admin settings. + */ + public function admin_init() { + // upgrade pre 2.0 option + if ( $old_ops = get_option( 'simple_local_avatars_caps' ) ) { + if ( ! empty( $old_ops['simple_local_avatars_caps'] ) ) { + update_option( 'simple_local_avatars', array( 'caps' => 1 ) ); + } + + delete_option( 'simple_local_avatar_caps' ); + } + + register_setting( 'discussion', 'simple_local_avatars', array( $this, 'sanitize_options' ) ); + 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)', 'simple-local-avatars' ), + ) + ); + 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)', 'simple-local-avatars' ), + ) + ); + } + + /** + * Add scripts to the profile editing page + * + * @param string $hook_suffix Page hook + */ + public function admin_enqueue_scripts( $hook_suffix ) { + if ( 'profile.php' !== $hook_suffix && 'user-edit.php' !== $hook_suffix ) { + return; + } + + if ( current_user_can( 'upload_files' ) ) { + wp_enqueue_media(); + } + + $user_id = ( 'profile.php' === $hook_suffix ) ? get_current_user_id() : (int) $_GET['user_id']; + + $this->remove_nonce = wp_create_nonce( 'remove_simple_local_avatar_nonce' ); + + $script_name_append = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.dev' : ''; + wp_enqueue_script( 'simple-local-avatars', plugins_url( '', dirname( __FILE__ ) ) . '/simple-local-avatars' . $script_name_append . '.js', array( 'jquery' ), false, true ); + wp_localize_script( + 'simple-local-avatars', + 'i10n_SimpleLocalAvatars', + array( + 'user_id' => $user_id, + 'insertMediaTitle' => __( 'Choose an Avatar', 'simple-local-avatars' ), + 'insertIntoPost' => __( 'Set as avatar', 'simple-local-avatars' ), + 'deleteNonce' => $this->remove_nonce, + 'mediaNonce' => wp_create_nonce( 'assign_simple_local_avatar_nonce' ), + ) + ); + } + + /** + * Sanitize new settings field before saving + * + * @param array|string $input Passed input values to sanitize + * @return array|string Sanitized input fields + */ + public function sanitize_options( $input ) { + $new_input['caps'] = empty( $input['caps'] ) ? 0 : 1; + $new_input['only'] = empty( $input['only'] ) ? 0 : 1; + return $new_input; + } + + /** + * Settings field for avatar upload capabilities + * + * @param array $args Field arguments + */ + public function avatar_settings_field( $args ) { + $args = wp_parse_args( + $args, + array( + 'key' => '', + 'desc' => '', + ) + ); + + if ( empty( $this->options[ $args['key'] ] ) ) { + $this->options[ $args['key'] ] = 0; + } + + echo ' + + '; + } + + /** + * Output new Avatar fields to user editing / profile screen + * + * @param object $profileuser User object + */ + public function edit_user_profile( $profileuser ) { + ?> +
+

+ + + + + + + + + + + +
+ ID ); + remove_filter( 'pre_option_avatar_rating', '__return_null' ); + ?> + + options['caps'] ); + } + + if ( $upload_rights ) { + do_action( 'simple_local_avatar_notices' ); + wp_nonce_field( 'simple_local_avatar_nonce', '_simple_local_avatar_nonce', false ); + $remove_url = add_query_arg( + array( + 'action' => 'remove-simple-local-avatar', + 'user_id' => $profileuser->ID, + '_wpnonce' => $this->remove_nonce, + ) + ); + ?> + +

+
+ + +

+ +

+ +   + + simple_local_avatar ) ? ' style="display:none;"' : ''; ?> + > + + +

+ simple_local_avatar ) ) { + echo '' . esc_html__( 'No local avatar is set. Set up your avatar at Gravatar.com.', 'simple-local-avatars' ) . ''; + } else { + echo '' . esc_html__( 'You do not have media management permissions. To change your local avatar, contact the blog administrator.', 'simple-local-avatars' ) . ''; + } + } + ?> +
+
simple_local_avatar ) ); ?>> + + simple_local_avatar_rating ) || ! array_key_exists( $profileuser->simple_local_avatar_rating, $this->avatar_ratings ) ) { + $profileuser->simple_local_avatar_rating = 'G'; + } + + foreach ( $this->avatar_ratings as $key => $rating ) : + echo "\n\t
"; + endforeach; + ?> +

+
+
+ avatar_delete( $user_id ); // delete old images if successful + + $meta_value = array(); + + // set the new avatar + if ( is_int( $url_or_media_id ) ) { + $meta_value['media_id'] = $url_or_media_id; + $url_or_media_id = wp_get_attachment_url( $url_or_media_id ); + } + + $meta_value['full'] = $url_or_media_id; + + update_user_meta( $user_id, 'simple_local_avatar', $meta_value ); // save user information (overwriting old) + } + + /** + * Save any changes to the user profile + * + * @param int $user_id ID of user being updated + */ + public function edit_user_profile_update( $user_id ) { + // check nonces + if ( empty( $_POST['_simple_local_avatar_nonce'] ) || ! wp_verify_nonce( $_POST['_simple_local_avatar_nonce'], 'simple_local_avatar_nonce' ) ) { + return; + } + + // check for uploaded files + if ( ! empty( $_FILES['simple-local-avatar']['name'] ) ) : + + // need to be more secure since low privelege users can upload + if ( false !== strpos( $_FILES['simple-local-avatar']['name'], '.php' ) ) { + $this->avatar_upload_error = __( 'For security reasons, the extension ".php" cannot be in your file name.', 'simple-local-avatars' ); + add_action( 'user_profile_update_errors', array( $this, 'user_profile_update_errors' ) ); + return; + } + + // front end (theme my profile etc) support + if ( ! function_exists( 'media_handle_upload' ) ) { + include_once ABSPATH . 'wp-admin/includes/media.php'; + } + + // allow developers to override file size upload limit for avatars + add_filter( 'upload_size_limit', array( $this, 'upload_size_limit' ) ); + + $this->user_id_being_edited = $user_id; // make user_id known to unique_filename_callback function + $avatar_id = media_handle_upload( + 'simple-local-avatar', + 0, + array(), + array( + 'mimes' => array( + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + ), + 'test_form' => false, + 'unique_filename_callback' => array( $this, 'unique_filename_callback' ), + ) + ); + + remove_filter( 'upload_size_limit', array( $this, 'upload_size_limit' ) ); + + if ( is_wp_error( $avatar_id ) ) { // handle failures. + $this->avatar_upload_error = '' . __( 'There was an error uploading the avatar:', 'simple-local-avatars' ) . ' ' . esc_html( $avatar_id->get_error_message() ); + add_action( 'user_profile_update_errors', array( $this, 'user_profile_update_errors' ) ); + return; + } + + $this->assign_new_user_avatar( $avatar_id, $user_id ); + + endif; + + // Handle ratings + if ( isset( $avatar_id ) || $avatar = get_user_meta( $user_id, 'simple_local_avatar', true ) ) { + if ( empty( $_POST['simple_local_avatar_rating'] ) || ! array_key_exists( $_POST['simple_local_avatar_rating'], $this->avatar_ratings ) ) { + $_POST['simple_local_avatar_rating'] = key( $this->avatar_ratings ); + } + + update_user_meta( $user_id, 'simple_local_avatar_rating', $_POST['simple_local_avatar_rating'] ); + } + } + + /** + * Allow developers to override the maximum allowable file size for avatar uploads + * + * @param int $bytes WordPress default byte size check + * @return int Maximum byte size + */ + public function upload_size_limit( $bytes ) { + return apply_filters( 'simple_local_avatars_upload_limit', $bytes ); + } + + /** + * Runs when a user clicks the Remove button for the avatar + */ + public function action_remove_simple_local_avatar() { + if ( ! empty( $_GET['user_id'] ) && ! empty( $_GET['_wpnonce'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'remove_simple_local_avatar_nonce' ) ) { + $user_id = (int) $_GET['user_id']; + + if ( ! current_user_can( 'edit_user', $user_id ) ) { + wp_die( esc_html__( 'You do not have permission to edit this user.', 'simple-local-avatars' ) ); + } + + $this->avatar_delete( $user_id ); // delete old images if successful + + if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { + echo get_simple_local_avatar( $user_id ); + } + } + + if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { + die; + } + } + + /** + * AJAX callback for assigning media ID fetched from media library to user + */ + public function ajax_assign_simple_local_avatar_media() { + // check required information and permissions + 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' ) ) { + die; + } + + $media_id = (int) $_POST['media_id']; + $user_id = (int) $_POST['user_id']; + + // ensure the media is real is an image + if ( wp_attachment_is_image( $media_id ) ) { + $this->assign_new_user_avatar( $media_id, $user_id ); + } + + echo get_simple_local_avatar( $user_id ); + + die; + } + + /** + * Delete avatars based on a user_id + * + * @param int $user_id User ID. + */ + public function avatar_delete( $user_id ) { + $old_avatars = (array) get_user_meta( $user_id, 'simple_local_avatar', true ); + + if ( empty( $old_avatars ) ) { + return; + } + + // if it was uploaded media, don't erase the full size or try to erase an the ID + if ( array_key_exists( 'media_id', $old_avatars ) ) { + unset( $old_avatars['media_id'], $old_avatars['full'] ); + } + + if ( ! empty( $old_avatars ) ) { + $upload_path = wp_upload_dir(); + + foreach ( $old_avatars as $old_avatar ) { + // derive the path for the file based on the upload directory + $old_avatar_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $old_avatar ); + if ( file_exists( $old_avatar_path ) ) { + unlink( $old_avatar_path ); + } + } + } + + delete_user_meta( $user_id, 'simple_local_avatar' ); + delete_user_meta( $user_id, 'simple_local_avatar_rating' ); + } + + /** + * Creates a unique, meaningful file name for uploaded avatars. + * + * @param string $dir Path for file + * @param string $name Filename + * @param string $ext File extension (e.g. ".jpg") + * @return string Final filename + */ + public function unique_filename_callback( $dir, $name, $ext ) { + $user = get_user_by( 'id', (int) $this->user_id_being_edited ); + $name = $base_name = sanitize_file_name( $user->display_name . '_avatar_' . time() ); + + // ensure no conflicts with existing file names + $number = 1; + while ( file_exists( $dir . "/$name$ext" ) ) { + $name = $base_name . '_' . $number; + $number++; + } + + return $name . $ext; + } + + /** + * Adds errors based on avatar upload problems. + * + * @param WP_Error $errors Error messages for user profile screen. + */ + public function user_profile_update_errors( WP_Error $errors ) { + $errors->add( 'avatar_error', $this->avatar_upload_error ); + } + + /** + * Registers the simple_local_avatar field in the REST API. + */ + public function register_rest_fields() { + register_rest_field( + 'user', + 'simple_local_avatar', + array( + 'get_callback' => array( $this, 'get_avatar_rest' ), + 'update_callback' => array( $this, 'set_avatar_rest' ), + 'schema' => array( + 'description' => 'The users simple local avatar', + 'type' => 'object', + ), + ) + ); + } + + /** + * Returns the simple_local_avatar meta key for the given user. + * + * @param object $user User object + */ + public function get_avatar_rest( $user ) { + $local_avatar = get_user_meta( $user['id'], 'simple_local_avatar', true ); + if ( empty( $local_avatar ) ) { + return; + } + return $local_avatar; + } + + /** + * Updates the simple local avatar from a REST request. + * + * Since we are just adding a field to the existing user endpoint + * we don't need to worry about ensuring the calling user has proper permissions. + * Only the user or an administrator would be able to change the avatar. + * + * @param array $input Input submitted via REST request. + * @param object $user The user making the request. + */ + public function set_avatar_rest( $input, $user ) { + $this->assign_new_user_avatar( $input['media_id'], $user->ID ); + } +} diff --git a/wp-content/plugins/simple-local-avatars/readme.txt b/wp-content/plugins/simple-local-avatars/readme.txt index 64e13669..5c92ee11 100644 --- a/wp-content/plugins/simple-local-avatars/readme.txt +++ b/wp-content/plugins/simple-local-avatars/readme.txt @@ -3,13 +3,14 @@ Contributors: jakemgold, 10up, thinkoomph Donate link: https://10up.com/plugins/simple-local-avatars-wordpress/ Tags: avatar, gravatar, user photos, users, profile Requires at least: 4.6 -Tested up to: 5.2 -Stable tag: 2.1.1 -Text Domain: simple-local-avatars +Tested up to: 5.5 +Requires PHP: 5.3 +Stable tag: 2.2.0 +License: GPLv2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html Adds an avatar upload field to user profiles. Generates requested sizes on demand just like Gravatar! - == 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. @@ -23,7 +24,6 @@ Just edit a user profile, and scroll down to the new "Avatar" field. The plug-in 1. Let's you decide whether lower privilege users (subscribers, contributors) can upload their own avatar 1. Enables rating of local avatars, just like Gravatar - == Installation == 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 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. - == Screenshots == 1. Avatar upload field on a user profile page - == Changelog == += 2.2.0 = +* **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/)) +* **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/)) +* **Added:** Ability to retrieve avatar with `WP_Post` object (props [@oscarssanchez](https://profiles.wordpress.org/oscarssanchez), [@blobaugh](https://profiles.wordpress.org/blobaugh)) +* **Added:** class and ID to Avatar section on Profile Page to allow easier styling (props [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/)) +* **Added:** [WP Acceptance](https://github.com/10up/wpacceptance/) test coverage (props [@dinhtungdu](https://profiles.wordpress.org/dinhtungdu/)) +* **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/)) +* **Changed:** `assign_new_user_avatar` function to public (props [@tripflex](https://profiles.wordpress.org/tripflex/)) +* **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/)) +* **Changed:** New plugin banner and icon (props [@JackieKjome](https://profiles.wordpress.org/jackiekjome/)) +* **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/)) +* **Changed:** GitHub Actions from HCL to YAML workflow syntax (props [@jeffpaul](https://profiles.wordpress.org/jeffpaul)) +* **Changed:** Documentation updates (props [@jeffpaul](https://profiles.wordpress.org/jeffpaul)) +* **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)) +* **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/)) + = 2.1.1 = * 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. @@ -72,7 +86,7 @@ You can also use `get_simple_local_avatar()` (with the same arguments) to retrei * Optimization for WordPress 3.2 / 3.3 (substitutes deprecated function) = 1.3 = -* Avatar file name saved as "user-display-name_avatar" (or other image extension) +* Avatar file name saved as "user-display-name_avatar" (or other image extension) * Russian localization added * Assorted minor code optimizations @@ -109,7 +123,6 @@ You can also use `get_simple_local_avatar()` (with the same arguments) to retrei * 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. * Localization support; German included - == Upgrade Notice == = 2.1 = diff --git a/wp-content/plugins/simple-local-avatars/screenshot-1.png b/wp-content/plugins/simple-local-avatars/screenshot-1.png deleted file mode 100644 index ebd81d0be2e84c9a9b0764df91555ab4560dca71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76478 zcmc$^Wl-GTvM!7zKp?m~3=Tm<7@XivkU$_<(BLw-yEC}EyF+kycXxMpzmWev=j{E~ z`|VcU^I_Iht@%x_?$z=<-7^8-WJEuH!219J0r62>Oh_IA;$0O41hfPk)a%ZYzvcu4 zB(0CQ&{su!$ipQM1D!dd*0Y-ydPI7D6l(VjDGZ+sY7B}f77S_~i0_<=Qw4GqsNIP3 z!kLpW$z<@0{Ll=*);omdf$OFzP{i`!Y`my6FL94H2n6DCF9o^YXrjIzqva6*cztsR zzMV+|eqA8^-!>rD;a-=2-=_ z^XLK$G^ zzW?GjA#C}nDUN(j-?ThytiI$IhmaY1G~6SL{qt%we18b}Xr$QIpd#f?0`bYrz|E;L z#yR^>#UH2HIy!+QIVlES=SL7ys0`o7mj~zAoyZ>J$$iPl>c$E9H#gk+Y>4eP4f~dX zA9fNA|J2g!Xg6w({E4Xw1RkszF*fPnmEB-S+v4?!RvH&yUG3f6_f%r<6uQcHQ#}<{ zZq?1SxK7aMY#-Zys?)l-AK2N{?08gumHWdT7~vP(ZR20Qn`NW*5&Or1`sy22lix9qJhv@I$V z2?z6o0mSb~p%7kk8%6Z^x%YjLGrfRRlxF1^X>|?zT<%h4eoolXv)J(7ra;TW+|sgI z2_GxfRnLYPwO{c@)76xS>G4qEM(@13|C_pE~A0>+u=*>&ZO zBY(^v4}n&(Cp@Tc)q$TNo@$eox7mQunMP;*d}#dg!Lh@IGf4NwNbSsZC6!S0ysu)t zx8^nF-m>uvKFzth@eWAJ`*3k++y=KJHgfaDBqyDe&x}EaLG-wM_lzGsRz(9;A2q>@G?MTsvG@rGCz7k|;5 zDI8vn%EiQIk8m81Ll>1%c1w+9YQHRrM9IbI|&ZPo~n_R@1iE0yN#$h zFLG;?p4K1C@KoB596-l|;d|EOCdfP0p;M85m&Y3#6N7JQiz1rh{cuH(b%
QI?9 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%0AGS|k`7wTV7OB+* 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 diff --git a/wp-content/plugins/simple-local-avatars/simple-local-avatars.php b/wp-content/plugins/simple-local-avatars/simple-local-avatars.php index cc1420d6..172b5f97 100644 --- a/wp-content/plugins/simple-local-avatars/simple-local-avatars.php +++ b/wp-content/plugins/simple-local-avatars/simple-local-avatars.php @@ -1,661 +1,60 @@ -options = (array) get_option( 'simple_local_avatars' ); - $this->avatar_ratings = array( - 'G' => __('G — Suitable for all audiences'), - 'PG' => __('PG — Possibly offensive, usually for audiences 13 and above'), - 'R' => __('R — Intended for adult audiences above 17'), - 'X' => __('X — Even more mature than above') - ); - - // supplement remote avatars, but not if inside "local only" mode - if ( empty( $this->options['only'] ) ) - add_filter( 'get_avatar', array( $this, 'get_avatar' ), 10, 5 ); - - add_action( 'admin_init', array( $this, 'admin_init' ) ); - - add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); - add_action( 'show_user_profile', array( $this, 'edit_user_profile' ) ); - add_action( 'edit_user_profile', array( $this, 'edit_user_profile' ) ); - - add_action( 'personal_options_update', array( $this, 'edit_user_profile_update' ) ); - add_action( 'edit_user_profile_update', array( $this, 'edit_user_profile_update' ) ); - add_action( 'admin_action_remove-simple-local-avatar', array( $this, 'action_remove_simple_local_avatar' ) ); - add_action( 'wp_ajax_assign_simple_local_avatar_media', array( $this, 'ajax_assign_simple_local_avatar_media' ) ); - add_action( 'wp_ajax_remove_simple_local_avatar', array( $this, 'action_remove_simple_local_avatar' ) ); - add_action( 'user_edit_form_tag', array( $this, 'user_edit_form_tag' ) ); - - add_filter( 'avatar_defaults', array( $this, 'avatar_defaults' ) ); - - add_action( 'rest_api_init', array( $this, 'register_rest_fields' ) ); - } - - /** - * Retrieve the local avatar for a user who provided a user ID or email address. - * - * @param string $avatar Avatar return by original function - * @param int|string|object $id_or_email A user ID, email address, or comment object - * @param int $size Size of the avatar image - * @param string $default URL to a default image to use if no avatar is available - * @param string $alt Alternative text to use in image tag. Defaults to blank - * @return string tag for the user's avatar - */ - public function get_avatar( $avatar = '', $id_or_email = '', $size = 96, $default = '', $alt = '' ) { - if ( is_numeric( $id_or_email ) ) - $user_id = (int) $id_or_email; - elseif ( is_string( $id_or_email ) && ( $user = get_user_by( 'email', $id_or_email ) ) ) - $user_id = $user->ID; - elseif ( is_object( $id_or_email ) && ! empty( $id_or_email->user_id ) ) - $user_id = (int) $id_or_email->user_id; - - if ( empty( $user_id ) ) - return $avatar; - - // fetch local avatar from meta and make sure it's properly ste - $local_avatars = get_user_meta( $user_id, 'simple_local_avatar', true ); - if ( empty( $local_avatars['full'] ) ) - return $avatar; - - // check rating - $avatar_rating = get_user_meta( $user_id, 'simple_local_avatar_rating', true ); - if ( ! empty( $avatar_rating ) && 'G' != $avatar_rating && ( $site_rating = get_option( 'avatar_rating' ) ) ) { - $ratings = array_keys( $this->avatar_ratings ); - $site_rating_weight = array_search( $site_rating, $ratings ); - $avatar_rating_weight = array_search( $avatar_rating, $ratings ); - if ( false !== $avatar_rating_weight && $avatar_rating_weight > $site_rating_weight ) - return $avatar; - } - - // handle "real" media - if ( ! empty( $local_avatars['media_id'] ) ) { - // has the media been deleted? - if ( ! $avatar_full_path = get_attached_file( $local_avatars['media_id'] ) ) { - return $avatar; - } - } - - $size = (int) $size; - - if ( empty( $alt ) ) - $alt = get_the_author_meta( 'display_name', $user_id ); - - // generate a new size - if ( ! array_key_exists( $size, $local_avatars ) ) { - $local_avatars[$size] = $local_avatars['full']; // just in case of failure elsewhere - - // allow automatic rescaling to be turned off - if ( $allow_dynamic_resizing = apply_filters( 'simple_local_avatars_dynamic_resize', true ) ) : - - $upload_path = wp_upload_dir(); - - // get path for image by converting URL, unless its already been set, thanks to using media library approach - if ( ! isset( $avatar_full_path ) ) - $avatar_full_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $local_avatars['full'] ); - - // generate the new size - $editor = wp_get_image_editor( $avatar_full_path ); - if ( ! is_wp_error( $editor ) ) { - $resized = $editor->resize( $size, $size, true ); - if ( ! is_wp_error( $resized ) ) { - $dest_file = $editor->generate_filename(); - $saved = $editor->save( $dest_file ); - if ( ! is_wp_error( $saved ) ) - $local_avatars[$size] = str_replace( $upload_path['basedir'], $upload_path['baseurl'], $dest_file ); - } - } - - // save updated avatar sizes - update_user_meta( $user_id, 'simple_local_avatar', $local_avatars ); - - endif; - } - - if ( 'http' != substr( $local_avatars[$size], 0, 4 ) ) - $local_avatars[$size] = home_url( $local_avatars[$size] ); - - $author_class = is_author( $user_id ) ? ' current-author' : '' ; - $avatar = "" . esc_attr( $alt ) . ""; - - return apply_filters( 'simple_local_avatar', $avatar ); - } - - public function admin_init() { - // upgrade pre 2.0 option - if ( $old_ops = get_option( 'simple_local_avatars_caps' ) ) { - if ( ! empty( $old_ops['simple_local_avatars_caps'] ) ) - update_option( 'simple_local_avatars', array( 'caps' => 1 ) ); - - delete_option( 'simple_local_avatar_caps' ); - } - - register_setting( 'discussion', 'simple_local_avatars', array( $this, 'sanitize_options' ) ); - 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)', 'simple-local-avatars' ) - ) - ); - 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)', 'simple-local-avatars' ) - ) - ); - } - - /** - * Add scripts to the profile editing page - * - * @param string $hook_suffix Page hook - */ - public function admin_enqueue_scripts( $hook_suffix ) { - if ( 'profile.php' != $hook_suffix && 'user-edit.php' != $hook_suffix ) - return; - - if ( current_user_can( 'upload_files' ) ) - wp_enqueue_media(); - - $user_id = ( 'profile.php' == $hook_suffix ) ? get_current_user_id() : (int) $_GET['user_id']; - - $this->remove_nonce = wp_create_nonce( 'remove_simple_local_avatar_nonce' ); - - $script_name_append = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.dev' : ''; - wp_enqueue_script( 'simple-local-avatars', plugins_url( '', __FILE__ ) . '/simple-local-avatars' . $script_name_append . '.js', array('jquery'), false, true ); - wp_localize_script( 'simple-local-avatars', 'i10n_SimpleLocalAvatars', array( - 'user_id' => $user_id, - 'insertMediaTitle' => __('Choose an Avatar','simple-local-avatars'), - 'insertIntoPost' => __('Set as avatar','simple-local-avatars'), - 'deleteNonce' => $this->remove_nonce, - 'mediaNonce' => wp_create_nonce( 'assign_simple_local_avatar_nonce' ), - ) ); - } - - /** - * Sanitize new settings field before saving - * - * @param array|string $input Passed input values to sanitize - * @return array|string Sanitized input fields - */ - public function sanitize_options( $input ) { - $new_input['caps'] = empty( $input['caps'] ) ? 0 : 1; - $new_input['only'] = empty( $input['only'] ) ? 0 : 1; - return $new_input; - } - - /** - * Settings field for avatar upload capabilities - * - * @param array $args Field arguments - */ - public function avatar_settings_field( $args ) { - $args = wp_parse_args( $args, array( - 'key' => '', - 'desc' => '', - ) ); - - if ( empty( $this->options[$args['key']] ) ) - $this->options[$args['key']] = 0; - - echo ' - - '; - } - - /** - * Output new Avatar fields to user editing / profile screen - * - * @param object $profileuser User object - */ - public function edit_user_profile( $profileuser ) { - ?> -

- - - - - - - - - - - -
- ID ); - remove_filter( 'pre_option_avatar_rating', '__return_null' ); - ?> - - options['caps'] ); - - if ( $upload_rights ) { - do_action( 'simple_local_avatar_notices' ); - wp_nonce_field( 'simple_local_avatar_nonce', '_simple_local_avatar_nonce', false ); - $remove_url = add_query_arg(array( - 'action' => 'remove-simple-local-avatar', - 'user_id' => $profileuser->ID, - '_wpnonce' => $this->remove_nonce, - ) ); - ?> - -

-
- - -

- -

-   - simple_local_avatar ) ) echo ' style="display:none;"'; ?>> -

- simple_local_avatar ) ) - echo '' . __('No local avatar is set. Set up your avatar at Gravatar.com.','simple-local-avatars') . ''; - else - echo '' . __('You do not have media management permissions. To change your local avatar, contact the blog administrator.','simple-local-avatars') . ''; - } - ?> -
-
simple_local_avatar ) ); ?>> - - simple_local_avatar_rating ) || ! array_key_exists( $profileuser->simple_local_avatar_rating, $this->avatar_ratings ) ) - $profileuser->simple_local_avatar_rating = 'G'; - - foreach ( $this->avatar_ratings as $key => $rating ) : - echo "\n\t
"; - endforeach; - ?> -

-
- avatar_delete( $user_id ); // delete old images if successful - - $meta_value = array(); - - // set the new avatar - if ( is_int( $url_or_media_id ) ) { - $meta_value['media_id'] = $url_or_media_id; - $url_or_media_id = wp_get_attachment_url( $url_or_media_id ); - } - - $meta_value['full'] = $url_or_media_id; - - update_user_meta( $user_id, 'simple_local_avatar', $meta_value ); // save user information (overwriting old) - } - - /** - * Save any changes to the user profile - * - * @param int $user_id ID of user being updated - */ - public function edit_user_profile_update( $user_id ) { - // check nonces - if( empty( $_POST['_simple_local_avatar_nonce'] ) || ! wp_verify_nonce( $_POST['_simple_local_avatar_nonce'], 'simple_local_avatar_nonce' ) ) - return; - - // check for uploaded files - if ( ! empty( $_FILES['simple-local-avatar']['name'] ) ) : - - // need to be more secure since low privelege users can upload - if ( false !== strpos( $_FILES['simple-local-avatar']['name'], '.php' ) ) { - $this->avatar_upload_error = __('For security reasons, the extension ".php" cannot be in your file name.','simple-local-avatars'); - add_action( 'user_profile_update_errors', array( $this, 'user_profile_update_errors' ) ); - return; - } - - // front end (theme my profile etc) support - if ( ! function_exists( 'media_handle_upload' ) ) - require_once( ABSPATH . 'wp-admin/includes/media.php' ); - - // allow developers to override file size upload limit for avatars - add_filter( 'upload_size_limit', array( $this, 'upload_size_limit' ) ); - - $this->user_id_being_edited = $user_id; // make user_id known to unique_filename_callback function - $avatar_id = media_handle_upload( 'simple-local-avatar', 0, array(), array( - 'mimes' => array( - 'jpg|jpeg|jpe' => 'image/jpeg', - 'gif' => 'image/gif', - 'png' => 'image/png', - ), - 'test_form' => false, - 'unique_filename_callback' => array( $this, 'unique_filename_callback' ) - ) ); - - remove_filter( 'upload_size_limit', array( $this, 'upload_size_limit' ) ); - - if ( is_wp_error( $avatar_id ) ) { // handle failures. - $this->avatar_upload_error = '' . __( 'There was an error uploading the avatar:', 'simple-local-avatars' ) . ' ' . esc_html( $avatar_id->get_error_message() ); - add_action( 'user_profile_update_errors', array( $this, 'user_profile_update_errors' ) ); - return; - } - - $this->assign_new_user_avatar( $avatar_id, $user_id ); - - endif; - - // handle rating - if ( isset( $avatar_id ) || $avatar = get_user_meta( $user_id, 'simple_local_avatar', true ) ) { - if ( empty( $_POST['simple_local_avatar_rating'] ) || ! array_key_exists( $_POST['simple_local_avatar_rating'], $this->avatar_ratings ) ) - $_POST['simple_local_avatar_rating'] = key( $this->avatar_ratings ); - - update_user_meta( $user_id, 'simple_local_avatar_rating', $_POST['simple_local_avatar_rating'] ); - } - } - - /** - * Allow developers to override the maximum allowable file size for avatar uploads - * - * @param int $bytes WordPress default byte size check - * @return int Maximum byte size - */ - public function upload_size_limit( $bytes ) { - return apply_filters( 'simple_local_avatars_upload_limit', $bytes ); - } - - /** - * Runs when a user clicks the Remove button for the avatar - */ - public function action_remove_simple_local_avatar() { - if ( ! empty( $_GET['user_id'] ) && ! empty( $_GET['_wpnonce'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'remove_simple_local_avatar_nonce' ) ) { - $user_id = (int) $_GET['user_id']; - - if ( ! current_user_can('edit_user', $user_id) ) - wp_die( __('You do not have permission to edit this user.') ); - - $this->avatar_delete( $user_id ); // delete old images if successful - - if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) - echo get_simple_local_avatar( $user_id ); - } - - if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) - die; - } - - /** - * AJAX callback for assigning media ID fetched from media library to user - */ - public function ajax_assign_simple_local_avatar_media() { - // check required information and permissions - 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' ) ) - die; - - $media_id = (int) $_POST['media_id']; - $user_id = (int) $_POST['user_id']; - - // ensure the media is real is an image - if ( wp_attachment_is_image( $media_id ) ) - $this->assign_new_user_avatar( $media_id, $user_id ); - - echo get_simple_local_avatar( $user_id ); - - die; - } - - /** - * remove the custom get_avatar hook for the default avatar list output on options-discussion.php - */ - public function avatar_defaults( $avatar_defaults ) { - remove_action( 'get_avatar', array( $this, 'get_avatar' ) ); - return $avatar_defaults; - } - - /** - * Delete avatars based on a user_id - * - * @param int $user_id - */ - public function avatar_delete( $user_id ) { - $old_avatars = (array) get_user_meta( $user_id, 'simple_local_avatar', true ); - - if ( empty( $old_avatars ) ) - return; - - // if it was uploaded media, don't erase the full size or try to erase an the ID - if ( array_key_exists( 'media_id', $old_avatars ) ) - unset( $old_avatars['media_id'], $old_avatars['full'] ); - - if ( ! empty( $old_avatars ) ) { - $upload_path = wp_upload_dir(); - - foreach ($old_avatars as $old_avatar ) { - // derive the path for the file based on the upload directory - $old_avatar_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $old_avatar ); - if ( file_exists( $old_avatar_path ) ) - unlink( $old_avatar_path ); - } - } - - delete_user_meta( $user_id, 'simple_local_avatar' ); - delete_user_meta( $user_id, 'simple_local_avatar_rating' ); - } - - /** - * Creates a unique, meaningful file name for uploaded avatars. - * - * @param string $dir Path for file - * @param string $name Filename - * @param string $ext File extension (e.g. ".jpg") - * @return string Final filename - */ - public function unique_filename_callback( $dir, $name, $ext ) { - $user = get_user_by( 'id', (int) $this->user_id_being_edited ); - $name = $base_name = sanitize_file_name( $user->display_name . '_avatar_' . time() ); - - // ensure no conflicts with existing file names - $number = 1; - while ( file_exists( $dir . "/$name$ext" ) ) { - $name = $base_name . '_' . $number; - $number++; - } - - return $name . $ext; - } - - /** - * Adds errors based on avatar upload problems. - * - * @param WP_Error $errors Error messages for user profile screen. - */ - public function user_profile_update_errors( WP_Error $errors ) { - $errors->add( 'avatar_error', $this->avatar_upload_error ); - } - - /** - * Registers the simple_local_avatar field in the REST API. - */ - public function register_rest_fields() { - register_rest_field( 'user', 'simple_local_avatar', array( - 'get_callback' => array( $this, 'get_avatar_rest' ), - 'update_callback' => array( $this, 'set_avatar_rest' ), - 'schema' => array( - 'description' => 'The users simple local avatar', - 'type' => 'object', - ) - )); - } - - /** - * Returns the simple_local_avatar meta key for the given user. - * - * @param object $user User object - */ - public function get_avatar_rest( $user ) { - $local_avatar = get_user_meta( $user['id'], 'simple_local_avatar', true ); - if ( empty( $local_avatar ) ) { - return; - } - return $local_avatar; - } - - /** - * Updates the simple local avatar from a REST request. - * - * Since we are just adding a field to the existing user endpoint - * we don't need to worry about ensuring the calling user has proper permissions. - * Only the user or an administrator would be able to change the avatar. - * - * @param array $input Input submitted via REST request. - * @param object $user The user making the request. - */ - public function set_avatar_rest( $input, $user ) { - $this->assign_new_user_avatar($input['media_id'], $user->ID); - } - -} - -$simple_local_avatars = new Simple_Local_Avatars; - -/** - * more efficient to call simple local avatar directly in theme and avoid gravatar setup - * - * @param int|string|object $id_or_email A user ID, email address, or comment object - * @param int $size Size of the avatar image - * @param string $default URL to a default image to use if no avatar is available - * @param string $alt Alternate text to use in image tag. Defaults to blank - * @return string tag for the user's avatar - */ -function get_simple_local_avatar( $id_or_email, $size = 96, $default = '', $alt = '' ) { - global $simple_local_avatars; - $avatar = $simple_local_avatars->get_avatar( '', $id_or_email, $size, $default, $alt ); - - if ( empty ( $avatar ) ) { - remove_action( 'get_avatar', array( $simple_local_avatars, 'get_avatar' ) ); - $avatar = get_avatar( $id_or_email, $size, $default, $alt ); - add_action( 'get_avatar', array( $simple_local_avatars, 'get_avatar' ), 10, 5 ); - } - - return $avatar; -} - -if ( ! function_exists( 'get_avatar' ) && ( $simple_local_avatars_options = get_option('simple_local_avatars') ) && ! empty( $simple_local_avatars_options['only'] ) ) : - - /** - * Retrieve the avatar for a user who provided a user ID or email address. - * - * @param int|string|object $id_or_email A user ID, email address, or comment object - * @param int $size Size of the avatar image - * @param string $default URL to a default image to use if no avatar is available - * @param string $alt Alternative text to use in image tag. Defaults to blank - * @return string tag for the user's avatar - */ - function get_avatar( $id_or_email, $size = 96, $default = '', $alt = '' ) { - global $simple_local_avatars; - - if ( ! get_option('show_avatars') ) - return false; - - $safe_alt = empty( $alt ) ? '' : esc_attr( $alt ); - - if ( !is_numeric($size) ) - $size = 96; - - if ( ! $avatar = $simple_local_avatars->get_avatar( '', $id_or_email, $size, $default, $alt ) ) : - - if ( empty($default) ) { - $avatar_default = get_option('avatar_default'); - if ( empty($avatar_default) ) - $default = 'mystery'; - else - $default = $avatar_default; - } - - $host = is_ssl() ? 'https://secure.gravatar.com' : 'http://0.gravatar.com'; - - if ( 'mystery' == $default ) - $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}"; // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com') - elseif ( 'blank' == $default ) - $default = includes_url( 'images/blank.gif' ); - elseif ( 'gravatar_default' == $default ) - $default = "$host/avatar/?s={$size}"; - else - $default = "$host/avatar/?d=$default&s={$size}"; - - $avatar = "{$safe_alt}"; - - endif; - - return apply_filters('get_avatar', $avatar, $id_or_email, $size, $default, $alt); - } - -endif; - -/** - * on uninstallation, remove the custom field from the users and delete the local avatars - */ - -register_uninstall_hook( __FILE__, 'simple_local_avatars_uninstall' ); - -function simple_local_avatars_uninstall() { - $simple_local_avatars = new Simple_Local_Avatars; - $users = get_users(array( - 'meta_key' => 'simple_local_avatar', - 'fields' => 'ids', - )); - - foreach ( $users as $user_id ): - $simple_local_avatars->avatar_delete( $user_id ); - endforeach; - - delete_option('simple_local_avatars'); -} + tag for the user's avatar + */ +function get_simple_local_avatar( $id_or_email, $size = 96, $default = '', $alt = '', $args = array() ) { + return apply_filters( 'simple_local_avatar', get_avatar( $id_or_email, $size, $default, $alt, $args ) ); +} + +register_uninstall_hook( __FILE__, 'simple_local_avatars_uninstall' ); +/** + * On uninstallation, remove the custom field from the users and delete the local avatars + */ +function simple_local_avatars_uninstall() { + $simple_local_avatars = new Simple_Local_Avatars(); + $users = get_users( + array( + 'meta_key' => 'simple_local_avatar', + 'fields' => 'ids', + ) + ); + + foreach ( $users as $user_id ) : + $simple_local_avatars->avatar_delete( $user_id ); + endforeach; + + delete_option( 'simple_local_avatars' ); +}