Skip to content

Conversation

@pfefferle
Copy link
Member

@pfefferle pfefferle commented Nov 5, 2025

This commit removes the 'actor mode' option and all related code, migrating to a system where blog actors are always enabled and user actors are controlled solely via the 'activitypub' capability. Migration logic ensures sites previously in blog-only mode do not grant the capability to new users by default. All UI, constants, and logic related to actor mode selection have been removed or refactored, and related settings fields and filters are cleaned up for clarity and maintainability.

Fixes #2418

Proposed changes:

  • Deprecated actor mode constants and settings, replacing them with capability-based control
  • Updated tests to reflect that both user and blog actors are always available
  • Added migration to preserve blog-only mode behavior via a new flag
  • Removed UI for actor mode selection

Other information:

  • Have you written new tests for your changes, if applicable?

Testing instructions:

  • Go to '..'

Changelog entry

  • Automatically create a changelog entry from the details below.
Changelog Entry Details

Significance

  • Patch
  • Minor
  • Major

Type

  • Added - for new features
  • Changed - for changes in existing functionality
  • Deprecated - for soon-to-be removed features
  • Removed - for now removed features
  • Fixed - for any bug fixes
  • Security - in case of vulnerabilities

Message

Simplified actor management by removing the actor mode setting—blog actors are now always enabled, and user actors are controlled through capabilities for clearer, more consistent behavior.

This commit removes the 'actor mode' option and all related code, migrating to a system where blog actors are always enabled and user actors are controlled solely via the 'activitypub' capability. Migration logic ensures sites previously in blog-only mode do not grant the capability to new users by default. All UI, constants, and logic related to actor mode selection have been removed or refactored, and related settings fields and filters are cleaned up for clarity and maintainability.
Replaces usage of ACTIVITYPUB_ACTOR_MODE, ACTIVITYPUB_BLOG_MODE, and ACTIVITYPUB_ACTOR_AND_BLOG_MODE constants with their string equivalents ('actor', 'blog', 'actor_blog') throughout PHPUnit tests. Updates test logic and data providers to match the new string-based configuration, and removes unnecessary option updates where blog actor is now always available.
Deleted the registration of the 'activitypub_profiles' settings section from the settings fields as it is no longer needed.
Refactor and update PHPUnit tests to reflect the removal of the 'actor mode' option. Tests now expect invalid or missing user actors to always fall back to the blog actor, and assertions have been updated accordingly. Deprecated or removed code paths related to actor mode have been eliminated from test data providers and test logic.
Deprecated and simplified the Followers::maybe_add_inboxes_of_blog_user method to always return false, reflecting the removal of actor mode. Updated scheduler, outbox, dispatcher, query, and transformer tests to align with the new behavior, ensuring both blog and user actors are always available and adjusting assertions and helper methods accordingly.
Updated comments, documentation, and test descriptions to remove or rephrase statements about the blog actor always being enabled. This clarifies that blog actors are available, but avoids implying a special always-on status, aligning with recent changes to actor mode and capability handling.
Updated comments in actor-related classes and functions to remove references to 'always enabled' for blog and user options. This clarifies the current behavior and aligns documentation with recent changes to actor capability handling.
Replaced hardcoded actor mode strings with defined constants for better maintainability and backward compatibility. Added actor mode constants in constants.php, updated migration logic to use these constants, and made minor code cleanups in functions.php and class-post.php.
Deleted the deprecated Followers::maybe_add_inboxes_of_blog_user method and its related PHPUnit tests, as actor mode has been removed. Also updated comments and minor code style in transformer test and added a phpcs ignore in outbox test.
Clarified the deprecation comment for actor mode constants in constants.php. Updated the Webfinger integration test to dynamically check the blog actor subject using the site's host instead of a hardcoded 'localhost' value.
@pfefferle pfefferle requested review from Copilot and obenland November 5, 2025 17:45
@pfefferle pfefferle self-assigned this Nov 5, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR removes the actor mode configuration system in favor of a capability-based approach for managing user and blog actors. Previously, sites could configure their actor mode (actor-only, blog-only, or both), but now both user and blog actors are always available, with user actors controlled via the 'activitypub' capability.

