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

@ -7,6 +7,7 @@
namespace Activitypub;
use Activitypub\Activity\Extended_Object\Quote_Authorization;
use Activitypub\Collection\Actors;
use Activitypub\Collection\Outbox;
use Activitypub\Transformer\Factory;
@ -138,6 +139,10 @@ class Query {
private function prepare_activitypub_data() {
$queried_object = $this->get_queried_object();
if ( $queried_object instanceof \WP_Post && \get_query_var( 'stamp' ) ) {
return $this->maybe_get_stamp();
}
// Check for Outbox Activity.
if (
$queried_object instanceof \WP_Post &&
@ -193,6 +198,14 @@ class Query {
}
}
// Check Term by ID.
if ( ! $queried_object ) {
$term_id = \get_query_var( 'term_id' );
if ( $term_id ) {
$queried_object = \get_term( $term_id );
}
}
// Try to get Author by ID.
if ( ! $queried_object ) {
$url = $this->get_request_url();
@ -248,7 +261,7 @@ class Query {
*
* @return string|null The request URL.
*/
protected function get_request_url() {
public function get_request_url() {
if ( ! isset( $_SERVER['REQUEST_URI'] ) ) {
return null;
}
@ -267,50 +280,74 @@ class Query {
* @return bool True if the request is an ActivityPub request, false otherwise.
*/
public function is_activitypub_request() {
if ( isset( $this->is_activitypub_request ) ) {
return $this->is_activitypub_request;
}
if ( ! isset( $this->is_activitypub_request ) ) {
global $wp_query;
global $wp_query;
$this->is_activitypub_request = false;
// One can trigger an ActivityPub request by adding `?activitypub` to the URL.
if (
isset( $wp_query->query_vars['activitypub'] ) ||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
isset( $_GET['activitypub'] )
) {
\defined( 'ACTIVITYPUB_REQUEST' ) || \define( 'ACTIVITYPUB_REQUEST', true );
$this->is_activitypub_request = true;
return true;
}
/*
* The other (more common) option to make an ActivityPub request
* is to send an Accept header.
*/
if ( isset( $_SERVER['HTTP_ACCEPT'] ) ) {
$accept = \sanitize_text_field( \wp_unslash( $_SERVER['HTTP_ACCEPT'] ) );
/*
* $accept can be a single value, or a comma separated list of values.
* We want to support both scenarios,
* and return true when the header includes at least one of the following:
* - application/activity+json
* - application/ld+json
* - application/json
*/
if ( \preg_match( '/(application\/(ld\+json|activity\+json|json))/i', $accept ) ) {
// One can trigger an ActivityPub request by adding `?activitypub` to the URL.
if ( isset( $wp_query->query_vars['activitypub'] ) || isset( $_GET['activitypub'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
\defined( 'ACTIVITYPUB_REQUEST' ) || \define( 'ACTIVITYPUB_REQUEST', true );
$this->is_activitypub_request = true;
return true;
// The other (more common) option to make an ActivityPub request is to send an Accept header.
} elseif ( isset( $_SERVER['HTTP_ACCEPT'] ) ) {
$accept = \sanitize_text_field( \wp_unslash( $_SERVER['HTTP_ACCEPT'] ) );
/*
* $accept can be a single value, or a comma separated list of values.
* We want to support both scenarios,
* and return true when the header includes at least one of the following:
* - application/activity+json
* - application/ld+json
* - application/json
*/
if ( \preg_match( '/(application\/(ld\+json|activity\+json|json))/i', $accept ) ) {
\defined( 'ACTIVITYPUB_REQUEST' ) || \define( 'ACTIVITYPUB_REQUEST', true );
$this->is_activitypub_request = true;
}
}
}
$this->is_activitypub_request = false;
/**
* Filters whether the current request is an ActivityPub request.
*
* @param bool $is_activitypub_request True if the request is an ActivityPub request, false otherwise.
*/
return \apply_filters( 'activitypub_is_activitypub_request', $this->is_activitypub_request );
}
return false;
/**
* Check if content negotiation is allowed for a request.
*
* @return bool True if content negotiation is allowed, false otherwise.
*/
public function should_negotiate_content() {
$return = false;
$always_negotiate = array( 'p', 'c', 'author', 'actor', 'stamp', 'preview', 'activitypub' );
$url = \wp_parse_url( $this->get_request_url(), PHP_URL_QUERY );
$query = array();
\wp_parse_str( $url, $query );
// Check if any of the query params are in the `$always_negotiate` array.
if ( \array_intersect( \array_keys( $query ), $always_negotiate ) ) {
$return = true;
}
if ( \get_option( 'activitypub_content_negotiation', '1' ) ) {
$return = true;
}
if ( \is_author() && \get_user_option( 'activitypub_use_permalink_as_id', \get_queried_object_id() ) ) {
$return = true;
}
/**
* Filters whether content negotiation should be forced.
*
* @param bool $return Whether content negotiation should be forced.
*/
return \apply_filters( 'activitypub_should_negotiate_content', $return );
}
/**
@ -348,4 +385,52 @@ class Query {
public function set_old_host_request( $state = true ) {
$this->is_old_host_request = $state;
}
/**
* Maybe get a QuoteAuthorization object from a stamp.
*
* @return bool True if the object was prepared, false otherwise.
*/
private function maybe_get_stamp() {
require_once ABSPATH . 'wp-admin/includes/post.php';
$stamp = \get_query_var( 'stamp' );
$meta = \get_post_meta_by_id( (int) $stamp );
if ( ! $meta ) {
return false;
}
$post = $this->get_queried_object();
// Ensure the meta belongs to the queried post to prevent arbitrary meta disclosure.
if ( (int) $meta->post_id !== $post->ID ) {
return false;
}
$user_uri = get_user_id( $post->post_author );
if ( ! $user_uri ) {
return false;
}
$stamp_uri = \add_query_arg(
array(
'p' => $post->ID,
'stamp' => $meta->meta_id,
),
\home_url( '/' )
);
$activitypub_object = new Quote_Authorization();
$activitypub_object->set_id( $stamp_uri );
$activitypub_object->set_attributed_to( $user_uri );
$activitypub_object->set_interacting_object( $meta->meta_value );
$activitypub_object->set_interaction_target( get_post_id( $post->ID ) );
$this->activitypub_object = $activitypub_object;
$this->activitypub_object_id = $activitypub_object->get_id();
return true;
}
}