Fix a fatal error when the ActivityPub plugin is not active - #714
Merged
Conversation
akirk
force-pushed
the
fix/activitypub-class-without-plugin
branch
from
September 4, 2026 11:50
9be1c0c to
2583389
Compare
Feed_Parser_ActivityPub is only required from the friends_load_parsers callback, which returns early when the ActivityPub plugin is missing. The templates rendering an author's display name called its custom emoji helpers regardless, so without that plugin /friends/ died mid-render, inside the first post's header, and the profile pages with it. Render the name through a new friends_author_display_name_html filter instead, defaulting to the escaped display name. The parser hooks it from its constructor, next to friends_post_author_meta, so the emoji are added exactly while the parser is registered and the default stands otherwise. No class_exists at the call sites. Two more places reached the parser unguarded and get the gating the rest of their file already uses: the actor handle on the profile header, and determine_mastodon_api_user() in User::mastodon_api_account_id(), which runs whenever Enable Mastodon Apps is active - with or without ActivityPub. Its two sibling call sites were already guarded. The relationship check below it used Feed_Parser_ActivityPub::SLUG on a path that is reached without the plugin; it compares against the literal now, the way the templates already do. Claude-Session: https://claude.ai/code/session_01J7aozaEFaZ3vLaLXith1qm
akirk
force-pushed
the
fix/activitypub-class-without-plugin
branch
from
September 4, 2026 12:05
1282f17 to
8628b89
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Without the ActivityPub plugin,
/friends/dies mid-render: the page stops inside the first post's header and nothing after it is sent. Profile pages go the same way.Feed_Parser_ActivityPubis required only from thefriends_load_parserscallback infriends.php, which returns early when\Activitypub\Activitypubdoesn't exist — and there is no autoloader. But the templates that render an author's display name call its custom emoji helpers regardless, for every post:templates/frontend/parts/header.php,parts/header-status.php— every post in the feedtemplates/frontend/author-header.php— every profile pageincludes/class-frontend.php,includes/class-blocks.php— the author-name blocksFriends works standalone, so this hits anyone who hasn't installed the ActivityPub plugin, or who deactivates it.
Changes
Rather than scattering
class_exists()over five call sites, the display name goes through a filter, which is the gating this plugin already uses for exactly this — two lines below the emoji call,header.phpdoesdo_action( 'friends_post_author_meta', $friend_user ), and the ActivityPub parser is what hooks it.friends_author_display_name_htmlfilter, applied wherever an author's display name is rendered, defaulting toesc_html( $display_name ).Feed_Parser_ActivityPub::author_display_name_html()hooks it from the constructor, alongsidefriends_post_author_meta. The parser is only constructed while the ActivityPub plugin is active, so the emoji rendering is added exactly then and the escaped default stands otherwise.Two other places reached the parser unguarded, and get the gating the rest of their own file already uses:
templates/frontend/author-header.php—get_actor_acct_from_attributed_to(). A feed can still be markedactivitypubin the database with the plugin gone. Returns''in that case, which is what the helper itself does anyway.includes/class-user.php—determine_mastodon_api_user()inmastodon_api_account_id(), which is hooked from the Enable Mastodon Apps integration, so it runs whenever EMA is active, with or without ActivityPub. Its two sibling call sites at:1178and:1290were already guarded; this one was missed.includes/class-user.php—mastodon_entity_relationship()readsFeed_Parser_ActivityPub::SLUGafter its ownclass_exists()if/else, on a path reached when the class is absent. It compares against the'activitypub'literal now, the wayauthor-header.phpalready does.Everything else that touches the parser is already behind a
class_exists/function_existscheck: the follower counts in the stats block and widget, direct message delivery status, webfinger resolution,get_activitypub_actor_id(), and the::SLUGuses across the migrations.Two references remain formally unguarded and are deliberately left alone, since neither is reachable without the plugin:
templates/frontend/parts/activitypub/follow-link.php:9is only ever rendered fromFeed_Parser_ActivityPub::friends_post_author_meta().includes/class-migration.php:2815sits downstream ofprocess_potential_reply_post(), which calls\Activitypub\Http::get_remote_object()on its first line.Testing instructions
Two Playground instances on the same fixture (a subscription with three status posts), one without the ActivityPub plugin and one with it installed and active. A probe mu-plugin reports what is loaded and hooked on a
/friends/request:friends_author_display_name_htmlhookedPages, before and after, without the ActivityPub plugin:
/friends//friends/newssite/After the change
/friends/,/friends/newssite/,/friends/messages/,/friends/followers/and the Friends and Settings admin pages all return 200 and close their HTML in both configurations, with no JS errors, and the feed shows 3 articles, 2 link preview cards and the correct author names either way.php -landphpcs --standard=phpcs.xmlclean on all 7 touched files. PHPUnit was not run locally (no WordPress test library on this machine) — leaving that to CI. No test touches the changed code paths directly; the emoji helpers themselves are unchanged and their existing tests still call them as before.Changelog entry
Changelog Entry Details
Type
Message
Fix a fatal error that stopped the friends page from rendering when the ActivityPub plugin is not active.
https://claude.ai/code/session_01J7aozaEFaZ3vLaLXith1qm