diff --git a/wp-content/plugins/activitypub/activitypub.php b/wp-content/plugins/activitypub/activitypub.php index 791a59c4..9c163161 100644 --- a/wp-content/plugins/activitypub/activitypub.php +++ b/wp-content/plugins/activitypub/activitypub.php @@ -3,7 +3,7 @@ * Plugin Name: ActivityPub * Plugin URI: https://github.com/pfefferle/wordpress-activitypub/ * Description: The ActivityPub protocol is a decentralized social networking protocol based upon the ActivityStreams 2.0 data format. - * Version: 2.3.0 + * Version: 2.3.1 * Author: Matthias Pfefferle & Automattic * Author URI: https://automattic.com/ * License: MIT @@ -21,7 +21,7 @@ use function Activitypub\site_supports_blocks; require_once __DIR__ . '/includes/compat.php'; require_once __DIR__ . '/includes/functions.php'; -\define( 'ACTIVITYPUB_PLUGIN_VERSION', '2.3.0' ); +\define( 'ACTIVITYPUB_PLUGIN_VERSION', '2.3.1' ); /** * Initialize the plugin constants. diff --git a/wp-content/plugins/activitypub/includes/class-activity-dispatcher.php b/wp-content/plugins/activitypub/includes/class-activity-dispatcher.php index 16387154..edc41f37 100644 --- a/wp-content/plugins/activitypub/includes/class-activity-dispatcher.php +++ b/wp-content/plugins/activitypub/includes/class-activity-dispatcher.php @@ -98,6 +98,11 @@ class Activity_Dispatcher { return; } + // do not announce replies + if ( $wp_object instanceof WP_Comment ) { + return; + } + $transformer = Factory::get_transformer( $wp_object ); $transformer->change_wp_user_id( Users::BLOG_USER_ID ); diff --git a/wp-content/plugins/activitypub/includes/class-comment.php b/wp-content/plugins/activitypub/includes/class-comment.php index 682fa665..1d52a9bd 100644 --- a/wp-content/plugins/activitypub/includes/class-comment.php +++ b/wp-content/plugins/activitypub/includes/class-comment.php @@ -276,7 +276,7 @@ class Comment { } // check for local comment - if ( \wp_parse_url( \site_url(), \PHP_URL_HOST ) === \wp_parse_url( $url, \PHP_URL_HOST ) ) { + if ( \wp_parse_url( \home_url(), \PHP_URL_HOST ) === \wp_parse_url( $url, \PHP_URL_HOST ) ) { $query = \wp_parse_url( $url, \PHP_URL_QUERY ); if ( $query ) { @@ -379,12 +379,7 @@ class Comment { } // generate URI based on comment ID - return \add_query_arg( - array( - 'c' => $comment->comment_ID, - ), - \trailingslashit( site_url() ) - ); + return \add_query_arg( 'c', $comment->comment_ID, \home_url() ); } /** diff --git a/wp-content/plugins/activitypub/includes/class-health-check.php b/wp-content/plugins/activitypub/includes/class-health-check.php index e07684f9..878ee85d 100644 --- a/wp-content/plugins/activitypub/includes/class-health-check.php +++ b/wp-content/plugins/activitypub/includes/class-health-check.php @@ -27,7 +27,7 @@ class Health_Check { } public static function add_tests( $tests ) { - if ( ! is_user_type_disabled( 'user' ) ) { + if ( ! is_user_disabled( get_current_user_id() ) ) { $tests['direct']['activitypub_test_author_url'] = array( 'label' => \__( 'Author URL test', 'activitypub' ), 'test' => array( self::class, 'test_author_url' ), diff --git a/wp-content/plugins/activitypub/includes/class-http.php b/wp-content/plugins/activitypub/includes/class-http.php index 12755ceb..5c9496b0 100644 --- a/wp-content/plugins/activitypub/includes/class-http.php +++ b/wp-content/plugins/activitypub/includes/class-http.php @@ -66,14 +66,26 @@ class Http { /** * Send a GET Request with the needed HTTP Headers * - * @param string $url The URL endpoint - * @param int $user_id The WordPress User-ID + * @param string $url The URL endpoint + * @param bool|int $cached If the result should be cached, or its duration. Default: 1hr. * * @return array|WP_Error The GET Response or an WP_ERROR */ - public static function get( $url ) { + public static function get( $url, $cached = false ) { \do_action( 'activitypub_pre_http_get', $url ); + if ( $cached ) { + $transient_key = self::generate_cache_key( $url ); + + $response = \get_transient( $transient_key ); + + if ( $response ) { + \do_action( 'activitypub_safe_remote_get_response', $response, $url ); + + return $response; + } + } + $date = \gmdate( 'D, d M Y H:i:s T' ); $signature = Signature::generate_signature( Users::APPLICATION_USER_ID, 'get', $url, $date ); @@ -108,6 +120,14 @@ class Http { \do_action( 'activitypub_safe_remote_get_response', $response, $url ); + if ( $cached ) { + $cache_duration = $cached; + if ( ! is_int( $cache_duration ) ) { + $cache_duration = HOUR_IN_SECONDS; + } + \set_transient( $transient_key, $response, $cache_duration ); + } + return $response; } @@ -130,4 +150,8 @@ class Http { return false; } + + public static function generate_cache_key( $url ) { + return 'activitypub_http_' . \md5( $url ); + } } diff --git a/wp-content/plugins/activitypub/includes/class-scheduler.php b/wp-content/plugins/activitypub/includes/class-scheduler.php index 48a556bc..1f761c75 100644 --- a/wp-content/plugins/activitypub/includes/class-scheduler.php +++ b/wp-content/plugins/activitypub/includes/class-scheduler.php @@ -253,6 +253,11 @@ class Scheduler { } elseif ( empty( $meta ) || ! is_array( $meta ) || is_wp_error( $meta ) ) { if ( $follower->count_errors() >= 5 ) { $follower->delete(); + \wp_schedule_single_event( + \time(), + 'activitypub_delete_actor_interactions', + array( $follower->get_id() ) + ); } else { Followers::add_error( $follower->get__id(), $meta ); } diff --git a/wp-content/plugins/activitypub/includes/class-signature.php b/wp-content/plugins/activitypub/includes/class-signature.php index e59a1f97..e7087595 100644 --- a/wp-content/plugins/activitypub/includes/class-signature.php +++ b/wp-content/plugins/activitypub/includes/class-signature.php @@ -379,10 +379,10 @@ class Signature { if ( \preg_match( '/keyId="(.*?)"/ism', $signature, $matches ) ) { $parsed_header['keyId'] = trim( $matches[1] ); } - if ( \preg_match( '/created=([0-9]*)/ism', $signature, $matches ) ) { + if ( \preg_match( '/created=["|\']*([0-9]*)["|\']*/ism', $signature, $matches ) ) { $parsed_header['(created)'] = trim( $matches[1] ); } - if ( \preg_match( '/expires=([0-9]*)/ism', $signature, $matches ) ) { + if ( \preg_match( '/expires=["|\']*([0-9]*)["|\']*/ism', $signature, $matches ) ) { $parsed_header['(expires)'] = trim( $matches[1] ); } if ( \preg_match( '/algorithm="(.*?)"/ism', $signature, $matches ) ) { @@ -434,12 +434,22 @@ class Signature { // created in future return false; } + + if ( ! array_key_exists( '(created)', $headers ) ) { + $signed_data .= $header . ': ' . $signature_block['(created)'] . "\n"; + continue; + } } if ( '(expires)' === $header ) { if ( ! empty( $signature_block['(expires)'] ) && \intval( $signature_block['(expires)'] ) < \time() ) { // expired in past return false; } + + if ( ! array_key_exists( '(expires)', $headers ) ) { + $signed_data .= $header . ': ' . $signature_block['(expires)'] . "\n"; + continue; + } } if ( 'date' === $header ) { // allow a bit of leeway for misconfigured clocks. diff --git a/wp-content/plugins/activitypub/includes/collection/class-interactions.php b/wp-content/plugins/activitypub/includes/collection/class-interactions.php index 67410f66..5fddee44 100644 --- a/wp-content/plugins/activitypub/includes/collection/class-interactions.php +++ b/wp-content/plugins/activitypub/includes/collection/class-interactions.php @@ -4,6 +4,7 @@ namespace Activitypub\Collection; use WP_Error; use WP_Comment_Query; +use function Activitypub\object_to_uri; use function Activitypub\url_to_commentid; use function Activitypub\object_id_to_comment; use function Activitypub\get_remote_metadata_by_actor; @@ -46,7 +47,8 @@ class Interactions { return false; } - $meta = get_remote_metadata_by_actor( $activity['actor'] ); + $actor = object_to_uri( $activity['actor'] ); + $meta = get_remote_metadata_by_actor( $actor ); if ( ! $meta || \is_wp_error( $meta ) ) { return false; diff --git a/wp-content/plugins/activitypub/includes/collection/class-users.php b/wp-content/plugins/activitypub/includes/collection/class-users.php index a331c203..6a9a5dc7 100644 --- a/wp-content/plugins/activitypub/includes/collection/class-users.php +++ b/wp-content/plugins/activitypub/includes/collection/class-users.php @@ -7,6 +7,7 @@ use Activitypub\Model\User; use Activitypub\Model\Blog_User; use Activitypub\Model\Application_User; +use function Activitypub\object_to_uri; use function Activitypub\url_to_authorid; use function Activitypub\is_user_disabled; @@ -136,6 +137,8 @@ class Users { * @return \Acitvitypub\Model\User The User. */ public static function get_by_resource( $resource ) { + $resource = object_to_uri( $resource ); + $scheme = 'acct'; $match = array(); // try to extract the scheme and the host diff --git a/wp-content/plugins/activitypub/includes/functions.php b/wp-content/plugins/activitypub/includes/functions.php index 7ea3ed9f..ee6ce46c 100644 --- a/wp-content/plugins/activitypub/includes/functions.php +++ b/wp-content/plugins/activitypub/includes/functions.php @@ -52,6 +52,17 @@ function get_remote_metadata_by_actor( $actor, $cached = true ) { if ( $pre ) { return $pre; } + + if ( is_array( $actor ) ) { + if ( array_key_exists( 'id', $actor ) ) { + $actor = $actor['id']; + } elseif ( array_key_exists( 'url', $actor ) ) { + $actor = $actor['url']; + } else { + return new WP_Error( 'activitypub_no_valid_actor_identifier', \__( 'The "actor" identifier is not valid', 'activitypub' ), array( 'status' => 404, 'actor' => $actor ) ); + } + } + if ( preg_match( '/^@?' . ACTIVITYPUB_USERNAME_REGEXP . '$/i', $actor ) ) { $actor = Webfinger::resolve( $actor ); } @@ -134,7 +145,7 @@ function url_to_authorid( $url ) { global $wp_rewrite; // check if url hase the same host - if ( \wp_parse_url( \site_url(), \PHP_URL_HOST ) !== \wp_parse_url( $url, \PHP_URL_HOST ) ) { + if ( \wp_parse_url( \home_url(), \PHP_URL_HOST ) !== \wp_parse_url( $url, \PHP_URL_HOST ) ) { return 0; } diff --git a/wp-content/plugins/activitypub/includes/handler/class-undo.php b/wp-content/plugins/activitypub/includes/handler/class-undo.php index 74d3dcae..5e222daa 100644 --- a/wp-content/plugins/activitypub/includes/handler/class-undo.php +++ b/wp-content/plugins/activitypub/includes/handler/class-undo.php @@ -4,6 +4,8 @@ namespace Activitypub\Handler; use Activitypub\Collection\Users; use Activitypub\Collection\Followers; +use function Activitypub\object_to_uri; + /** * Handle Undo requests */ @@ -28,10 +30,10 @@ class Undo { if ( isset( $activity['object']['type'] ) && 'Follow' === $activity['object']['type'] && - isset( $activity['object']['object'] ) && - filter_var( $activity['object']['object'], FILTER_VALIDATE_URL ) + isset( $activity['object']['object'] ) ) { - $user = Users::get_by_resource( $activity['object']['object'] ); + $user_id = object_to_uri( $activity['object']['object'] ); + $user = Users::get_by_resource( $user_id ); if ( ! $user || is_wp_error( $user ) ) { // If we can not find a user, @@ -40,8 +42,9 @@ class Undo { } $user_id = $user->get__id(); + $actor = object_to_uri( $activity['actor'] ); - Followers::remove_follower( $user_id, $activity['actor'] ); + Followers::remove_follower( $user_id, $actor ); } } } diff --git a/wp-content/plugins/activitypub/includes/transformer/class-post.php b/wp-content/plugins/activitypub/includes/transformer/class-post.php index 1023dfdf..3c4905ec 100644 --- a/wp-content/plugins/activitypub/includes/transformer/class-post.php +++ b/wp-content/plugins/activitypub/includes/transformer/class-post.php @@ -343,10 +343,10 @@ class Post extends Base { case 'core/cover': if ( ! empty( $block['attrs']['id'] ) ) { $alt = ''; - $check = preg_match( '//i', $block['innerHTML'], $match ); + $check = preg_match( '//i', $block['innerHTML'], $match ); if ( $check ) { - $alt = $match[1]; + $alt = $match[2]; } $media['image'][] = array( @@ -432,8 +432,8 @@ class Post extends Base { /** * Filter the image URL returned for each post. * - * @param array|false $thumbnail The image URL, or false if no image is available. - * @param int $id The attachment ID. + * @param array|false $thumbnail The image URL, or false if no image is available. + * @param int $id The attachment ID. * @param string $image_size The image size to retrieve. Set to 'full' by default. */ $thumbnail = apply_filters( @@ -451,11 +451,11 @@ class Post extends Base { ); if ( ! empty( $media['alt'] ) ) { - $image['name'] = \esc_attr( $media['alt'] ); + $image['name'] = \wp_strip_all_tags( \html_entity_decode( $media['alt'] ) ); } else { $alt = \get_post_meta( $id, '_wp_attachment_image_alt', true ); if ( $alt ) { - $image['name'] = \esc_attr( $alt ); + $image['name'] = \wp_strip_all_tags( \html_entity_decode( $alt ) ); } } diff --git a/wp-content/plugins/activitypub/integration/class-enable-mastodon-apps.php b/wp-content/plugins/activitypub/integration/class-enable-mastodon-apps.php index 27e1412e..8fe2c3f5 100644 --- a/wp-content/plugins/activitypub/integration/class-enable-mastodon-apps.php +++ b/wp-content/plugins/activitypub/integration/class-enable-mastodon-apps.php @@ -3,10 +3,14 @@ namespace Activitypub\Integration; use DateTime; use Activitypub\Webfinger as Webfinger_Util; +use Activitypub\Http; use Activitypub\Collection\Users; use Activitypub\Collection\Followers; use Activitypub\Integration\Nodeinfo; +use Enable_Mastodon_Apps\Mastodon_API; use Enable_Mastodon_Apps\Entity\Account; +use Enable_Mastodon_Apps\Entity\Status; +use Enable_Mastodon_Apps\Entity\Media_Attachment; use function Activitypub\get_remote_metadata_by_actor; @@ -23,9 +27,11 @@ class Enable_Mastodon_Apps { */ public static function init() { \add_filter( 'mastodon_api_account_followers', array( self::class, 'api_account_followers' ), 10, 2 ); - \add_filter( 'mastodon_api_account', array( self::class, 'api_account' ), 20, 2 ); + \add_filter( 'mastodon_api_account', array( self::class, 'api_account_add_followers' ), 20, 2 ); \add_filter( 'mastodon_api_account', array( self::class, 'api_account_external' ), 10, 2 ); \add_filter( 'mastodon_api_search', array( self::class, 'api_search' ), 40, 2 ); + \add_filter( 'mastodon_api_get_posts_query_args', array( self::class, 'api_get_posts_query_args' ) ); + \add_filter( 'mastodon_api_statuses', array( self::class, 'api_statuses_external' ), 10, 2 ); } /** @@ -95,8 +101,8 @@ class Enable_Mastodon_Apps { * * @return Enable_Mastodon_Apps\Entity\Account The filtered Account */ - public static function api_account( $account, $user_id ) { - if ( ! $account instanceof Account ) { + public static function api_account_add_followers( $account, $user_id ) { + if ( ! $account instanceof Account || ! is_numeric( $user_id ) ) { return $account; } @@ -121,8 +127,9 @@ class Enable_Mastodon_Apps { } } - $account->acct = $user->get_webfinger(); + $account->acct = $user->get_preferred_username(); $account->note = $user->get_summary(); + $account->followers_count = Followers::count_followers( $user_id ); return $account; } @@ -136,34 +143,47 @@ class Enable_Mastodon_Apps { * @return Enable_Mastodon_Apps\Entity\Account The filtered Account */ public static function api_account_external( $user_data, $user_id ) { - if ( ! preg_match( '/^' . ACTIVITYPUB_USERNAME_REGEXP . '$/', $user_id ) ) { + if ( $user_data || is_numeric( $user_id ) ) { + // Only augment. return $user_data; } $uri = Webfinger_Util::resolve( $user_id ); - if ( ! $uri ) { + if ( ! $uri || is_wp_error( $uri ) ) { return $user_data; } - $acct = Webfinger_Util::uri_to_acct( $uri ); + $account = self::get_account_for_actor( $uri ); + if ( $account ) { + return $account; + } + + return $user_data; + } + + private static function get_account_for_actor( $uri ) { + if ( ! is_string( $uri ) ) { + return null; + } $data = get_remote_metadata_by_actor( $uri ); if ( ! $data || is_wp_error( $data ) ) { - return $user_data; + return null; + } + $account = new Account(); + + $acct = Webfinger_Util::uri_to_acct( $uri ); + if ( str_starts_with( $acct, 'acct:' ) ) { + $acct = substr( $acct, 5 ); } - if ( $user_data instanceof Account ) { - $account = $user_data; - } else { - $account = new Account(); - } - - $account->id = strval( $user_id ); + $account->id = $acct; $account->username = $acct; $account->acct = $acct; $account->display_name = $data['name']; $account->url = $uri; + if ( ! empty( $data['summary'] ) ) { $account->note = $data['summary']; } @@ -178,8 +198,8 @@ class Enable_Mastodon_Apps { } if ( isset( $data['image'] ) ) { - $account->header = $data['image']; - $account->header_static = $data['image']; + $account->header = $data['image']['url']; + $account->header_static = $data['image']['url']; } $account->created_at = new DateTime( $data['published'] ); @@ -233,4 +253,114 @@ class Enable_Mastodon_Apps { return $search_data; } + + public function api_get_posts_query_args( $args ) { + if ( isset( $args['author'] ) && is_string( $args['author'] ) ) { + $uri = Webfinger_Util::resolve( $args['author'] ); + if ( $uri && ! is_wp_error( $uri ) ) { + $args['activitypub'] = $uri; + unset( $args['author'] ); + } + } + + return $args; + } + + public static function api_statuses_external( $statuses, $args ) { + if ( ! isset( $args['activitypub'] ) ) { + return $statuses; + } + + $data = get_remote_metadata_by_actor( $args['activitypub'] ); + + if ( ! $data || is_wp_error( $data ) || ! isset( $data['outbox'] ) ) { + return $statuses; + } + + $response = Http::get( $data['outbox'], true ); + if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) { + return $statuses; + } + + $outbox = json_decode( wp_remote_retrieve_body( $response ), true ); + if ( ! $outbox || is_wp_error( $outbox ) || ! isset( $outbox['first'] ) ) { + return $statuses; + } + + $account = self::get_account_for_actor( $args['activitypub'] ); + if ( ! $account ) { + return $statuses; + } + + $response = Http::get( $outbox['first'], true ); + if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) { + return $statuses; + } + $posts = json_decode( wp_remote_retrieve_body( $response ), true ); + + $activitypub_statuses = array_map( + function ( $item ) use ( $account ) { + $object = $item['object']; + if ( ! isset( $object['type'] ) || 'Note' !== $object['type'] ) { + return null; + } + + $status = new Status(); + $status->id = Mastodon_API::remap_url( $object['id'] ); + $status->created_at = new DateTime( $object['published'] ); + $status->content = $object['content']; + $status->account = $account; + + if ( ! empty( $object['inReplyTo'] ) ) { + $status->in_reply_to_id = $object['inReplyTo']; + } + + if ( ! empty( $object['visibility'] ) ) { + $status->visibility = $object['visibility']; + } + + $status->uri = $object['url']; + + if ( ! empty( $object['attachment'] ) ) { + $status->media_attachments = array_map( + function ( $attachment ) { + $default_attachment = array( + 'url' => null, + 'mediaType' => null, + 'name' => null, + 'width' => 0, + 'height' => 0, + 'blurhash' => null, + ); + + $attachment = array_merge( $default_attachment, $attachment ); + + $media_attachment = new Media_Attachment(); + $media_attachment->id = Mastodon_API::remap_url( $attachment['url'], $attachment ); + $media_attachment->type = strtok( $attachment['mediaType'], '/' ); + $media_attachment->url = $attachment['url']; + $media_attachment->preview_url = $attachment['url']; + $media_attachment->description = $attachment['name']; + $media_attachment->blurhash = $attachment['blurhash']; + $media_attachment->meta = array( + 'original' => array( + 'width' => $attachment['width'], + 'height' => $attachment['height'], + 'size' => $attachment['width'] . 'x' . $attachment['height'], + 'aspect' => $attachment['width'] / $attachment['height'], + ), + ); + return $media_attachment; + }, + $object['attachment'] + ); + } + + return $status; + }, + $posts['orderedItems'] + ); + + return $activitypub_statuses; + } } diff --git a/wp-content/plugins/activitypub/readme.txt b/wp-content/plugins/activitypub/readme.txt index e9344b1a..18774da3 100644 --- a/wp-content/plugins/activitypub/readme.txt +++ b/wp-content/plugins/activitypub/readme.txt @@ -3,7 +3,7 @@ Contributors: automattic, pfefferle, mediaformat, mattwiebe, akirk, jeherve, nur Tags: OStatus, fediverse, activitypub, activitystream Requires at least: 5.5 Tested up to: 6.5 -Stable tag: 2.3.0 +Stable tag: 2.3.1 Requires PHP: 5.6 License: MIT License URI: http://opensource.org/licenses/MIT @@ -133,6 +133,17 @@ For reasons of data protection, it is not possible to see the followers of other == Changelog == += 2.3.1 = + +* Added: Enable Mastodon Apps: Add remote outbox fetching +* Added: Help texts +* Fixed: Compatibility issues with Discourse +* Fixed: Do not announce replies +* Fixed: Also delete interactions with deleted person +* Fixed: Check Author-URL only if user is enabled for ActivityPub +* Fixed: Generate comment IDs for federation from home_url +* Removed: Beta label from the #Hashtag settings + = 2.3.0 = * Added: Mark links as "unhandled-link" and "status-link", for a better UX in the Mastodon App @@ -152,13 +163,6 @@ For reasons of data protection, it is not possible to see the followers of other * Changed: Remote Reply: limit enqueue to when needed * Changed: Abstract shared Dialog code - -= 2.2.0 = - -* Added: Remote-Reply lightbox -* Added: Support `application/ld+json` mime-type with AP profile in WebFinger -* Fixed: Prevent scheduler overload - See full Changelog on [GitHub](https://github.com/Automattic/wordpress-activitypub/blob/master/CHANGELOG.md). == Upgrade Notice == diff --git a/wp-content/plugins/activitypub/templates/settings.php b/wp-content/plugins/activitypub/templates/settings.php index 2da88a7e..071aa1bd 100644 --- a/wp-content/plugins/activitypub/templates/settings.php +++ b/wp-content/plugins/activitypub/templates/settings.php @@ -30,7 +30,10 @@

