updated plugin ActivityPub version 8.3.0

This commit is contained in:
2026-06-03 21:28:46 +00:00
committed by Gitium
parent a4b78ec277
commit 6fe182458a
340 changed files with 43232 additions and 7568 deletions

View File

@ -0,0 +1,302 @@
<?php
/**
* Self-Destruct CLI Command.
*
* @package Activitypub
*/
namespace Activitypub\Cli;
use Activitypub\Activity\Activity;
use Activitypub\Collection\Actors;
use Activitypub\Collection\Outbox;
use Activitypub\Collection\Remote_Posts;
use function Activitypub\add_to_outbox;
/**
* Remove the blog from the Fediverse.
*
* @package Activitypub
*/
class Self_Destruct_Command extends \WP_CLI_Command {
/**
* Remove the entire blog from the Fediverse.
*
* This command permanently removes your blog from ActivityPub networks by sending
* Delete activities to all followers. This action is IRREVERSIBLE.
*
* ## OPTIONS
*
* [--status]
* : Check the status of the self-destruct process instead of running it.
* Use this to monitor progress after initiating the deletion process.
*
* [--yes]
* : Skip the confirmation prompt and proceed with deletion immediately.
* Use with extreme caution as this bypasses all safety checks.
*
* ## EXAMPLES
*
* # Start the self-destruct process (with confirmation prompt)
* $ wp activitypub self-destruct
*
* # Check the status of an ongoing self-destruct process
* $ wp activitypub self-destruct --status
*
* # Force deletion without confirmation (dangerous!)
* $ wp activitypub self-destruct --yes
*
* ## WHAT THIS DOES
*
* - Finds all users with ActivityPub capabilities
* - Creates Delete activities for each user
* - Sends these activities to all followers
* - Removes your blog from ActivityPub discovery
* - Sets a flag to track completion status
*
* ## IMPORTANT NOTES
*
* - This action cannot be undone
* - Keep the ActivityPub plugin active during the process
* - The process may take several minutes to complete
* - You will be notified when the process finishes
*
* @param array $args The positional arguments (unused).
* @param array $assoc_args The associative arguments (--status, --yes).
*/
public function __invoke( $args, $assoc_args = array() ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
// Check if --status flag is provided.
if ( isset( $assoc_args['status'] ) ) {
$this->show_self_destruct_status();
return;
}
// Check if self-destruct has already been run.
if ( \get_option( 'activitypub_self_destruct' ) ) {
\WP_CLI::error( 'Self-destruct has already been initiated. The process may still be running or has completed.' . PHP_EOL . \WP_CLI::colorize( 'To check the status, run: %Bwp activitypub self-destruct --status%n' ) );
return;
}
$this->execute_self_destruct( $assoc_args );
}
/**
* Execute the self-destruct process.
*
* This method handles the actual deletion process:
* 1. Displays warning and confirmation prompt
* 2. Retrieves all ActivityPub-capable users
* 3. Creates and schedules Delete activities for each user
* 4. Sets the self-destruct flag for status tracking
* 5. Provides progress feedback and completion instructions
*
* @param array $assoc_args The associative arguments from WP-CLI.
*/
private function execute_self_destruct( $assoc_args ) {
$this->display_self_destruct_warning();
\WP_CLI::confirm( 'Are you absolutely sure you want to continue?', $assoc_args );
$user_ids = $this->get_activitypub_users();
if ( empty( $user_ids ) ) {
\WP_CLI::warning( 'No ActivityPub users found. Nothing to delete.' );
return;
}
$processed = $this->process_user_deletions( $user_ids );
// Delete all remote posts.
$deleted_posts = Remote_Posts::delete_all();
if ( $deleted_posts > 0 ) {
\WP_CLI::line( \WP_CLI::colorize( "%G✓%n Deleted {$deleted_posts} remote post(s)." ) );
}
$this->display_completion_message( $processed );
}
/**
* Display the self-destruct warning message.
*/
private function display_self_destruct_warning() {
\WP_CLI::line( \WP_CLI::colorize( '%R⚠ DESTRUCTIVE OPERATION ⚠️%n' ) );
\WP_CLI::line( '' );
$question = 'You are about to delete your blog from the Fediverse. This action is IRREVERSIBLE and will:';
\WP_CLI::line( \WP_CLI::colorize( "%y{$question}%n" ) );
\WP_CLI::line( \WP_CLI::colorize( '%y• Send Delete activities to all followers%n' ) );
\WP_CLI::line( \WP_CLI::colorize( '%y• Remove your blog from ActivityPub networks%n' ) );
\WP_CLI::line( \WP_CLI::colorize( '%y• Delete all cached remote posts%n' ) );
\WP_CLI::line( '' );
}
/**
* Get all users with ActivityPub capabilities.
*
* @return array Array of user IDs with ActivityPub capabilities.
*/
private function get_activitypub_users() {
return \get_users(
array(
'fields' => 'ID',
'capability__in' => array( 'activitypub' ),
)
);
}
/**
* Process user deletions and create Delete activities.
*
* @param array $user_ids Array of user IDs to process.
*
* @return int Number of users successfully processed.
*/
private function process_user_deletions( $user_ids ) {
$user_count = \count( $user_ids );
\WP_CLI::line( \WP_CLI::colorize( '%GStarting Fediverse deletion process...%n' ) );
\WP_CLI::line( \WP_CLI::colorize( "%BFound {$user_count} ActivityPub user(s) to process:%n" ) );
\WP_CLI::line( '' );
// Set the self-destruct flag.
\update_option( 'activitypub_self_destruct', true );
$processed = 0;
foreach ( $user_ids as $user_id ) {
if ( $this->create_delete_activity_for_user( $user_id, $processed, $user_count ) ) {
++$processed;
}
}
\WP_CLI::line( '' );
if ( 0 === $processed ) {
\WP_CLI::error( 'Failed to schedule any deletions. Please check your configuration.' );
}
return $processed;
}
/**
* Create a Delete activity for a specific user.
*
* @param int $user_id The user ID to process.
* @param int $processed Number of users already processed.
* @param int $user_count Total number of users to process.
*
* @return bool True if the activity was created successfully, false otherwise.
*/
private function create_delete_activity_for_user( $user_id, $processed, $user_count ) {
$actor = Actors::get_by_id( $user_id );
if ( ! $actor ) {
\WP_CLI::line( \WP_CLI::colorize( "%R✗ Failed to load user ID: {$user_id}%n" ) );
return false;
}
$activity = new Activity();
$activity->set_actor( $actor->get_id() );
$activity->set_object( $actor->get_id() );
$activity->set_type( 'Delete' );
$result = add_to_outbox( $activity, null, $user_id );
if ( \is_wp_error( $result ) ) {
\WP_CLI::line( \WP_CLI::colorize( "%R✗ Failed to schedule deletion for: %B{$actor->get_name()}%n - {$result->get_error_message()}" ) );
return false;
}
$current = $processed + 1;
\WP_CLI::line( \WP_CLI::colorize( "%G✓%n [{$current}/{$user_count}] Scheduled deletion for: %B{$actor->get_name()}%n" ) );
return true;
}
/**
* Display the completion message after processing.
*
* @param int $processed Number of users successfully processed.
*/
private function display_completion_message( $processed ) {
if ( 0 === $processed ) {
return; // Error already displayed in process_user_deletions.
}
\WP_CLI::success( "Successfully scheduled {$processed} user(s) for Fediverse deletion." );
\WP_CLI::line( '' );
\WP_CLI::line( \WP_CLI::colorize( '%Y📋 Next Steps:%n' ) );
\WP_CLI::line( \WP_CLI::colorize( '%Y• Keep the ActivityPub plugin active%n' ) );
\WP_CLI::line( \WP_CLI::colorize( '%Y• Delete activities will be sent automatically%n' ) );
\WP_CLI::line( \WP_CLI::colorize( '%Y• Process may take several minutes to complete%n' ) );
\WP_CLI::line( \WP_CLI::colorize( '%Y• The plugin will notify you when the process is done.%n' ) );
\WP_CLI::line( '' );
}
/**
* Show the status of the self-destruct process.
*
* Checks the current state of the self-destruct process by:
* - Verifying if the process has been initiated
* - Counting remaining pending Delete activities
* - Displaying appropriate status messages and progress
* - Providing guidance on next steps
*
* Status can be:
* - NOT STARTED: Process hasn't been initiated
* - IN PROGRESS: Delete activities are still being processed
* - COMPLETED: All Delete activities have been sent
*/
private function show_self_destruct_status() {
// Only proceed if self-destruct is active.
if ( ! \get_option( 'activitypub_self_destruct', false ) ) {
\WP_CLI::line( \WP_CLI::colorize( '%C❌ Status: NOT STARTED%n' ) );
\WP_CLI::line( \WP_CLI::colorize( '%CThe self-destruct process has not been initiated.%n' ) );
\WP_CLI::line( '' );
\WP_CLI::line( \WP_CLI::colorize( '%CTo start the process, run:%n %Bwp activitypub self-destruct%n' ) );
\WP_CLI::line( '' );
return;
}
\WP_CLI::line( \WP_CLI::colorize( '%B🔍 Self-Destruct Status Check%n' ) );
\WP_CLI::line( '' );
// Check if there are any more pending Delete activities for self-destruct.
$pending_deletes = \get_posts(
array(
'post_type' => Outbox::POST_TYPE,
'post_status' => 'pending',
'posts_per_page' => -1,
'fields' => 'ids',
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
'meta_query' => array(
array(
'key' => '_activitypub_activity_type',
'value' => 'Delete',
),
),
)
);
// Get count of pending Delete activities.
$pending_count = count( $pending_deletes );
// If no more pending Delete activities, self-destruct is complete.
if ( 0 === $pending_count ) {
\WP_CLI::line( \WP_CLI::colorize( '%G✅ Status: COMPLETED%n' ) );
\WP_CLI::line( \WP_CLI::colorize( '%GYour blog has been successfully removed from the Fediverse.%n' ) );
\WP_CLI::line( '' );
\WP_CLI::line( \WP_CLI::colorize( '%Y📋 What happened:%n' ) );
\WP_CLI::line( \WP_CLI::colorize( '%Y• Delete activities were sent to all followers%n' ) );
\WP_CLI::line( \WP_CLI::colorize( '%Y• Your blog is no longer discoverable on ActivityPub networks%n' ) );
\WP_CLI::line( \WP_CLI::colorize( '%Y• The self-destruct process has finished%n' ) );
} else {
\WP_CLI::line( \WP_CLI::colorize( '%Y⏳ Status: IN PROGRESS%n' ) );
\WP_CLI::line( \WP_CLI::colorize( '%YThe self-destruct process is currently running.%n' ) );
\WP_CLI::line( '' );
\WP_CLI::line( \WP_CLI::colorize( "%YProgress: {$pending_count} Delete Activities still pending%n" ) );
\WP_CLI::line( '' );
\WP_CLI::line( \WP_CLI::colorize( '%YNote: The process may take several minutes to complete.%n' ) );
}
\WP_CLI::line( '' );
}
}