diff --git a/includes/class-activity-dispatcher.php b/includes/class-activity-dispatcher.php index 9540578af..670a3a2f2 100644 --- a/includes/class-activity-dispatcher.php +++ b/includes/class-activity-dispatcher.php @@ -160,7 +160,7 @@ public static function send_profile_update( $user_id ) { */ private static function send_activity_to_followers( $activity, $user_id, $wp_object ) { /** - * Filter to prevent sending an Activity to followers. + * Filters whether to send an Activity to followers. * * @param bool $send_activity_to_followers Whether to send the Activity to followers. * @param Activity $activity The ActivityPub Activity. @@ -172,11 +172,11 @@ private static function send_activity_to_followers( $activity, $user_id, $wp_obj } /** - * Filter to modify the Activity before sending it to followers. + * Filters the list of inboxes to send the Activity to. * - * @param Activity $activity The ActivityPub Activity. - * @param int $user_id The user ID. - * @param \WP_User|WP_Post|WP_Comment $wp_object The WordPress object. + * @param array $inboxes The list of inboxes to send to. + * @param int $user_id The user ID. + * @param Activity $activity The ActivityPub Activity. */ $inboxes = apply_filters( 'activitypub_send_to_inboxes', array(), $user_id, $activity ); $inboxes = array_unique( $inboxes ); @@ -208,7 +208,7 @@ public static function send_post( $id, $type ) { } /** - * Action to send an Activity for a Post. + * Fires when an Activity is being sent for any object type. * * @param WP_Post $post The WordPress Post. * @param string $type The Activity-Type. @@ -216,7 +216,7 @@ public static function send_post( $id, $type ) { do_action( 'activitypub_send_activity', $post, $type ); /** - * Action to send a specific Activity for a Post. + * Fires when a specific type of Activity is being sent. * * @param WP_Post $post The WordPress Post. */ @@ -237,7 +237,7 @@ public static function send_comment( $id, $type ) { } /** - * Action to send an Activity for a Comment. + * Fires when an Activity is being sent for a Comment. * * @param WP_Comment $comment The WordPress Comment. * @param string $type The Activity-Type. @@ -245,7 +245,7 @@ public static function send_comment( $id, $type ) { do_action( 'activitypub_send_activity', $comment, $type ); /** - * Action to send a specific Activity for a Comment. + * Fires when a specific type of Activity is being sent for a Comment. * * @param WP_Comment $comment The WordPress Comment. */ diff --git a/includes/class-activitypub.php b/includes/class-activitypub.php index f6da99f23..49ffbd502 100644 --- a/includes/class-activitypub.php +++ b/includes/class-activitypub.php @@ -555,6 +555,9 @@ private static function register_post_types() { \register_post_type( Extra_Fields::USER_POST_TYPE, $args ); \register_post_type( Extra_Fields::BLOG_POST_TYPE, $args ); + /** + * Fires after ActivityPub custom post types have been registered. + */ \do_action( 'activitypub_after_register_post_type' ); } diff --git a/includes/class-comment.php b/includes/class-comment.php index 2fb024f1e..252917b85 100644 --- a/includes/class-comment.php +++ b/includes/class-comment.php @@ -65,6 +65,13 @@ public static function comment_reply_link( $link, $args, $comment ) { esc_attr( wp_json_encode( $attrs ) ) ); + /** + * Filters the HTML markup for the ActivityPub remote comment reply container. + * + * @param string $div The HTML markup for the remote reply container. Default is a div + * with class 'activitypub-remote-reply' and data attributes for + * the selected comment ID and internal comment ID. + */ return apply_filters( 'activitypub_comment_reply_link', $div ); } diff --git a/includes/class-http.php b/includes/class-http.php index 8d719e845..85edec316 100644 --- a/includes/class-http.php +++ b/includes/class-http.php @@ -26,6 +26,13 @@ class Http { * @return array|WP_Error The POST Response or an WP_Error. */ public static function post( $url, $body, $user_id ) { + /** + * Fires before an HTTP POST request is made. + * + * @param string $url The URL endpoint. + * @param string $body The POST body. + * @param int $user_id The WordPress User ID. + */ \do_action( 'activitypub_pre_http_post', $url, $body, $user_id ); $date = \gmdate( 'D, d M Y H:i:s T' ); @@ -35,7 +42,7 @@ public static function post( $url, $body, $user_id ) { $wp_version = get_masked_wp_version(); /** - * Filter the HTTP headers user agent. + * Filters the HTTP headers user agent string. * * @param string $user_agent The user agent string. */ @@ -84,6 +91,11 @@ public static function post( $url, $body, $user_id ) { * @return array|WP_Error The GET Response or a WP_Error. */ public static function get( $url, $cached = false ) { + /** + * Fires before an HTTP GET request is made. + * + * @param string $url The URL endpoint. + */ \do_action( 'activitypub_pre_http_get', $url ); if ( $cached ) { @@ -110,14 +122,24 @@ public static function get( $url, $cached = false ) { $wp_version = get_masked_wp_version(); /** - * Filter the HTTP headers user agent. + * Filters the HTTP headers user agent string. + * + * This filter allows developers to modify the user agent string that is + * sent with HTTP requests. * * @param string $user_agent The user agent string. */ $user_agent = \apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version . '; ' . \get_bloginfo( 'url' ) ); + /** + * Filters the timeout duration for remote GET requests in ActivityPub. + * + * @param int $timeout The timeout value in seconds. Default 100 seconds. + */ + $timeout = \apply_filters( 'activitypub_remote_get_timeout', 100 ); + $args = array( - 'timeout' => apply_filters( 'activitypub_remote_get_timeout', 100 ), + 'timeout' => $timeout, 'limit_response_size' => 1048576, 'redirection' => 3, 'user-agent' => "$user_agent; ActivityPub", @@ -164,7 +186,7 @@ public static function get( $url, $cached = false ) { */ public static function is_tombstone( $url ) { /** - * Action before checking if the URL is a tombstone. + * Fires before checking if the URL is a tombstone. * * @param string $url The URL to check. */ diff --git a/includes/class-link.php b/includes/class-link.php index 6da1233c4..783f1fecd 100644 --- a/includes/class-link.php +++ b/includes/class-link.php @@ -112,6 +112,11 @@ public static function replace_with_links( $result ) { $display_class .= 'ellipsis'; } + /** + * Filters the rel attribute for ActivityPub links. + * + * @param string $rel The rel attribute string. Default 'nofollow noopener noreferrer'. + */ $rel = apply_filters( 'activitypub_link_rel', 'nofollow noopener noreferrer' ); return \sprintf( diff --git a/includes/class-shortcodes.php b/includes/class-shortcodes.php index 91884a874..6ac73c03c 100644 --- a/includes/class-shortcodes.php +++ b/includes/class-shortcodes.php @@ -129,6 +129,7 @@ public static function excerpt( $atts, $content, $tag ) { $excerpt = generate_post_summary( $item, $excerpt_length ); + /** This filter is documented in wp-includes/post-template.php */ return \apply_filters( 'the_excerpt', $excerpt ); } @@ -169,6 +170,7 @@ public static function content( $atts, $content, $tag ) { $content = \get_post_field( 'post_content', $item ); if ( 'yes' === $atts['apply_filters'] ) { + /** This filter is documented in wp-includes/post-template.php */ $content = \apply_filters( 'the_content', $content ); } else { $content = do_blocks( $content ); diff --git a/includes/collection/class-extra-fields.php b/includes/collection/class-extra-fields.php index 7661d5778..73066f1b8 100644 --- a/includes/collection/class-extra-fields.php +++ b/includes/collection/class-extra-fields.php @@ -42,6 +42,15 @@ public static function get_actor_fields( $user_id ) { $query = new \WP_Query( $args ); $fields = $query->posts ?? array(); + /** + * Filters the extra fields for an ActivityPub actor. + * + * This filter allows developers to modify or add custom fields to an actor's + * profile. + * + * @param \WP_Post[] $fields Array of WP_Post objects representing the extra fields. + * @param int $user_id The ID of the user whose fields are being retrieved. + */ return apply_filters( 'activitypub_get_actor_extra_fields', $fields, $user_id ); } diff --git a/includes/functions.php b/includes/functions.php index b6cc9aa83..a06a09b7f 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -21,6 +21,15 @@ function get_context() { $context = Activity::JSON_LD_CONTEXT; + /** + * Filters the ActivityPub JSON-LD context. + * + * This filter allows developers to modify or extend the JSON-LD context used + * in ActivityPub responses. The context defines the vocabulary and terms used + * in the ActivityPub JSON objects. + * + * @param array $context The default ActivityPub JSON-LD context array. + */ return \apply_filters( 'activitypub_json_context', $context ); } @@ -68,6 +77,16 @@ function get_webfinger_resource( $user_id ) { * @return array|WP_Error The Actor profile as array or WP_Error on failure. */ function get_remote_metadata_by_actor( $actor, $cached = true ) { + /** + * Filters the metadata before it is retrieved from a remote actor. + * + * Passing a non-false value will effectively short-circuit the remote request, + * returning that value instead. + * + * @param mixed $pre The value to return instead of the remote metadata. + * Default false to continue with the remote request. + * @param string $actor The actor URL. + */ $pre = apply_filters( 'pre_get_remote_metadata_by_actor', false, $actor ); if ( $pre ) { return $pre; @@ -414,7 +433,7 @@ function is_post_disabled( $post ) { $disabled = true; } - /* + /** * Allow plugins to disable posts for ActivityPub. * * @param boolean $disabled True if the post is disabled, false otherwise. @@ -1312,11 +1331,7 @@ function generate_post_summary( $post, $length = 500 ) { $content = \sanitize_post_field( 'post_excerpt', $post->post_excerpt, $post->ID ); if ( $content ) { - /** - * Filters the post excerpt. - * - * @param string $content The post excerpt. - */ + /** This filter is documented in wp-includes/post-template.php */ return \apply_filters( 'the_excerpt', $content ); } @@ -1354,6 +1369,7 @@ function generate_post_summary( $post, $length = 500 ) { /* Removed until this is merged: https://github.com/mastodon/mastodon/pull/28629 + /** This filter is documented in wp-includes/post-template.php return \apply_filters( 'the_excerpt', $content ); */ return $content; @@ -1459,6 +1475,15 @@ function get_content_visibility( $post_id ) { $_visibility = $visibility; } + /** + * Filters the visibility of a post. + * + * @param string $_visibility The visibility of the post. Possible values are: + * - 'public': Post is public and federated. + * - 'quiet_public': Post is public but not federated. + * - 'local': Post is only visible locally. + * @param \WP_Post $post The post object. + */ return \apply_filters( 'activitypub_content_visibility', $_visibility, $post ); } @@ -1512,7 +1537,7 @@ function get_upload_baseurl() { /** * Filters the upload base URL. * - * @param string \wp_get_upload_dir()['baseurl'] The upload base URL. + * @param string $upload_dir The upload base URL. Default \wp_get_upload_dir()['baseurl'] */ return apply_filters( 'activitypub_get_upload_baseurl', $upload_dir['baseurl'] ); } diff --git a/includes/handler/class-follow.php b/includes/handler/class-follow.php index a704e4ec1..f3e3d5487 100644 --- a/includes/handler/class-follow.php +++ b/includes/handler/class-follow.php @@ -55,13 +55,15 @@ public static function handle_follow( $activity ) { $activity['actor'] ); - do_action( - 'activitypub_followers_post_follow', - $activity['actor'], - $activity, - $user_id, - $follower - ); + /** + * Fires after a new follower has been added. + * + * @param string $actor The URL of the actor (follower) who initiated the follow. + * @param array $activity The complete activity data of the follow request. + * @param int $user_id The ID of the WordPress user being followed. + * @param \Activitypub\Model\Follower $follower The Follower object containing the new follower's data. + */ + do_action( 'activitypub_followers_post_follow', $activity['actor'], $activity, $user_id, $follower ); // Send notification. $notification = new Notification( diff --git a/includes/handler/class-update.php b/includes/handler/class-update.php index 5cc58efe2..983c68d42 100644 --- a/includes/handler/class-update.php +++ b/includes/handler/class-update.php @@ -88,6 +88,14 @@ public static function update_interaction( $activity ) { $state = $commentdata; } + /** + * Fires after an Update activity has been handled. + * + * @param array $activity The complete Update activity data. + * @param null $user Always null for Update activities. + * @param int|array $state 1 if comment was updated successfully, error data otherwise. + * @param \WP_Comment|null $reaction The updated comment object if successful, null otherwise. + */ \do_action( 'activitypub_handled_update', $activity, null, $state, $reaction ); } diff --git a/includes/model/class-blog.php b/includes/model/class-blog.php index 0c0d05932..e5f860522 100644 --- a/includes/model/class-blog.php +++ b/includes/model/class-blog.php @@ -204,7 +204,11 @@ public static function get_default_username() { /** * Filters the default blog username. * - * @param string $host The default username. + * This filter allows developers to modify the default username that is + * generated for the blog, which by default is the site's host name + * without the 'www.' prefix. + * + * @param string $host The default username (site's host name). */ return apply_filters( 'activitypub_default_blog_username', $host ); } diff --git a/includes/rest/class-inbox.php b/includes/rest/class-inbox.php index 9d0b44c47..814a2f986 100644 --- a/includes/rest/class-inbox.php +++ b/includes/rest/class-inbox.php @@ -85,7 +85,7 @@ public static function user_inbox_get( $request ) { } /** - * Action triggered prior to the ActivityPub profile being created and sent to the client. + * Fires before the ActivityPub inbox is created and sent to the client. */ \do_action( 'activitypub_rest_inbox_pre' ); @@ -103,14 +103,14 @@ public static function user_inbox_get( $request ) { // phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase /** - * Filter the ActivityPub inbox array. + * Filters the ActivityPub inbox data before it is sent to the client. * * @param array $json The ActivityPub inbox array. */ $json = \apply_filters( 'activitypub_rest_inbox_array', $json ); /** - * Action triggered after the ActivityPub profile has been created and sent to the client. + * Fires after the ActivityPub inbox has been created and sent to the client. */ \do_action( 'activitypub_inbox_post' ); diff --git a/includes/rest/class-interaction.php b/includes/rest/class-interaction.php index 8bf78267e..2eca4bf2e 100644 --- a/includes/rest/class-interaction.php +++ b/includes/rest/class-interaction.php @@ -80,10 +80,26 @@ public static function get( $request ) { case 'Service': case 'Application': case 'Organization': + /** + * Filters the URL used for following an ActivityPub actor. + * + * @param string $redirect_url The URL to redirect to. + * @param string $uri The URI of the actor to follow. + * @param array $object The full actor object data. + */ $redirect_url = \apply_filters( 'activitypub_interactions_follow_url', $redirect_url, $uri, $object ); break; default: $redirect_url = \admin_url( 'post-new.php?in_reply_to=' . $uri ); + /** + * Filters the URL used for replying to an ActivityPub object. + * + * By default, this redirects to the WordPress post editor with the in_reply_to parameter set. + * + * @param string $redirect_url The URL to redirect to. + * @param string $uri The URI of the object to reply to. + * @param array $object The full object data being replied to. + */ $redirect_url = \apply_filters( 'activitypub_interactions_reply_url', $redirect_url, $uri, $object ); } diff --git a/includes/rest/class-nodeinfo.php b/includes/rest/class-nodeinfo.php index 3eb5fc007..0118603d5 100644 --- a/includes/rest/class-nodeinfo.php +++ b/includes/rest/class-nodeinfo.php @@ -77,7 +77,7 @@ public static function register_routes() { */ public static function nodeinfo() { /** - * Action triggered prior to the ActivityPub profile being created and sent to the client. + * Fires before the NodeInfo data is created and sent to the client. */ \do_action( 'activitypub_rest_nodeinfo_pre' ); @@ -126,7 +126,7 @@ public static function nodeinfo() { */ public static function nodeinfo2() { /** - * Action triggered prior to the ActivityPub profile being created and sent to the client. + * Fires before the NodeInfo 2.0 data is created and sent to the client. */ \do_action( 'activitypub_rest_nodeinfo2_pre' ); diff --git a/includes/transformer/class-post.php b/includes/transformer/class-post.php index 21d9593a0..ce45cf1be 100644 --- a/includes/transformer/class-post.php +++ b/includes/transformer/class-post.php @@ -301,8 +301,15 @@ protected function get_attachment() { return array(); } - // Once upon a time we only supported images, but we now support audio/video as well. - // We maintain the image-centric naming for backwards compatibility. + /** + * Filters the maximum number of media attachments allowed in a post. + * + * Despite the name suggesting only images, this filter controls the maximum number + * of all media attachments (images, audio, and video) that can be included in an + * ActivityPub post. The name is maintained for backwards compatibility. + * + * @param int $max_media Maximum number of media attachments. Default ACTIVITYPUB_MAX_IMAGE_ATTACHMENTS. + */ $max_media = \intval( \apply_filters( 'activitypub_max_image_attachments', @@ -1003,6 +1010,12 @@ protected function get_content() { $content = \preg_replace( '/[\n\r\t]/', '', $content ); $content = \trim( $content ); + /** + * Filters the post content before it is transformed for ActivityPub. + * + * @param string $content The post content to be transformed. + * @param WP_Post $post The post object being transformed. + */ $content = \apply_filters( 'activitypub_the_content', $content, $post ); // Don't need these anymore, should never appear in a post. @@ -1032,6 +1045,17 @@ protected function get_post_content_template() { $template .= '[ap_content]'; } + /** + * Filters the template used to generate ActivityPub object content. + * + * This filter allows developers to modify the template that determines how post + * content is formatted in ActivityPub objects. The template can include special + * shortcodes like [ap_title] and [ap_content] that are processed during content + * generation. + * + * @param string $template The template string containing shortcodes. + * @param WP_Post $wp_object The WordPress post object being transformed. + */ return apply_filters( 'activitypub_object_content_template', $template, $this->wp_object ); } diff --git a/templates/blog-json.php b/templates/blog-json.php index f2d1e0023..ece2181c7 100644 --- a/templates/blog-json.php +++ b/templates/blog-json.php @@ -8,7 +8,9 @@ $user = new \Activitypub\Model\Blog(); /** - * Action triggered prior to the ActivityPub profile being created and sent to the client + * Fires before an ActivityPub blog profile is generated and sent to the client. + * + * @param int $user_id The ID of the WordPress blog user whose profile is being generated. */ \do_action( 'activitypub_json_author_pre', $user->get__id() ); @@ -16,6 +18,8 @@ echo $user->to_json(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped /** - * Action triggered after the ActivityPub profile has been created and sent to the client + * Fires after an ActivityPub blog profile has been generated and sent to the client. + * + * @param int $user_id The ID of the WordPress blog user whose profile was generated. */ \do_action( 'activitypub_json_author_post', $user->get__id() ); diff --git a/templates/comment-json.php b/templates/comment-json.php index 49c3d33c3..3a2df1062 100644 --- a/templates/comment-json.php +++ b/templates/comment-json.php @@ -16,7 +16,7 @@ } /** - * Action triggered prior to the ActivityPub profile being created and sent to the client + * Fires before an ActivityPub comment object is generated and sent to the client. */ \do_action( 'activitypub_json_comment_pre' ); @@ -24,6 +24,6 @@ echo $transformer->to_object()->to_json(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped /** - * Action triggered after the ActivityPub profile has been created and sent to the client + * Fires after an ActivityPub comment object has been generated and sent to the client. */ \do_action( 'activitypub_json_comment_post' ); diff --git a/templates/post-json.php b/templates/post-json.php index 745629f5d..4be19296a 100644 --- a/templates/post-json.php +++ b/templates/post-json.php @@ -17,7 +17,7 @@ /** - * Action triggered prior to the ActivityPub profile being created and sent to the client + * Fires before an ActivityPub post object is generated and sent to the client. */ \do_action( 'activitypub_json_post_pre' ); @@ -25,6 +25,6 @@ echo $transformer->to_object()->to_json(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped /** - * Action triggered after the ActivityPub profile has been created and sent to the client + * Fires after an ActivityPub post object has been generated and sent to the client. */ \do_action( 'activitypub_json_post_post' ); diff --git a/templates/user-json.php b/templates/user-json.php index 548d4be86..340f6e519 100644 --- a/templates/user-json.php +++ b/templates/user-json.php @@ -8,7 +8,9 @@ $user = \Activitypub\Collection\Actors::get_by_id( \get_the_author_meta( 'ID' ) ); /** - * Action triggered prior to the ActivityPub profile being created and sent to the client + * Fires before an ActivityPub user profile is generated and sent to the client. + * + * @param int $user_id The ID of the WordPress user whose profile is being generated. */ \do_action( 'activitypub_json_author_pre', $user->get__id() ); @@ -16,6 +18,8 @@ echo $user->to_json(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped /** - * Action triggered after the ActivityPub profile has been created and sent to the client + * Fires after an ActivityPub user profile has been generated and sent to the client. + * + * @param int $user_id The ID of the WordPress user whose profile was generated. */ \do_action( 'activitypub_json_author_post', $user->get__id() );