- publish_posts capability) gets their own ActivityPub profile.', 'activitypub' ), array( 'code' => array() ) ); ?> + activitypub capability) gets their own ActivityPub profile.', 'activitypub' ), array( 'code' => array() ) ); ?> + + user settings.', 'activitypub' ), admin_url( '/users.php' ) ), array( 'a' => array( 'href' => array() ) ) ); ?> + array() ) ); ?>

- +

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 4c16d5aa..df0146e1 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 @@ -275,7 +275,7 @@ class Simple_Local_Avatars { } // Local only mode - if ( ! $simple_local_avatar_url && ! empty( $this->options['only'] ) ) { + if ( ! $simple_local_avatar_url ) { $args['url'] = $this->get_default_avatar_url( $args['size'] ); } @@ -342,10 +342,13 @@ class Simple_Local_Avatars { } // check rating - $avatar_rating = get_user_meta( $user_id, $this->rating_key, true ); - $site_rating = get_option( 'avatar_rating' ); + $avatar_rating = get_user_meta( $user_id, $this->rating_key, true ); + $site_rating = get_option( 'avatar_rating' ); + $all_avatar_ratings = ! empty( $this->avatar_ratings ) && is_array( $this->avatar_ratings ) + ? $this->avatar_ratings + : array(); if ( ! empty( $avatar_rating ) && 'G' !== $avatar_rating && $site_rating ) { - $ratings = array_keys( $this->avatar_ratings ); + $ratings = array_keys( $all_avatar_ratings ); $site_rating_weight = array_search( $site_rating, $ratings, true ); $avatar_rating_weight = array_search( $avatar_rating, $ratings, true ); if ( false !== $avatar_rating_weight && $avatar_rating_weight > $site_rating_weight ) { @@ -910,7 +913,7 @@ class Simple_Local_Avatars {
ID ) ); + echo get_simple_local_avatar( $profileuser->ID ); remove_filter( 'pre_option_avatar_rating', '__return_empty_string' ); ?> @@ -1042,7 +1045,7 @@ class Simple_Local_Avatars { // check for uploaded files if ( ! empty( $_FILES['simple-local-avatar']['name'] ) && 0 === $_FILES['simple-local-avatar']['error'] ) : - // need to be more secure since low privelege users can upload + // need to be more secure since low privilege users can upload $allowed_mime_types = wp_get_mime_types(); $file_mime_type = strtolower( $_FILES['simple-local-avatar']['type'] ); @@ -1132,17 +1135,8 @@ class Simple_Local_Avatars { $this->avatar_delete( $user_id ); // delete old images if successful - /** - * Enable themes and other plugins to react to avatar deletions. - * - * @since 2.6.0 - * - * @param int $user_id Id of the user who's avatar was deleted. - */ - do_action( 'simple_local_avatar_deleted', $user_id ); - if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { - echo wp_kses_post( get_simple_local_avatar( $user_id ) ); + echo get_simple_local_avatar( $user_id ); } } @@ -1168,7 +1162,7 @@ class Simple_Local_Avatars { $this->assign_new_user_avatar( $media_id, $user_id ); } - echo wp_kses_post( get_simple_local_avatar( $user_id ) ); + echo get_simple_local_avatar( $user_id ); die; } @@ -1204,6 +1198,15 @@ class Simple_Local_Avatars { delete_user_meta( $user_id, $this->user_key ); delete_user_meta( $user_id, $this->rating_key ); + + /** + * Enable themes and other plugins to react to avatar deletions. + * + * @since 2.6.0 + * + * @param int $user_id Id of the user who's avatar was deleted. + */ + do_action( 'simple_local_avatar_deleted', $user_id ); } /** diff --git a/wp-content/plugins/simple-local-avatars/readme.txt b/wp-content/plugins/simple-local-avatars/readme.txt index 5e516ba5..24c65c7d 100644 --- a/wp-content/plugins/simple-local-avatars/readme.txt +++ b/wp-content/plugins/simple-local-avatars/readme.txt @@ -2,10 +2,8 @@ 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.4 -Requires PHP: 7.4 -Stable tag: 2.7.7 +Tested up to: 6.5 +Stable tag: 2.7.8 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -33,7 +31,7 @@ Just edit a user profile, and scroll down to the new "Avatar" field. The plug-in Use avatars in your theme using WordPress' built in `get_avatar()` function: [http://codex.wordpress.org/Function_Reference/get_avatar](http://codex.wordpress.org/Function_Reference/get_avatar "get_avatar function") -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. +You can also use `get_simple_local_avatar()` (with the same arguments) to retrieve local avatars a bit faster, but this will make your theme dependent on this plug-in. == Frequently Asked Questions == @@ -47,6 +45,22 @@ No. Simple Local Avatars neither collects, stores, nor sends any PII data of vi == Changelog == += 2.7.8 - 2024-05-06 = +**Note that this release bumps the minimum required version of WordPress from 5.7 to 6.3.** + +* **Added:** "Testing" section in the `CONTRIBUTING.md` file (props [@kmgalanakis](https://github.com/kmgalanakis), [@jeffpaul](https://github.com/jeffpaul) via [#274](https://github.com/10up/simple-local-avatars/pull/274)). +* **Changed:** Bumped WordPress "tested up to" version 6.5 (props [@sudip-md](https://github.com/sudip-md), [@dkotter](https://github.com/dkotter), [@jeffpaul](https://github.com/jeffpaul) via [#270](https://github.com/10up/simple-local-avatars/pull/270)). +* **Changed:** Move `simple_local_avatar_deleted` action to `avatar_delete` (props [@lllopo](https://github.com/lllopo), [@faisal-alvi](https://github.com/faisal-alvi), [@dkotter](https://github.com/dkotter) via [#255](https://github.com/10up/simple-local-avatars/pull/255)). +* **Changed:** Clean up NPM dependencies and update node to `v20` (props [@Sidsector9](https://github.com/Sidsector9), [@dkotter](https://github.com/dkotter) via [#257](https://github.com/10up/simple-local-avatars/pull/257)). +* **Changed:** Update `CODEOWNERS` of the plugin (props [@jeffpaul](https://github.com/jeffpaul), [@dkotter](https://github.com/dkotter) via [#253](https://github.com/10up/simple-local-avatars/pull/253)). +* **Changed:** Disabled auto sync pull requests with target branch (props [@iamdharmesh](https://github.com/iamdharmesh), [@jeffpaul](https://github.com/jeffpaul) via [#263](https://github.com/10up/simple-local-avatars/pull/263)). +* **Changed:** Upgrade `download-artifact` from v3 to v4 (props [@iamdharmesh](https://github.com/iamdharmesh), [@jeffpaul](https://github.com/jeffpaul) via [#265](https://github.com/10up/simple-local-avatars/pull/265)). +* **Changed:** Replaced `lee-dohm/no-response` with `actions/stale` to help with closing `no-response/stale` issues (props [@jeffpaul](https://github.com/jeffpaul), [@dkotter](https://github.com/dkotter) via [#266](https://github.com/10up/simple-local-avatars/pull/266)). +* **Fixed:** Broken default avatar when `Local Avatars Only` is unchecked (props [@faisal-alvi](https://github.com/faisal-alvi), [@ankitguptaindia](https://github.com/ankitguptaindia), [@qasumitbagthariya](https://github.com/qasumitbagthariya) via [#260](https://github.com/10up/simple-local-avatars/pull/260)). +* **Fixed:** Ensure high-quality avatar preview on profile edit screen (props [@ocean90](https://github.com/ocean90), [@dkotter](https://github.com/dkotter) via [#273](https://github.com/10up/simple-local-avatars/pull/273)). +* **Fixed:** Possible PHP warning (props [@BhargavBhandari90](https://github.com/BhargavBhandari90), [@dkotter](https://github.com/dkotter) via [#261](https://github.com/10up/simple-local-avatars/pull/261)). +* **Fixed:** Fixed typos (props [@szepeviktor](https://github.com/szepeviktor), [@dkotter](https://github.com/dkotter) via [#268](https://github.com/10up/simple-local-avatars/pull/268)). + = 2.7.7 - 2023-12-13 = * **Fixed:** Revert the Host/Domain support for local avatar URL (props [@faisal-alvi](https://github.com/faisal-alvi), [@jakejackson1](https://github.com/jakejackson1), [@leogermani](https://github.com/leogermani), [@dkotter](https://github.com/dkotter) via [#247](https://github.com/10up/simple-local-avatars/pull/247)). * **Security:** Bump `axios` from 0.25.0 to 1.6.2 and `@wordpress/scripts` from 23.7.2 to 26.18.0 (props [@dependabot](https://github.com/apps/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#250](https://github.com/10up/simple-local-avatars/pull/250)). @@ -245,6 +259,9 @@ No. Simple Local Avatars neither collects, stores, nor sends any PII data of vi == Upgrade Notice == += 2.7.8 = +**Note that this release bumps the minimum required version of WordPress from 5.7 to 6.3.** + = 2.6.0 = **Note that this release bumps the minimum required version of WordPress from 4.6 to 5.7 and PHP from 5.6 to 7.4.** 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 42249806..5a3da1e2 100644 --- a/wp-content/plugins/simple-local-avatars/simple-local-avatars.php +++ b/wp-content/plugins/simple-local-avatars/simple-local-avatars.php @@ -3,8 +3,8 @@ * 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.7 - * Requires at least: 5.7 + * Version: 2.7.8 + * Requires at least: 6.3 * Requires PHP: 7.4 * Author: 10up * Author URI: https://10up.com @@ -67,7 +67,7 @@ define( 'SLA_PLUGIN_BASENAME', plugin_basename( __FILE__ ) ); require_once dirname( __FILE__ ) . '/includes/class-simple-local-avatars.php'; // Global constants. -define( 'SLA_VERSION', '2.7.7' ); +define( 'SLA_VERSION', '2.7.8' ); define( 'SLA_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); if ( ! defined( 'SLA_IS_NETWORK' ) ) {