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 index 0eb8fa84..09cf948a 100644 --- 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 @@ -65,9 +65,9 @@ class Simple_Local_Avatars { public function __construct() { $this->add_hooks(); - $this->options = (array) get_option( 'simple_local_avatars' ); - $this->user_key = 'simple_local_avatar'; - $this->rating_key = 'simple_local_avatar_rating'; + $this->options = (array) get_option( 'simple_local_avatars' ); + $this->user_key = 'simple_local_avatar'; + $this->rating_key = 'simple_local_avatar_rating'; if ( ! $this->is_avatar_shared() // Are we sharing avatars? @@ -136,18 +136,26 @@ class Simple_Local_Avatars { } if ( 'profile.php' === $pagenow ) { - add_filter( 'media_view_strings', function ( $strings ) { - $strings['skipCropping'] = esc_html__( 'Default Crop', 'simple-local-avatars' ); + add_filter( + 'media_view_strings', + function ( $strings ) { + $strings['skipCropping'] = esc_html__( 'Default Crop', 'simple-local-avatars' ); - return $strings; - }, 10, 1 ); + return $strings; + }, + 10, + 1 + ); } // Fix: An error occurred cropping the image (https://github.com/10up/simple-local-avatars/issues/141). if ( isset( $_POST['action'] ) && 'crop-image' === $_POST['action'] && is_admin() && wp_doing_ajax() ) { - add_action( 'plugins_loaded', function () { - remove_all_actions( 'setup_theme' ); - } ); + add_action( + 'plugins_loaded', + function () { + remove_all_actions( 'setup_theme' ); + } + ); } } @@ -202,13 +210,13 @@ class Simple_Local_Avatars { * @return boolean */ public function is_avatar_shared() { + if ( ! is_multisite() ) { + return false; + } + if ( - is_multisite() // Are we on multisite. - && ! isset( $this->options['shared'] ) // And our shared option doesn't exist. - || ( - isset( $this->options['shared'] ) // Or our shared option is set. - && 1 === $this->options['shared'] - ) + ! isset( $this->options['shared'] ) // Our shared option doesn't exist. + || 1 === $this->options['shared'] // Or our shared option is set. ) { return true; } @@ -330,14 +338,21 @@ class Simple_Local_Avatars { */ public function get_simple_local_avatar_url( $id_or_email, $size ) { $user_id = $this->get_user_id( $id_or_email ); + $size = (int) $size; if ( empty( $user_id ) ) { return ''; } - // Fetch local avatar from meta and make sure it's properly set. $local_avatars = get_user_meta( $user_id, $this->user_key, true ); - if ( empty( $local_avatars['full'] ) ) { + + // Return avatar if exists. + if ( is_array( $local_avatars ) && array_key_exists( $size, $local_avatars ) && ( strpos( $local_avatars[ $size ], content_url() ) === 0 ) ) { + return esc_url( $local_avatars[ $size ] ); + } + + // Fetch local avatar from meta and make sure it's properly set. + if ( empty( $local_avatars['media_id'] ) ) { return ''; } @@ -353,70 +368,88 @@ class Simple_Local_Avatars { } } - // handle "real" media - if ( ! empty( $local_avatars['media_id'] ) ) { - // If using shared avatars, make sure we validate the URL on the main site. - if ( $this->is_avatar_shared() ) { - $origin_blog_id = isset( $local_avatars['blog_id'] ) && ! empty( $local_avatars['blog_id'] ) ? $local_avatars['blog_id'] : get_main_site_id(); - switch_to_blog( $origin_blog_id ); - } + /** + * Filter the URL of an avatar for the given user and size. + * + * This filters is applied before Simple Local Avatars validates the value of the + * `$local_avatars` array which comes from the user meta field. This allows the URL + * to be short-circuited, for example by a dynamic image resizing service. + * + * @param string|null $url The URL of the avatar. If null, the URL will be + * generated by Simple Local Avatars. + * @param int $user_id The user ID. + * @param int $size Requested avatar size. + * @param array $local_avatars The local avatars for the user. + * @return string|null The URL of the avatar, or null to allow Simple Local Avatars to + * generate the URL. + */ + $url = apply_filters( 'pre_simple_local_avatar_url', null, $user_id, $size, $local_avatars ); - $avatar_full_path = get_attached_file( $local_avatars['media_id'] ); - - if ( $this->is_avatar_shared() ) { - restore_current_blog(); - } - - // has the media been deleted? - if ( ! $avatar_full_path ) { - return ''; - } + if ( is_string( $url ) ) { + return esc_url( $url ); } - $size = (int) $size; + // handle "real" media + // If using shared avatars, make sure we validate the URL on the main site. + if ( $this->is_avatar_shared() ) { + $origin_blog_id = ! empty( $local_avatars['blog_id'] ) ? $local_avatars['blog_id'] : get_main_site_id(); + switch_to_blog( $origin_blog_id ); + } + + $avatar_full_path = get_attached_file( $local_avatars['media_id'] ); + + if ( $this->is_avatar_shared() ) { + restore_current_blog(); + } + + // has the media been deleted? + if ( ! $avatar_full_path ) { + return ''; + } + + // Use dynamic full url in favour of host/domain change. + $local_avatars['full'] = wp_get_attachment_image_url( $local_avatars['media_id'], 'full' ); // Generate a new size. - if ( ! array_key_exists( $size, $local_avatars ) ) { - $local_avatars[ $size ] = $local_avatars['full']; // just in case of failure elsewhere + // Just in case of failure elsewhere, set the full size as default. + $local_avatars[ $size ] = $local_avatars['full']; - // allow automatic rescaling to be turned off - if ( apply_filters( 'simple_local_avatars_dynamic_resize', true ) ) : + // allow automatic rescaling to be turned off + if ( apply_filters( 'simple_local_avatars_dynamic_resize', true ) ) : - $upload_path = wp_upload_dir(); + $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'] ); - } + // 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 ) ) { - // Transform the destination file path into URL. - $dest_file_url = ''; - if ( false !== strpos( $dest_file, $upload_path['basedir'] ) ) { - $dest_file_url = str_replace( $upload_path['basedir'], $upload_path['baseurl'], $dest_file ); - } else if ( is_multisite() && false !== strpos( $dest_file, ABSPATH . 'wp-content/uploads' ) ) { - $dest_file_url = str_replace( ABSPATH . 'wp-content/uploads', network_site_url( '/wp-content/uploads' ), $dest_file ); - } - - $local_avatars[ $size ] = $dest_file_url; + // 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 ) ) { + // Transform the destination file path into URL. + $dest_file_url = ''; + if ( false !== strpos( $dest_file, $upload_path['basedir'] ) ) { + $dest_file_url = str_replace( $upload_path['basedir'], $upload_path['baseurl'], $dest_file ); + } elseif ( is_multisite() && false !== strpos( $dest_file, ABSPATH . 'wp-content/uploads' ) ) { + $dest_file_url = str_replace( ABSPATH . 'wp-content/uploads', network_site_url( '/wp-content/uploads' ), $dest_file ); } + + $local_avatars[ $size ] = $dest_file_url; } } + } - // save updated avatar sizes - update_user_meta( $user_id, $this->user_key, $local_avatars ); + // save updated avatar sizes + update_user_meta( $user_id, $this->user_key, $local_avatars ); + endif; - endif; - } - - if ( 'http' !== substr( $local_avatars[ $size ], 0, 4 ) ) { + if ( strpos( $local_avatars[ $size ], 'http' ) !== 0 ) { $local_avatars[ $size ] = home_url( $local_avatars[ $size ] ); } @@ -1004,7 +1037,7 @@ class Simple_Local_Avatars { * * @param int $user_id Id of the user who's avatar was updated */ - do_action( 'simple_local_avatar_updated' , $user_id ); + do_action( 'simple_local_avatar_updated', $user_id ); } /** @@ -1411,9 +1444,9 @@ class Simple_Local_Avatars { $file_name_data = pathinfo( get_attached_file( $media_id ) ); } - $file_dir_name = $file_name_data['dirname']; - $file_name = $file_name_data['filename']; - $file_ext = $file_name_data['extension']; + $file_dir_name = $file_name_data['dirname']; + $file_name = $file_name_data['filename']; + $file_ext = $file_name_data['extension']; foreach ( $local_avatars as $local_avatars_key => $local_avatar_value ) { if ( ! in_array( $local_avatars_key, [ 'media_id', 'full' ], true ) ) { $file_size_path = sprintf( '%1$s/%2$s-%3$sx%3$s.%4$s', $file_dir_name, $file_name, $local_avatars_key, $file_ext ); @@ -1436,9 +1469,6 @@ class Simple_Local_Avatars { * @return array Default options of avatar. */ public function add_avatar_default_field( $defaults ) { - if ( ! did_action( 'wp_enqueue_media' ) ) { - wp_enqueue_media(); - } $default_avatar_file_url = ''; $default_avatar_file_id = get_option( 'simple_local_avatar_default', '' ); if ( ! empty( $default_avatar_file_id ) ) { diff --git a/wp-content/plugins/simple-local-avatars/readme.txt b/wp-content/plugins/simple-local-avatars/readme.txt index f051650f..8327a85e 100644 --- a/wp-content/plugins/simple-local-avatars/readme.txt +++ b/wp-content/plugins/simple-local-avatars/readme.txt @@ -3,9 +3,9 @@ Contributors: jakemgold, 10up, thinkoomph, jeffpaul, faisal03 Donate link: https://10up.com/plugins/simple-local-avatars-wordpress/ Tags: avatar, gravatar, user photos, users, profile Requires at least: 5.7 -Tested up to: 6.2 +Tested up to: 6.4 Requires PHP: 7.4 -Stable tag: 2.7.5 +Stable tag: 2.7.6 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -35,13 +35,40 @@ 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. +== Frequently Asked Questions == + += Does Simple Local Avatars collect personal data of website visitors? = + +No. Simple Local Avatars neither collects, stores, nor sends any PII data of visitors or avatar users on the host site or to 10up or other services. + == Screenshots == 1. Avatar upload field on a user profile page == Changelog == -## [2.7.5] - 2023-05-12 = += 2.7.6 - 2023-11-30 = +* **Added:** Check for minimum required PHP version before loading the plugin (props [@kmgalanakis](https://github.com/kmgalanakis), [@faisal-alvi](https://github.com/faisal-alvi) via [#226](https://github.com/10up/simple-local-avatars/pull/226)). +* **Added:** `pre_simple_local_avatar_url` filter to allow an avatar image to be short-circuited before Simple Local Avatars processes it (props [@johnbillion](https://github.com/johnbillion), [@peterwilsoncc](https://github.com/peterwilsoncc) via [#237](https://github.com/10up/simple-local-avatars/pull/237)). +* **Added:** Repo Automator GitHub Action (props [@iamdharmesh](https://github.com/iamdharmesh), [@faisal-alvi](https://github.com/faisal-alvi) via [#228](https://github.com/10up/simple-local-avatars/pull/228)). +* **Added:** E2E test for checking the front end of avatars (props [@Firestorm980](https://github.com/Firestorm980), [@iamdharmesh](https://github.com/iamdharmesh) via [#219](https://github.com/10up/simple-local-avatars/pull/219)). +* **Changed:** Bumped WordPress "tested up to" version 6.4 (props [@zamanq](https://github.com/zamanq), [@ankitguptaindia](https://github.com/ankitguptaindia), [@faisal-alvi](https://github.com/faisal-alvi), [@qasumitbagthariya](https://github.com/qasumitbagthariya) via [#230](https://github.com/10up/simple-local-avatars/pull/230), [#244](https://github.com/10up/simple-local-avatars/pull/244)). +* **Changed:** Update the Dependency Review GitHub Action to leverage our org-wide config file to check for GPL-compatible licenses (props [@jeffpaul](https://github.com/jeffpaul), [@faisal-alvi](https://github.com/faisal-alvi) via [#215](https://github.com/10up/simple-local-avatars/pull/215)). +* **Changed:** Documentation updates (props [@jeffpaul](https://github.com/jeffpaul), [@faisal-alvi](https://github.com/faisal-alvi) via [#242](https://github.com/10up/simple-local-avatars/pull/242)). +* **Fixed:** Address conflicts with other plugins and loading the media API (props [@EHLOVader](https://github.com/EHLOVader), [@dkotter](https://github.com/dkotter) via [#218](https://github.com/10up/simple-local-avatars/pull/218)). +* **Fixed:** Prevent PHP fatal error when switching from a multisite to single site installation (props [@ocean90](https://github.com/ocean90), [@ravinderk](https://github.com/ravinderk), [@faisal-alvi](https://github.com/faisal-alvi) via [#222](https://github.com/10up/simple-local-avatars/pull/222)). +* **Fixed:** Local avatar urls remain old after domain/host change (props [@jayedul](https://github.com/jayedul), [@ravinderk](https://github.com/ravinderk), [@jeffpaul](https://github.com/jeffpaul), [@faisal-alvi](https://github.com/faisal-alvi) via [#216](https://github.com/10up/simple-local-avatars/pull/216)). +* **Security:** Bump `word-wrap` from 1.2.3 to 1.2.4 (props [@dependabot](https://github.com/apps/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#223](https://github.com/10up/simple-local-avatars/pull/223)). +* **Security:** Bump `tough-cookie` from 4.1.2 to 4.1.3 (props [@dependabot](https://github.com/apps/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#225](https://github.com/10up/simple-local-avatars/pull/225)). +* **Security:** Bump `@cypress/request` from 2.88.10 to 3.0.0 (props [@dependabot](https://github.com/apps/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#225](https://github.com/10up/simple-local-avatars/pull/225), [#234](https://github.com/10up/simple-local-avatars/pull/234)). +* **Security:** Bump `cypress` from 11.2.0 to 13.2.0 (props [@dependabot](https://github.com/apps/dependabot), [@faisal-alvi](https://github.com/faisal-alvi), [@iamdharmesh](https://github.com/iamdharmesh) via [#234](https://github.com/10up/simple-local-avatars/pull/234), [#236](https://github.com/10up/simple-local-avatars/pull/236)). +* **Security:** Bump `postcss` from 8.4.21 to 8.4.31 (props [@dependabot](https://github.com/apps/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#238](https://github.com/10up/simple-local-avatars/pull/238)). +* **Security:** Bump `@babel/traverse` from 7.20.12 to 7.23.2 (props [@dependabot](https://github.com/apps/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#240](https://github.com/10up/simple-local-avatars/pull/240)). +* **Security:** Bump `@10up/cypress-wp-utils` version to 0.2.0 (props [@iamdharmesh](https://github.com/iamdharmesh), [@faisal-alvi](https://github.com/faisal-alvi) via [#236](https://github.com/10up/simple-local-avatars/pull/236)). +* **Security:** Bump `@wordpress/env` version from 5.2.0 to 8.7.0 (props [@iamdharmesh](https://github.com/iamdharmesh), [@faisal-alvi](https://github.com/faisal-alvi) via [#236](https://github.com/10up/simple-local-avatars/pull/236)). +* **Security:** Bump `cypress-mochawesome-reporter` version from 3.0.1 to 3.6.0 (props [@iamdharmesh](https://github.com/iamdharmesh), [@faisal-alvi](https://github.com/faisal-alvi) via [#236](https://github.com/10up/simple-local-avatars/pull/236)). + += 2.7.5 - 2023-05-15 = * **Added:** Ajax loading animation during process of uploading and deleting local avatars (props [@lllopo](https://github.com/lllopo), [@BhargavBhandari90](https://github.com/BhargavBhandari90), [@faisal-alvi](https://github.com/faisal-alvi) via [#204](https://github.com/10up/simple-local-avatars/pull/204)). * **Changed:** Avatar removal button text (props [@jayedul](https://github.com/jayedul), [@jeffpaul](https://github.com/jeffpaul), [@dkotter](https://github.com/dkotter), [@faisal-alvi](https://github.com/faisal-alvi) via [#208](https://github.com/10up/simple-local-avatars/pull/208)). * **Changed:** WordPress "tested up to" version 6.2 (props [@jayedul](https://github.com/jayedul), [@faisal-alvi](https://github.com/faisal-alvi) via [#210](https://github.com/10up/simple-local-avatars/pull/210)). 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 15021494..b05ea1bc 100644 --- a/wp-content/plugins/simple-local-avatars/simple-local-avatars.php +++ b/wp-content/plugins/simple-local-avatars/simple-local-avatars.php @@ -3,7 +3,7 @@ * Plugin Name: Simple Local Avatars * Plugin URI: https://10up.com/plugins/simple-local-avatars-wordpress/ * Description: Adds an avatar upload field to user profiles. Generates requested sizes on demand, just like Gravatar! Simple and lightweight. - * Version: 2.7.5 + * Version: 2.7.6 * Requires at least: 5.7 * Requires PHP: 7.4 * Author: 10up @@ -15,12 +15,59 @@ * @package SimpleLocalAvatars */ +/** + * Get the minimum version of PHP required by this plugin. + * + * @since 2.7.6 + * + * @return string Minimum version required. + */ +function minimum_php_requirement(): string { + return '7.4'; +} + +/** + * Whether PHP installation meets the minimum requirements + * + * @since 2.7.6 + * + * @return bool True if meets minimum requirements, false otherwise. + */ +function site_meets_php_requirements(): bool { + return version_compare( phpversion(), minimum_php_requirement(), '>=' ); +} + +// Try to load the plugin files, ensuring our PHP version is met first. +if ( ! site_meets_php_requirements() ) { + add_action( + 'admin_notices', + function() { + ?> +
+

+ +

+
+