ID ); self::maybe_delete_posts( $follower->ID ); $state = Remote_Actors::delete( $follower->ID ); } return $state ?? false; } /** * Schedule Deletion of Interactions of a Remote Actor. * * @param int $id The remote actor ID. */ public static function maybe_delete_interactions( $id ) { \wp_schedule_single_event( \time(), 'activitypub_delete_remote_actor_interactions', array( $id ) ); } /** * Schedule Deletion of Reader Items of a Remote Actor. * * @param int $id The remote actor ID. */ public static function maybe_delete_posts( $id ) { \wp_schedule_single_event( \time(), 'activitypub_delete_remote_actor_posts', array( $id ) ); } /** * Delete Interactions from a Remote Actor. * * @param int $id The ID of the actor whose comments to delete. * * @return bool True on success, false otherwise. */ public static function delete_interactions( $id ) { $comments = Interactions::get_by_remote_actor_id( $id ); foreach ( $comments as $comment ) { \wp_delete_comment( $comment, true ); } if ( $comments ) { return true; } else { return false; } } /** * Delete Reader Items from an Actor. * * @param int $id The ID of the actor whose comments to delete. * * @return bool True on success, false otherwise. */ public static function delete_posts( $id ) { $posts = Remote_Posts::get_by_remote_actor_id( $id ); foreach ( $posts as $post ) { Remote_Posts::delete( $post->ID ); } if ( $posts ) { return true; } else { return false; } } /** * Delete a Reaction if URL is a Tombstone. * * Note: When comments are deleted, WordPress automatically deletes all associated * comment meta including _activitypub_remote_actor_id. The remote actor post itself * is not deleted, as it may be referenced by other comments or may be needed for * future interactions. * * @param array $activity The delete activity. * * @return bool True on success, false otherwise. */ public static function maybe_delete_interaction( $activity ) { $id = object_to_uri( $activity['object'] ); $comments = Interactions::get_by_id( $id ); if ( $comments && Tombstone::exists( $id ) ) { foreach ( $comments as $comment ) { // WordPress will automatically delete all comment meta including _activitypub_remote_actor_id. wp_delete_comment( $comment->comment_ID, true ); } return true; } return false; } /** * Delete a post from the Posts collection. * * @param array $activity The delete activity. * * @return bool|\WP_Error True on success, false or WP_Error on failure. */ public static function maybe_delete_post( $activity ) { $id = object_to_uri( $activity['object'] ); // Check if the object exists and is a tombstone. if ( Tombstone::exists( $id ) ) { return Remote_Posts::delete_by_guid( $id ); } return false; } /** * Skip inbox storage for `Delete` requests. * * @param bool $skip Whether to skip inbox storage. * @param array $data The activity data array. * * @return bool Whether to skip inbox storage. */ public static function skip_inbox_storage( $skip, $data ) { if ( isset( $data['type'] ) && 'Delete' === $data['type'] ) { return true; } return $skip; } /** * Defer signature verification for `Delete` requests. * * Endpoints that opt in to mandatory signing by calling * `verify_signature( $request, true )` must not be overridden — the * Delete carve-out is only for the default inbox path where the * remote actor's keys may legitimately be gone before the Delete * arrives. * * @since 8.2.0 The `$force_signature` parameter is now respected. * * @param bool $defer Whether to defer signature verification. * @param \WP_REST_Request $request The request object. * @param bool $force_signature Whether the caller has forced signature verification. * * @return bool Whether to defer signature verification. */ public static function defer_signature_verification( $defer, $request, $force_signature = false ) { if ( $force_signature ) { return $defer; } $json = $request->get_json_params(); if ( isset( $json['type'] ) && 'Delete' === $json['type'] ) { return true; } return $defer; } /** * Set the object to the object ID. * * @param \Activitypub\Activity\Activity $activity The Activity object. * * @return \Activitypub\Activity\Activity The filtered Activity object. */ public static function outbox_activity( $activity ) { if ( 'Delete' === $activity->get_type() ) { $activity->set_object( object_to_uri( $activity->get_object() ) ); } return $activity; } /** * Add a URL to the tombstone registry when a Delete activity is sent. * * @param int $outbox_id The ID of the outbox activity. * @param \Activitypub\Activity\Activity $activity The Activity object. */ public static function maybe_bury( $outbox_id, $activity ) { if ( 'Delete' !== $activity->get_type() ) { return; } $object = $activity->get_object(); if ( ! $object ) { return; } Tombstone::bury( object_to_uri( $object ) ); if ( \is_object( $object ) ) { Tombstone::bury( $object->get_id(), $object->get_url() ); } } }