From 60148a3b652918772aa3e72d0c1a0a45659273f2 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Tue, 21 Nov 2023 14:57:44 +0100 Subject: [PATCH 1/8] check if user is available --- integration/class-webfinger.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/integration/class-webfinger.php b/integration/class-webfinger.php index 177b417..c9dd565 100644 --- a/integration/class-webfinger.php +++ b/integration/class-webfinger.php @@ -30,6 +30,10 @@ class Webfinger { public static function add_user_discovery( $array, $resource, $user ) { $user = User_Collection::get_by_id( $user->ID ); + if ( ! $user || is_wp_error( $user ) ) { + return $array; + } + $array['links'][] = array( 'rel' => 'self', 'type' => 'application/activity+json', From d00e5a03c8e768f6db1f7342851fde5c64bff8dc Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Tue, 21 Nov 2023 15:00:39 +0100 Subject: [PATCH 2/8] check if $resource is set --- includes/class-webfinger.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/includes/class-webfinger.php b/includes/class-webfinger.php index b6b0a64..75f7ff6 100644 --- a/includes/class-webfinger.php +++ b/includes/class-webfinger.php @@ -41,9 +41,14 @@ class Webfinger { * @return string|WP_Error The URL or WP_Error */ public static function resolve( $resource ) { + if ( ! $resource ) { + return null; + } + if ( ! preg_match( '/^@?' . ACTIVITYPUB_USERNAME_REGEXP . '$/i', $resource, $m ) ) { return null; } + $transient_key = 'activitypub_resolve_' . ltrim( $resource, '@' ); $link = \get_transient( $transient_key ); From 1af821621b749146ecb86b18291126f9d261049b Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Tue, 21 Nov 2023 15:05:12 +0100 Subject: [PATCH 3/8] check if ID is set fallback to URL --- includes/rest/class-inbox.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/includes/rest/class-inbox.php b/includes/rest/class-inbox.php index 2cedf15..2b406ea 100644 --- a/includes/rest/class-inbox.php +++ b/includes/rest/class-inbox.php @@ -123,6 +123,7 @@ class Inbox { * @return WP_REST_Response */ public static function user_inbox_post( $request ) { + var_dump( $request->get_params() ); $user_id = $request->get_param( 'user_id' ); $user = User_Collection::get_by_various( $user_id ); @@ -236,8 +237,12 @@ class Inbox { $params['actor'] = array( 'required' => true, 'sanitize_callback' => function( $param, $request, $key ) { - if ( ! \is_string( $param ) ) { - $param = $param['id']; + if ( \is_array( $param ) ) { + if ( isset( $param['id'] ) ) { + $param = $param['id']; + } else { + $param = $param['url']; + } } return \esc_url_raw( $param ); }, From ba44ac701bc78727f22f8281d221a83f5ea25363 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Tue, 21 Nov 2023 15:05:47 +0100 Subject: [PATCH 4/8] remove var_dump --- includes/rest/class-inbox.php | 1 - 1 file changed, 1 deletion(-) diff --git a/includes/rest/class-inbox.php b/includes/rest/class-inbox.php index 2b406ea..15fb4b2 100644 --- a/includes/rest/class-inbox.php +++ b/includes/rest/class-inbox.php @@ -123,7 +123,6 @@ class Inbox { * @return WP_REST_Response */ public static function user_inbox_post( $request ) { - var_dump( $request->get_params() ); $user_id = $request->get_param( 'user_id' ); $user = User_Collection::get_by_various( $user_id ); From c857eee6169e7448eb369c5b8e5bd2bae8233874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Menrath?= Date: Wed, 22 Nov 2023 13:59:39 +0100 Subject: [PATCH 5/8] transformer: move all related code to \Activitypub\Transformer namespace --- includes/class-activity-dispatcher.php | 6 +- includes/class-admin.php | 9 +- includes/model/class-post.php | 4 +- includes/rest/class-collection.php | 2 +- includes/rest/class-outbox.php | 4 +- .../class-base.php} | 113 ++++++++---------- includes/transformer/class-post.php | 13 +- .../class-transformers-manager.php | 36 +++--- templates/post-json.php | 2 +- templates/settings.php | 12 +- tests/test-class-activitypub-activity.php | 4 +- tests/test-class-activitypub-post.php | 4 +- ...typub-rest-post-signature-verification.php | 4 +- 13 files changed, 102 insertions(+), 111 deletions(-) rename includes/{class-transformer-base.php => transformer/class-base.php} (89%) rename includes/{ => transformer}/class-transformers-manager.php (91%) diff --git a/includes/class-activity-dispatcher.php b/includes/class-activity-dispatcher.php index 6e5edd5..617162d 100644 --- a/includes/class-activity-dispatcher.php +++ b/includes/class-activity-dispatcher.php @@ -5,7 +5,7 @@ use WP_Post; use Activitypub\Activity\Activity; use Activitypub\Collection\Users; use Activitypub\Collection\Followers; -use Activitypub\Transformers_Manager; +use Activitypub\Transformer\Transformers_Manager; use function Activitypub\is_single_user; use function Activitypub\is_user_disabled; @@ -65,7 +65,7 @@ class Activity_Dispatcher { return; } - $transformer = \Activitypub\Transformers_Manager::instance()->get_transformer( $wp_post ); + $transformer = \Activitypub\Transformer\Transformers_Manager::instance()->get_transformer( $wp_post ); $object = $transformer->to_object(); $activity = new Activity(); @@ -102,7 +102,7 @@ class Activity_Dispatcher { return; } - $transformer = \Activitypub\Transformers_Manager::instance()->get_transformer( $wp_post ); + $transformer = \Activitypub\Transformer\Transformers_Manager::instance()->get_transformer( $wp_post ); $object = $transformer->to_object(); $activity = new Activity(); diff --git a/includes/class-admin.php b/includes/class-admin.php index 718e1c6..1105a0a 100644 --- a/includes/class-admin.php +++ b/includes/class-admin.php @@ -3,7 +3,7 @@ namespace Activitypub; use WP_User_Query; use Activitypub\Model\Blog_User; -use Activitypub\Base\Transformer_Base; +use Activitypub\Base\Transformer\Base as Transformer_Base; /** * ActivityPub Admin Class @@ -24,7 +24,8 @@ class Admin { \add_action( 'show_user_profile', array( self::class, 'add_profile' ) ); } - add_filter( 'activitypub/transformers/is_transformer_enabled', function( $should_register, Transformer_Base $widget_instance ) { + add_filter( + 'activitypub/transformers/is_transformer_enabled', function( $should_register, Transformer_Base $widget_instance ) { return ! Options::is_transformer_disabled( $transformer_instance->get_name() ); }, 10, 2 ); } @@ -162,8 +163,8 @@ class Admin { /** * Flexible activation of post_types together with mapping ActivityPub transformers. - * - * If a post-type is not mapped to any ActivtiyPub transformer it means it is not activated + * + * If a post-type is not mapped to any ActivtiyPub transformer it means it is not activated * for ActivityPub federation. * * @since version_number_transformer_management_placeholder diff --git a/includes/model/class-post.php b/includes/model/class-post.php index a9aa498..ac451d0 100644 --- a/includes/model/class-post.php +++ b/includes/model/class-post.php @@ -1,7 +1,7 @@ post = $post; $this->object = Post_Transformer->set_wp_post( $post )->to_object(); diff --git a/includes/rest/class-collection.php b/includes/rest/class-collection.php index 353b414..75efb9d 100644 --- a/includes/rest/class-collection.php +++ b/includes/rest/class-collection.php @@ -4,7 +4,7 @@ namespace Activitypub\Rest; use WP_Error; use WP_REST_Server; use WP_REST_Response; -use Activitypub\Transformers_Manager; +use Activitypub\Transformer\Transformers_Manager; use Activitypub\Activity\Activity; use Activitypub\Collection\Users as User_Collection; diff --git a/includes/rest/class-outbox.php b/includes/rest/class-outbox.php index 7d0d10d..e5ff834 100644 --- a/includes/rest/class-outbox.php +++ b/includes/rest/class-outbox.php @@ -5,7 +5,7 @@ use stdClass; use WP_Error; use WP_REST_Server; use WP_REST_Response; -use Activitypub\Transformers_Manager; +use Activitypub\Transformer\Transformers_Manager; use Activitypub\Activity\Activity; use Activitypub\Collection\Users as User_Collection; @@ -105,7 +105,7 @@ class Outbox { ); foreach ( $posts as $post ) { - $transformer = \Activitypub\Transformers_Manager::instance()->get_transformer( $post ); + $transformer = \Activitypub\Transformer\Transformers_Manager::instance()->get_transformer( $post ); $post = $transformer->to_object(); $activity = new Activity(); $activity->set_type( 'Create' ); diff --git a/includes/class-transformer-base.php b/includes/transformer/class-base.php similarity index 89% rename from includes/class-transformer-base.php rename to includes/transformer/class-base.php index 56adda8..d4062a9 100644 --- a/includes/class-transformer-base.php +++ b/includes/transformer/class-base.php @@ -4,15 +4,13 @@ * * @link https://github.com/landrok/activitypub */ - -namespace Activitypub; +namespace Activitypub\Transformer; use WP_Post; use Activitypub\Collection\Users; use Activitypub\Model\Blog_User; use Activitypub\Activity\Base_Object; use Activitypub\Shortcodes; -use Activitypub\Transformer_Base; use function Activitypub\esc_hashtag; use function Activitypub\is_single_user; @@ -22,7 +20,7 @@ use function Activitypub\site_supports_blocks; /** * Base class to implement WordPress to ActivityPub transformers. */ -abstract class Transformer_Base { +abstract class Base { /** * The WP_Post object. * @@ -35,40 +33,38 @@ abstract class Transformer_Base { * * This helps to chain the output of the Transformer. * - * @param WP_Post $wp_post The WP_Post object - * + * @param WP_Post $wp_post The WP_Post object. * @return void */ public function set_wp_post( WP_Post $wp_post ) { if ( $this->supports_post_type( get_post_type( $wp_post ) ) ) { $this->wp_post = $wp_post; } else { - //TODO Error, this should not happen. - } + // TODO Error, this should not happen. + } } - /** + /** * Get the supported WP post_types that the transformer can use as an input. * - * By default all post types are supported. + * By default all post types are supported. * You may very likely wish to override this function. - * + * * @since version_number_transformer_management_placeholder - * @return string[] An array containing all the supported post types. + * @return string[] An array containing all the supported post types. */ - public function get_supported_post_types() { - return \get_post_types( array( 'public' => true ), 'names' ); - } + public function get_supported_post_types() { + return \get_post_types( array( 'public' => true ), 'names' ); + } - /** + /** * Get the name of the plugin that registered the transformer. - * - * @see Forked from the WordPress elementor plugin. - * + * + * @see Forked from the WordPress elementor plugin. * @since version_number_transformer_management_placeholder - * @return string Plugin name + * @return string Plugin name */ - private function get_plugin_name_from_transformer_instance( $transformer ) { + private function get_plugin_name_from_transformer_instance( $transformer ) { $class_reflection = new \ReflectionClass( $transformer ); $plugin_basename = plugin_basename( $class_reflection->getFileName() ); @@ -76,39 +72,36 @@ abstract class Transformer_Base { $plugin_directory = strtok( $plugin_basename, '/' ); $plugins_data = get_plugins( '/' . $plugin_directory ); - $plugin_data = array_shift( $plugins_data ); + $plugin_data = array_shift( $plugins_data ); return $plugin_data['Name'] ?? esc_html__( 'Unknown', 'activitypub' ); } - /** + /** * Return whether the transformer supports a post type. * * @since version_number_transformer_management_placeholder - * - * @return string post_type Post type name. + * @return string post_type Post type name. */ - final public function supports_post_type( $post_type ) { + final public function supports_post_type( $post_type ) { return in_array( $post_type, $this->get_supported_post_types() ); } - /** + /** * Get the name used for registering the transformer with the ActivityPub plugin. * * @since version_number_transformer_management_placeholder - * - * @return string name + * @return string name */ - abstract public function get_name(); + abstract public function get_name(); - /** + /** * Get the display name for the ActivityPub transformer. * * @since version_number_transformer_management_placeholder - * - * @return string display name + * @return string display name */ - abstract public function get_label(); + abstract public function get_label(); /** * Returns the ActivityStreams 2.0 Object-Type for a Post. @@ -118,7 +111,7 @@ abstract class Transformer_Base { * @return string The Object-Type. */ abstract protected function get_object_type(); - + /** * Returns the content for the ActivityPub Item. * @@ -162,7 +155,7 @@ abstract class Transformer_Base { } - /** + /** * Returns the ID of the Post. * * @return string The Posts ID. @@ -244,7 +237,7 @@ abstract class Transformer_Base { } if ( $max_media > 0 ) { - $blocks = \parse_blocks( $this->wp_post->post_content ); + $blocks = \parse_blocks( $this->wp_post->post_content ); $media_ids = self::get_media_ids_from_blocks( $blocks, $media_ids, $max_media ); } @@ -278,12 +271,12 @@ abstract class Transformer_Base { if ( $max_images > 0 ) { $query = new \WP_Query( array( - 'post_parent' => $id, - 'post_status' => 'inherit', - 'post_type' => 'attachment', + 'post_parent' => $id, + 'post_status' => 'inherit', + 'post_type' => 'attachment', 'post_mime_type' => 'image', - 'order' => 'ASC', - 'orderby' => 'menu_order ID', + 'order' => 'ASC', + 'orderby' => 'menu_order ID', 'posts_per_page' => $max_images, ) ); @@ -300,9 +293,10 @@ abstract class Transformer_Base { /** * Recursively get media IDs from blocks. + * * @param array $blocks The blocks to search for media IDs * @param array $media_ids The media IDs to append new IDs to - * @param int $max_media The maximum number of media to return. + * @param int $max_media The maximum number of media to return. * * @return array The image IDs. */ @@ -361,8 +355,8 @@ abstract class Transformer_Base { * @return array The ActivityPub Attachment. */ public static function wp_attachment_to_activity_attachment( $id ) { - $attachment = array(); - $mime_type = \get_post_mime_type( $id ); + $attachment = array(); + $mime_type = \get_post_mime_type( $id ); $mime_type_parts = \explode( '/', $mime_type ); // switching on image/audio/video switch ( $mime_type_parts[0] ) { @@ -406,10 +400,10 @@ abstract class Transformer_Base { 'url' => \wp_get_attachment_url( $id ), 'name' => \get_the_title( $id ), ); - $meta = wp_get_attachment_metadata( $id ); + $meta = wp_get_attachment_metadata( $id ); // height and width for videos if ( isset( $meta['width'] ) && isset( $meta['height'] ) ) { - $attachment['width'] = $meta['width']; + $attachment['width'] = $meta['width']; $attachment['height'] = $meta['height']; } // @todo: add `icon` support for audio/video attachments. Maybe use post thumbnail? @@ -460,12 +454,12 @@ abstract class Transformer_Base { } /** - * Returns a list of Mentions, used in the Post. - * - * @see https://docs.joinmastodon.org/spec/activitypub/#Mention - * - * @return array The list of Mentions. - */ + * Returns a list of Mentions, used in the Post. + * + * @see https://docs.joinmastodon.org/spec/activitypub/#Mention + * + * @return array The list of Mentions. + */ protected function get_cc() { $cc = array(); @@ -492,7 +486,7 @@ abstract class Transformer_Base { $post_tags = \get_the_tags( $this->wp_post->ID ); if ( $post_tags ) { foreach ( $post_tags as $post_tag ) { - $tag = array( + $tag = array( 'type' => 'Hashtag', 'href' => \esc_url( \get_tag_link( $post_tag->term_id ) ), 'name' => esc_hashtag( $post_tag->name ), @@ -504,7 +498,7 @@ abstract class Transformer_Base { $mentions = $this->get_mentions(); if ( $mentions ) { foreach ( $mentions as $mention => $url ) { - $tag = array( + $tag = array( 'type' => 'Mention', 'href' => \esc_url( $url ), 'name' => \esc_html( $mention ), @@ -540,9 +534,9 @@ abstract class Transformer_Base { /** * Gets the contentMap - * + * * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-contentmap - * + * * @return array the contenmap */ protected function get_content_map() { @@ -560,7 +554,7 @@ abstract class Transformer_Base { */ public function to_object() { $wp_post = $this->wp_post; - $object = new Base_Object(); + $object = new Base_Object(); $object->set_id( $this->get_id() ); $object->set_url( $this->get_url() ); @@ -593,5 +587,4 @@ abstract class Transformer_Base { return $object; } - -} \ No newline at end of file +} diff --git a/includes/transformer/class-post.php b/includes/transformer/class-post.php index ba8f4ed..e89adbb 100644 --- a/includes/transformer/class-post.php +++ b/includes/transformer/class-post.php @@ -1,12 +1,12 @@ wp_post ); + $post_type = \get_post_type( $this->wp_post ); switch ( $post_type ) { case 'post': $post_format = \get_post_format( $this->wp_post ); @@ -87,7 +85,7 @@ class Transformer_Post extends Transformer_Base { $object_type = 'Page'; break; case 'attachment': - $mime_type = \get_post_mime_type(); + $mime_type = \get_post_mime_type(); $media_type = \preg_replace( '/(\/[a-zA-Z]+)/i', '', $mime_type ); switch ( $media_type ) { case 'audio': @@ -129,5 +127,4 @@ class Transformer_Post extends Transformer_Base { return \get_option( 'activitypub_custom_post_content', ACTIVITYPUB_CUSTOM_POST_CONTENT ); } - } diff --git a/includes/class-transformers-manager.php b/includes/transformer/class-transformers-manager.php similarity index 91% rename from includes/class-transformers-manager.php rename to includes/transformer/class-transformers-manager.php index 56d9c8d..9d8de30 100644 --- a/includes/class-transformers-manager.php +++ b/includes/transformer/class-transformers-manager.php @@ -3,9 +3,10 @@ * Inspired by the way elementor handles addons. * * @link https://github.com/elementor/elementor/ + * @package Activitypub */ -namespace Activitypub; +namespace Activitypub\Transformer; use WP_Post; use WP_Comment; @@ -25,7 +26,6 @@ if ( ! defined( 'ABSPATH' ) ) { * * @since version_number_transformer_management_placeholder */ - class Transformers_Manager { const DEFAULT_TRANSFORMER_MAPPING = array( 'post' => ACTIVITYPUB_DEFAULT_TRANSFORMER, @@ -40,7 +40,7 @@ class Transformers_Manager { * @since version_number_transformer_management_placeholder * @access private * - * @var \ActivityPub\Transformer_Base[] + * @var \ActivityPub\Transformer\Base[] */ private $transformers = null; @@ -98,7 +98,7 @@ class Transformers_Manager { * * @since version_number_transformer_management_placeholder * @access public - */ + */ public function __construct() { $this->require_files(); } @@ -110,9 +110,9 @@ class Transformers_Manager { * * @since version_number_transformer_management_placeholder * @access private - */ + */ private function require_files() { - require ACTIVITYPUB_PLUGIN_DIR . 'includes/class-transformer-base.php'; + require ACTIVITYPUB_PLUGIN_DIR . 'includes/transformer/class-base.php'; } /** @@ -133,13 +133,13 @@ class Transformers_Manager { * @since version_number_transformer_management_placeholder * @access public * - * @param \ActivityPub\Transformer_Base $transformer_instance ActivityPub Transformer. + * @param \ActivityPub\Transformer\Base $transformer_instance ActivityPub Transformer. * * @return bool True if the ActivityPub transformer was registered. */ - public function register( Transformer_Base $transformer_instance) { + public function register( \ActivityPub\Transformer\Base $transformer_instance) { - if ( ! $transformer_instance instanceof Transformer_Base ) { + if ( ! $transformer_instance instanceof \ActivityPub\Transformer\Base ) { _doing_it_wrong( __METHOD__, __( 'ActivityPub transformer instance must be a of \ActivityPub\Transformer_Base class.' ), @@ -147,7 +147,7 @@ class Transformers_Manager { ); return false; } - + $transformer_name = $transformer_instance->get_name(); if ( preg_match( '/[A-Z]+/', $transformer_name ) ) { _doing_it_wrong( @@ -176,7 +176,7 @@ class Transformers_Manager { 'version_number_transformer_management_placeholder' ); return false; - } + } /** * Should the ActivityPub transformer be registered. @@ -184,7 +184,7 @@ class Transformers_Manager { * @since version_number_transformer_management_placeholder * * @param bool $should_register Should the ActivityPub transformer be registered. Default is `true`. - * @param \ActivityPub\Transformer_Base $transformer_instance Widget instance. + * @param \ActivityPub\Transformer\Base $transformer_instance Widget instance. */ // TODO: does not implementing this slow down the website? -> compare with gutenberg block registration. // $should_register = apply_filters( 'activitypub/transformers/is_transformer_enabled', true, $transformer_instance ); @@ -206,7 +206,7 @@ class Transformers_Manager { * * @since version_number_transformer_management_placeholder * @access private - */ + */ private function init_transformers() { $builtin_transformers = [ 'post' @@ -219,7 +219,7 @@ class Transformers_Manager { $class_name = ucfirst( $transformer_name ); - $class_name = '\Activitypub\Transformer_' . $class_name; + $class_name = '\Activitypub\Transformer\\' . $class_name; $this->register( new $class_name() ); } @@ -248,7 +248,7 @@ class Transformers_Manager { * * @param string $transformers Optional. Transformer name. Default is null. * - * @return Transformer_Base|Transformer_Base[]|null Registered transformers. + * @return Base|Base[]|null Registered transformers. */ public function get_transformers( $transformer_name = null ) { if ( is_null( $this->transformers ) ) { @@ -264,7 +264,7 @@ class Transformers_Manager { /** * Get the mapped ActivityPub transformer. - * + * * Returns a new instance of the needed WordPress to ActivityPub transformer. * * @since version_number_transformer_management_placeholder @@ -272,7 +272,7 @@ class Transformers_Manager { * * @param WP_Post|WP_Comment $wp_post The WordPress Post/Comment. * - * @return Transformer_Base|null Registered transformers. + * @return \ActivityPub\Transformer\Base|null Registered transformers. */ public function get_transformer( $object ) { switch ( get_class( $object ) ) { @@ -289,5 +289,5 @@ class Transformers_Manager { return apply_filters( 'activitypub_transformer', null, $object, get_class( $object ) ); } } -} +} diff --git a/templates/post-json.php b/templates/post-json.php index d13b771..f213a66 100644 --- a/templates/post-json.php +++ b/templates/post-json.php @@ -2,7 +2,7 @@ // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited $post = \get_post(); -$transformer = \Activitypub\Transformers_Manager::instance()->get_transformer( $post ); +$transformer = \Activitypub\Transformer\Transformers_Manager::instance()->get_transformer( $post ); $json = \array_merge( array( '@context' => \Activitypub\get_context() ), $transformer->to_object()->to_array() ); diff --git a/templates/settings.php b/templates/settings.php index 91a35fa..19535b4 100644 --- a/templates/settings.php +++ b/templates/settings.php @@ -216,7 +216,7 @@ - +

@@ -237,19 +237,19 @@ return $object->name; }, $all_public_post_types); - $transformer_manager = \Activitypub\Transformers_Manager::instance(); + $transformer_manager = \Activitypub\Transformer\Transformers_Manager::instance(); $transformers = $transformer_manager->get_transformers(); ?> - +