Key changes:

  • Deprecated actor mode constants and settings, replacing them with capability-based control
  • Updated tests to reflect that both user and blog actors are always available
  • Added migration to preserve blog-only mode behavior via a new flag
  • Removed UI for actor mode selection

Reviewed Changes

Copilot reviewed 42 out of 42 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
includes/constants.php Moved and deprecated actor mode constants with @deprecated tags
includes/functions.php Simplified is_user_type_disabled() to always return false; updated get_user_id() to always fall back to blog actor
includes/class-migration.php Added migration function to handle actor mode to capabilities transition
includes/class-activitypub.php Updated user registration to respect activitypub_disable_users_by_default flag
includes/transformer/class-post.php Updated to always return blog as audience and both actors for self interaction policy
includes/scheduler/class-actor.php Removed actor mode checks, always initialize blog and user actor hooks
includes/scheduler/class-post.php Updated parameter type hint to allow null for $post_before
includes/wp-admin/* Removed actor mode UI elements and checks
includes/collection/class-actors.php Removed actor mode checks from actor collection methods
includes/collection/class-followers.php Removed deprecated maybe_add_inboxes_of_blog_user method
includes/collection/class-replies.php Simplified to always fall back to blog actor
includes/class-scheduler.php Removed actor mode check from announce activity scheduling
includes/class-options.php Removed actor mode option filter
tests/phpunit/includes/class-activitypub-outbox-testcase.php Added activity_type parameter to get_latest_outbox_item() method
tests/phpunit/tests/integration/class-test-webfinger.php Updated test to expect blog actor fallback for invalid users
tests/phpunit/tests/includes/transformer/* Updated tests to remove actor mode checks and expect both actors
tests/phpunit/tests/includes/scheduler/* Updated tests to use activity_type filtering and removed actor mode setup
tests/phpunit/tests/includes/rest/* Updated tests to use string literals instead of constants for actor mode
tests/phpunit/tests/includes/collection/* Updated tests to always expect blog actor availability
tests/phpunit/tests/includes/model/class-test-blog.php Updated to use string literal for actor mode
tests/phpunit/tests/includes/class-test-* Updated various test files to remove actor mode setup and adjust expectations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

* @param \WP_Post|null $post_before Post object before the update.
*/
public static function schedule_post_activity( $post_id, $post, $update, $post_before ) {
public static function schedule_post_activity( $post_id, $post, $update, $post_before = null ) {
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter type hint for $post_before has changed from \WP_Post to \WP_Post|null, but the PHPDoc block at lines 34-37 doesn't reflect this nullable type. The PHPDoc should be updated to document that $post_before can be null.

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

* Note: This filter is deprecated. Use capability management instead.
*
* @param boolean $disabled True if the user type is disabled, false otherwise.
* @param string $type The User-Type.
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filter documentation indicates deprecation, but there's no @deprecated tag. Consider adding a proper @deprecated tag with version number to follow WordPress documentation standards and make it clear to developers when this was deprecated (e.g., '@deprecated unreleased').

Suggested change
* @param string $type The User-Type.
* @param string $type The User-Type.
* @deprecated unreleased

Copilot uses AI. Check for mistakes.
Comment on lines +493 to +495
// If site was in blog-only mode, set flag to disable users by default.
if ( ACTIVITYPUB_BLOG_MODE === $actor_mode ) {
\update_option( 'activitypub_disable_users_by_default', true );
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The migration only handles ACTIVITYPUB_BLOG_MODE, but doesn't explicitly handle existing users' capabilities. Sites in ACTIVITYPUB_ACTOR_MODE or ACTIVITYPUB_ACTOR_AND_BLOG_MODE may have different user capability states that aren't being preserved. Consider documenting this migration strategy or adding logic to handle these cases.

Suggested change
// If site was in blog-only mode, set flag to disable users by default.
if ( ACTIVITYPUB_BLOG_MODE === $actor_mode ) {
\update_option( 'activitypub_disable_users_by_default', true );
/**
* Migration strategy:
* - ACTIVITYPUB_BLOG_MODE: Disable users by default.
* - ACTIVITYPUB_ACTOR_MODE: Grant 'activitypub' capability to all users who previously had ActivityPub access.
* - ACTIVITYPUB_ACTOR_AND_BLOG_MODE: Grant 'activitypub' capability to all users who previously had ActivityPub access, and keep blog actor enabled.
* For all modes, clean up legacy options.
*/
if ( defined( 'ACTIVITYPUB_BLOG_MODE' ) && ACTIVITYPUB_BLOG_MODE === $actor_mode ) {
// Blog-only mode: disable users by default.
\update_option( 'activitypub_disable_users_by_default', true );
} elseif (
( defined( 'ACTIVITYPUB_ACTOR_MODE' ) && ACTIVITYPUB_ACTOR_MODE === $actor_mode ) ||
( defined( 'ACTIVITYPUB_ACTOR_AND_BLOG_MODE' ) && ACTIVITYPUB_ACTOR_AND_BLOG_MODE === $actor_mode )
) {
// Actor mode or both: ensure users who previously had ActivityPub access retain the capability.
$users = \get_users( array( 'fields' => array( 'ID' ) ) );
foreach ( $users as $user ) {
$user_obj = \get_userdata( $user->ID );
if ( $user_obj && ! $user_obj->has_cap( 'activitypub' ) ) {
$user_obj->add_cap( 'activitypub' );
}
}
// Optionally, you may want to set 'activitypub_disable_users_by_default' to false.
\update_option( 'activitypub_disable_users_by_default', false );
} else {
// Unknown mode: document that no migration was performed.
// You may want to log this event.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI commented Nov 5, 2025

@pfefferle I've opened a new pull request, #2423, to work on those changes. Once the pull request is ready, I'll request review from you.

Eliminated the is_single_user() function and all associated checks throughout the codebase, as actor mode has been removed. Updated related logic in comment handling, user counting, blog type determination, and transformers to reflect this change.
When switching to blog-only mode, this update removes the 'activitypub' capability from all users who previously had it, ensuring that user capabilities are consistent with the new mode.
Replaces the meta_key/meta_value query with 'capability__in' => array('activitypub') when removing the activitypub capability from users. This improves query performance and aligns with WordPress best practices for capability checks.
Eliminated logic and comments related to 'single user' mode in Blog::get_type() and Opengraph::add_metadata(). This simplifies the code by removing special handling for single user blogs.
@github-actions github-actions bot added the [Focus] Compatibility Ensuring the plugin plays well with other plugins label Nov 5, 2025
pfefferle and others added 2 commits November 5, 2025 21:32
Co-authored-by: Konstantin Obenland <[email protected]>
Moved the 'type' and 'posting_restricted_to_mods' values from methods to protected properties. Removed redundant methods and conditional checks, simplifying the class structure and improving clarity.
@pfefferle pfefferle requested a review from Copilot November 5, 2025 21:38
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 47 out of 47 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

* @param int $post_id Post ID.
* @param \WP_Post $post Post object.
* @param bool $update Whether this is an existing post being updated.
* @param \WP_Post|null $post_before Post object before the update.
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter $post_before is documented as \WP_Post|null but the default value is null. This change appears to be adding a default parameter that wasn't there before. If this is addressing a specific issue where $post_before might not be passed, add a @since unreleased tag to document when this parameter became optional.

Suggested change
* @param \WP_Post|null $post_before Post object before the update.
* @param \WP_Post|null $post_before Post object before the update.
* @since unreleased Parameter $post_before is now optional.

Copilot uses AI. Check for mistakes.
Updated the docblock for the user type disabling filter to explicitly mark it as deprecated and recommend using capability management instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Simplify Actor Modes

3 participants