From 359eabf67149448eee8f2086e9687078142b5537 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 3 Jul 2023 11:20:44 +0200 Subject: [PATCH 1/2] use collection instead of factory --- includes/activity/class-activity.php | 165 ++++++++++++++++++ includes/activity/class-actor.php | 8 + includes/class-activity-dispatcher.php | 2 +- includes/class-activitypub.php | 2 +- includes/class-http.php | 4 +- includes/class-scheduler.php | 3 +- includes/class-signature.php | 6 +- includes/class-webfinger.php | 2 +- .../class-users.php} | 4 +- includes/functions.php | 4 +- includes/model/class-application-user.php | 4 +- includes/model/class-blog-user.php | 4 +- includes/model/class-post.php | 4 +- includes/model/class-user.php | 4 +- includes/peer/class-users.php | 67 ------- includes/rest/class-followers.php | 4 +- includes/rest/class-following.php | 4 +- includes/rest/class-inbox.php | 6 +- includes/rest/class-outbox.php | 4 +- includes/rest/class-users.php | 7 +- includes/rest/class-webfinger.php | 4 +- includes/table/class-followers.php | 4 +- includes/transformer/class-wp-user.php | 76 ++++++++ templates/admin-header.php | 2 +- templates/author-json.php | 2 +- templates/settings.php | 2 +- templates/welcome.php | 4 +- ...typub-rest-post-signature-verification.php | 4 +- 28 files changed, 295 insertions(+), 111 deletions(-) create mode 100644 includes/activity/class-activity.php rename includes/{class-user-factory.php => collection/class-users.php} (98%) delete mode 100644 includes/peer/class-users.php create mode 100644 includes/transformer/class-wp-user.php diff --git a/includes/activity/class-activity.php b/includes/activity/class-activity.php new file mode 100644 index 0000000..592bbc1 --- /dev/null +++ b/includes/activity/class-activity.php @@ -0,0 +1,165 @@ + 'as:manuallyApprovesFollowers', + 'PropertyValue' => 'schema:PropertyValue', + 'schema' => 'http://schema.org#', + 'pt' => 'https://joinpeertube.org/ns#', + 'toot' => 'http://joinmastodon.org/ns#', + 'value' => 'schema:value', + 'Hashtag' => 'as:Hashtag', + 'featured' => array( + '@id' => 'toot:featured', + '@type' => '@id', + ), + 'featuredTags' => array( + '@id' => 'toot:featuredTags', + '@type' => '@id', + ), + ), + ); + + /** + * The object's unique global identifier + * + * @see https://www.w3.org/TR/activitypub/#obj-id + * + * @var string + */ + protected $id; + + /** + * @var string + */ + protected $type = 'Activity'; + + /** + * The context within which the object exists or an activity was + * performed. + * The notion of "context" used is intentionally vague. + * The intended function is to serve as a means of grouping objects + * and activities that share a common originating context or + * purpose. An example could be all activities relating to a common + * project or event. + * + * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-context + * + * @var string + * | ObjectType + * | Link + * | null + */ + protected $context = self::CONTEXT; + + /** + * Describes the direct object of the activity. + * For instance, in the activity "John added a movie to his + * wishlist", the object of the activity is the movie added. + * + * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-object-term + * + * @var string + * | ObjectType + * | Link + * | null + */ + protected $object; + + /** + * Describes one or more entities that either performed or are + * expected to perform the activity. + * Any single activity can have multiple actors. + * The actor MAY be specified using an indirect Link. + * + * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-actor + * + * @var string + * | \ActivityPhp\Type\Extended\AbstractActor + * | array + * | array + * | Link + */ + protected $actor; + + /** + * The indirect object, or target, of the activity. + * The precise meaning of the target is largely dependent on the + * type of action being described but will often be the object of + * the English preposition "to". + * For instance, in the activity "John added a movie to his + * wishlist", the target of the activity is John's wishlist. + * An activity can have more than one target. + * + * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-target + * + * @var string + * | ObjectType + * | array + * | Link + * | array + */ + protected $target; + + /** + * Describes the result of the activity. + * For instance, if a particular action results in the creation of + * a new resource, the result property can be used to describe + * that new resource. + * + * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-result + * + * @var string + * | ObjectType + * | Link + * | null + */ + protected $result; + + /** + * An indirect object of the activity from which the + * activity is directed. + * The precise meaning of the origin is the object of the English + * preposition "from". + * For instance, in the activity "John moved an item to List B + * from List A", the origin of the activity is "List A". + * + * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-origin + * + * @var string + * | ObjectType + * | Link + * | null + */ + protected $origin; + + /** + * One or more objects used (or to be used) in the completion of an + * Activity. + * + * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-instrument + * + * @var string + * | ObjectType + * | Link + * | null + */ + protected $instrument; +} diff --git a/includes/activity/class-actor.php b/includes/activity/class-actor.php index 202783f..fabd653 100644 --- a/includes/activity/class-actor.php +++ b/includes/activity/class-actor.php @@ -7,6 +7,14 @@ namespace Activitypub\Activity; +/** + * \Activitypub\Activity\Actor is an implementation of + * one an Activity Streams Actor. + * + * Represents an individual actor. + * + * @see https://www.w3.org/TR/activitystreams-vocabulary/#actor-types + */ class Actor extends Base_Object { /** * @var string diff --git a/includes/class-activity-dispatcher.php b/includes/class-activity-dispatcher.php index 00ffd48..c7862c0 100644 --- a/includes/class-activity-dispatcher.php +++ b/includes/class-activity-dispatcher.php @@ -3,7 +3,7 @@ namespace Activitypub; use Activitypub\Model\Post; use Activitypub\Model\Activity; -use Activitypub\User_Factory; +use Activitypub\Collection\Users; use Activitypub\Collection\Followers; use function Activitypub\safe_remote_post; diff --git a/includes/class-activitypub.php b/includes/class-activitypub.php index cd84dc1..3b4d68a 100644 --- a/includes/class-activitypub.php +++ b/includes/class-activitypub.php @@ -82,7 +82,7 @@ class Activitypub { $json_template = false; // check if user can publish posts - if ( \is_author() && ! User_Factory::get_by_id( \get_the_author_meta( 'ID' ) ) ) { + if ( \is_author() && ! Users::get_by_id( \get_the_author_meta( 'ID' ) ) ) { return $template; } diff --git a/includes/class-http.php b/includes/class-http.php index 240e5ea..dd19f9b 100644 --- a/includes/class-http.php +++ b/includes/class-http.php @@ -2,7 +2,7 @@ namespace Activitypub; use WP_Error; -use Activitypub\User_Factory; +use Activitypub\Collection\Users; /** * ActivityPub HTTP Class @@ -63,7 +63,7 @@ class Http { */ public static function get( $url ) { $date = \gmdate( 'D, d M Y H:i:s T' ); - $signature = Signature::generate_signature( User_Factory::APPLICATION_USER_ID, 'get', $url, $date ); + $signature = Signature::generate_signature( Users::APPLICATION_USER_ID, 'get', $url, $date ); $wp_version = \get_bloginfo( 'version' ); $user_agent = \apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version . '; ' . \get_bloginfo( 'url' ) ); diff --git a/includes/class-scheduler.php b/includes/class-scheduler.php index ddb68e1..ed0dbda 100644 --- a/includes/class-scheduler.php +++ b/includes/class-scheduler.php @@ -3,6 +3,7 @@ namespace Activitypub; use Activitypub\Model\Post; +use Activitypub\Collection\Users; use Activitypub\Collection\Followers; /** @@ -82,7 +83,7 @@ class Scheduler { return; } - $activitypub_post = new Post( $post, Users::BLOG_USER_ID ); + $activitypub_post = new Post( $post ); \wp_schedule_single_event( \time(), diff --git a/includes/class-signature.php b/includes/class-signature.php index b9666cc..b7c98fc 100644 --- a/includes/class-signature.php +++ b/includes/class-signature.php @@ -5,7 +5,7 @@ use WP_Error; use DateTime; use DateTimeZone; use Activitypub\Model\User; -use Activitypub\User_Factory; +use Activitypub\Collection\Users; /** * ActivityPub Signature Class @@ -106,7 +106,7 @@ class Signature { * @return string The signature. */ public static function generate_signature( $user_id, $http_method, $url, $date, $digest = null ) { - $user = User_Factory::get_by_id( $user_id ); + $user = Users::get_by_id( $user_id ); $key = $user->get__private_key(); $url_parts = \wp_parse_url( $url ); @@ -136,7 +136,7 @@ class Signature { \openssl_sign( $signed_string, $signature, $key, \OPENSSL_ALGO_SHA256 ); $signature = \base64_encode( $signature ); // phpcs:ignore - $user = User_Factory::get_by_id( $user_id ); + $user = Users::get_by_id( $user_id ); $key_id = $user->get_url() . '#main-key'; if ( ! empty( $digest ) ) { diff --git a/includes/class-webfinger.php b/includes/class-webfinger.php index 958f544..4a3a1a6 100644 --- a/includes/class-webfinger.php +++ b/includes/class-webfinger.php @@ -24,7 +24,7 @@ class Webfinger { return \get_webfinger_resource( $user_id, false ); } - $user = User_Factory::get_by_id( $user_id ); + $user = Users::get_by_id( $user_id ); if ( ! $user ) { return ''; } diff --git a/includes/class-user-factory.php b/includes/collection/class-users.php similarity index 98% rename from includes/class-user-factory.php rename to includes/collection/class-users.php index 8cc9f26..62b4264 100644 --- a/includes/class-user-factory.php +++ b/includes/collection/class-users.php @@ -1,5 +1,5 @@ get_user_id() ); + $user = Users::get_by_id( $this->get_user_id() ); return $user->get_url(); } diff --git a/includes/model/class-user.php b/includes/model/class-user.php index 10d10d6..c66e3d8 100644 --- a/includes/model/class-user.php +++ b/includes/model/class-user.php @@ -5,7 +5,7 @@ use WP_Query; use WP_Error; use Activitypub\Signature; use Activitypub\Model\User; -use Activitypub\User_Factory; +use Activitypub\Collection\Users; use Activitypub\Activity\Actor; use function Activitypub\is_user_disabled; @@ -13,7 +13,7 @@ use function Activitypub\get_rest_url_by_path; class User extends Actor { /** - * The User-ID + * The local User-ID (WP_User). * * @var int */ diff --git a/includes/peer/class-users.php b/includes/peer/class-users.php deleted file mode 100644 index fd9c7b8..0000000 --- a/includes/peer/class-users.php +++ /dev/null @@ -1,67 +0,0 @@ -wp_rewrite_rules(); - - // not using rewrite rules, and 'author=N' method failed, so we're out of options - if ( empty( $rewrite ) ) { - return 0; - } - - // generate rewrite rule for the author url - $author_rewrite = $wp_rewrite->get_author_permastruct(); - $author_regexp = \str_replace( '%author%', '', $author_rewrite ); - - // match the rewrite rule with the passed url - if ( \preg_match( '/https?:\/\/(.+)' . \preg_quote( $author_regexp, '/' ) . '([^\/]+)/i', $url, $match ) ) { - $user = \get_user_by( 'slug', $match[2] ); - if ( $user ) { - return $user->ID; - } - } - - return 0; - } -} diff --git a/includes/rest/class-followers.php b/includes/rest/class-followers.php index 477393e..c359391 100644 --- a/includes/rest/class-followers.php +++ b/includes/rest/class-followers.php @@ -5,7 +5,7 @@ use WP_Error; use stdClass; use WP_REST_Server; use WP_REST_Response; -use Activitypub\User_Factory; +use Activitypub\Collection\Users; use Activitypub\Collection\Followers as FollowerCollection; use function Activitypub\get_rest_url_by_path; @@ -52,7 +52,7 @@ class Followers { */ public static function get( $request ) { $user_id = $request->get_param( 'user_id' ); - $user = User_Factory::get_by_various( $user_id ); + $user = Users::get_by_various( $user_id ); if ( is_wp_error( $user ) ) { return $user; diff --git a/includes/rest/class-following.php b/includes/rest/class-following.php index 6f13482..10f4bed 100644 --- a/includes/rest/class-following.php +++ b/includes/rest/class-following.php @@ -1,7 +1,7 @@ get_param( 'user_id' ); - $user = User_Factory::get_by_various( $user_id ); + $user = Users::get_by_various( $user_id ); if ( is_wp_error( $user ) ) { return $user; diff --git a/includes/rest/class-inbox.php b/includes/rest/class-inbox.php index b8d75c9..eee740c 100644 --- a/includes/rest/class-inbox.php +++ b/includes/rest/class-inbox.php @@ -4,7 +4,7 @@ namespace Activitypub\Rest; use WP_Error; use WP_REST_Server; use WP_REST_Response; -use Activitypub\User_Factory; +use Activitypub\Collection\Users; use Activitypub\Model\Activity; use function Activitypub\get_context; @@ -74,7 +74,7 @@ class Inbox { */ public static function user_inbox_get( $request ) { $user_id = $request->get_param( 'user_id' ); - $user = User_Factory::get_by_various( $user_id ); + $user = Users::get_by_various( $user_id ); if ( is_wp_error( $user ) ) { return $user; @@ -126,7 +126,7 @@ class Inbox { public static function user_inbox_post( $request ) { $user_id = $request->get_param( 'user_id' ); - $user = User_Factory::get_by_various( $user_id ); + $user = Users::get_by_various( $user_id ); if ( is_wp_error( $user ) ) { return $user; diff --git a/includes/rest/class-outbox.php b/includes/rest/class-outbox.php index 1dc05c7..3df982f 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\User_Factory; +use Activitypub\Collection\Users; use Activitypub\Model\Post; use Activitypub\Model\Activity; @@ -53,7 +53,7 @@ class Outbox { */ public static function user_outbox_get( $request ) { $user_id = $request->get_param( 'user_id' ); - $user = User_Factory::get_by_various( $user_id ); + $user = Users::get_by_various( $user_id ); if ( is_wp_error( $user ) ) { return $user; diff --git a/includes/rest/class-users.php b/includes/rest/class-users.php index 1dd08f8..dac7792 100644 --- a/includes/rest/class-users.php +++ b/includes/rest/class-users.php @@ -4,7 +4,8 @@ namespace Activitypub\Rest; use WP_Error; use WP_REST_Server; use WP_REST_Response; -use Activitypub\User_Factory; +use \Activitypub\Model\Activity; +use Activitypub\Collection\User_Collection; use function Activitypub\is_activitypub_request; @@ -50,7 +51,7 @@ class Users { */ public static function get( $request ) { $user_id = $request->get_param( 'user_id' ); - $user = User_Factory::get_by_various( $user_id ); + $user = User_Collection::get_by_various( $user_id ); if ( is_wp_error( $user ) ) { return $user; @@ -68,7 +69,7 @@ class Users { \do_action( 'activitypub_outbox_pre' ); $user->set_context( - \Activitypub\Model\Activity::CONTEXT + Activity::CONTEXT ); $json = $user->to_array(); diff --git a/includes/rest/class-webfinger.php b/includes/rest/class-webfinger.php index f124889..1dc79c9 100644 --- a/includes/rest/class-webfinger.php +++ b/includes/rest/class-webfinger.php @@ -3,7 +3,7 @@ namespace Activitypub\Rest; use WP_Error; use WP_REST_Response; -use Activitypub\User_Factory; +use Activitypub\Collection\Users; /** * ActivityPub WebFinger REST-Class @@ -47,7 +47,7 @@ class Webfinger { */ public static function webfinger( $request ) { $resource = $request->get_param( 'resource' ); - $user = User_Factory::get_by_resource( $resource ); + $user = Users::get_by_resource( $resource ); if ( is_wp_error( $user ) ) { return $user; diff --git a/includes/table/class-followers.php b/includes/table/class-followers.php index f16a479..93d9456 100644 --- a/includes/table/class-followers.php +++ b/includes/table/class-followers.php @@ -2,7 +2,7 @@ namespace Activitypub\Table; use WP_List_Table; -use Activitypub\User_Factory; +use Activitypub\Collection\Users; use Activitypub\Collection\Followers as FollowerCollection; if ( ! \class_exists( '\WP_List_Table' ) ) { @@ -14,7 +14,7 @@ class Followers extends WP_List_Table { public function __construct() { if ( get_current_screen()->id === 'settings_page_activitypub' ) { - $this->user_id = User_Factory::BLOG_USER_ID; + $this->user_id = Users::BLOG_USER_ID; } else { $this->user_id = \get_current_user_id(); } diff --git a/includes/transformer/class-wp-user.php b/includes/transformer/class-wp-user.php new file mode 100644 index 0000000..083b119 --- /dev/null +++ b/includes/transformer/class-wp-user.php @@ -0,0 +1,76 @@ +wp_user = $wp_user; + } + + public function to_user() { + $wp_user = $this->wp_user; + if ( + is_user_disabled( $user->ID ) || + ! get_user_by( 'id', $user->ID ) + ) { + return new WP_Error( + 'activitypub_user_not_found', + \__( 'User not found', 'activitypub' ), + array( 'status' => 404 ) + ); + } + + $user = new User(); + + $user->setwp_user->ID( \esc_url( \get_author_posts_url( $wp_user->ID ) ) ); + $user->set_url( \esc_url( \get_author_posts_url( $wp_user->ID ) ) ); + $user->set_summary( $this->get_summary() ); + $user->set_name( \esc_attr( $wp_user->display_name ) ); + $user->set_preferred_username( \esc_attr( $wp_user->login ) ); + + $user->set_icon( $this->get_icon() ); + $user->set_image( $this->get_image() ); + + return $user; + } + + public function get_summary() { + $description = get_user_meta( $this->wp_user->ID, 'activitypub_user_description', true ); + if ( empty( $description ) ) { + $description = $this->wp_user->description; + } + return \wpautop( \wp_kses( $description, 'default' ) ); + } + + public function get_icon() { + $icon = \esc_url( + \get_avatar_url( + $this->wp_user->ID, + array( 'size' => 120 ) + ) + ); + + return array( + 'type' => 'Image', + 'url' => $icon, + ); + } + + public function get_image() { + if ( \has_header_image() ) { + $image = \esc_url( \get_header_image() ); + return array( + 'type' => 'Image', + 'url' => $image, + ); + } + + return null; + } +} diff --git a/templates/admin-header.php b/templates/admin-header.php index f2e7ed5..3b40468 100644 --- a/templates/admin-header.php +++ b/templates/admin-header.php @@ -12,7 +12,7 @@ - + diff --git a/templates/author-json.php b/templates/author-json.php index 3defd98..6c5f8ad 100644 --- a/templates/author-json.php +++ b/templates/author-json.php @@ -1,5 +1,5 @@ set_context( \Activitypub\Model\Activity::CONTEXT diff --git a/templates/settings.php b/templates/settings.php index 162ea02..b587b9e 100644 --- a/templates/settings.php +++ b/templates/settings.php @@ -31,7 +31,7 @@
- +

diff --git a/templates/welcome.php b/templates/welcome.php index 0bce61c..02e8be3 100644 --- a/templates/welcome.php +++ b/templates/welcome.php @@ -15,7 +15,7 @@

- +

@@ -44,7 +44,7 @@

ID ); + $user = \Activitypub\Collection\Users::get_by_id( wp_get_current_user()->ID ); echo wp_kses( \sprintf( // translators: diff --git a/tests/test-class-activitypub-rest-post-signature-verification.php b/tests/test-class-activitypub-rest-post-signature-verification.php index 3ee895e..f39927d 100644 --- a/tests/test-class-activitypub-rest-post-signature-verification.php +++ b/tests/test-class-activitypub-rest-post-signature-verification.php @@ -42,7 +42,7 @@ class Test_Activitypub_Signature_Verification extends WP_UnitTestCase { $signed_headers = $signature_block['headers']; $signed_data = Activitypub\Signature::get_signed_data( $signed_headers, $signature_block, $headers ); - $user = Activitypub\User_Factory::get_by_id( 1 ); + $user = Activitypub\Collection\Users::get_by_id( 1 ); $public_key = $user->get__public_key(); @@ -55,7 +55,7 @@ class Test_Activitypub_Signature_Verification extends WP_UnitTestCase { add_filter( 'pre_get_remote_metadata_by_actor', function( $json, $actor ) { - $user = Activitypub\User_Factory::get_by_id( 1 ); + $user = Activitypub\Collection\Users::get_by_id( 1 ); $public_key = $user->get__public_key(); // return ActivityPub Profile with signature return array( From 493b8ffad5925539511718c616e7ab0a1ddcbdba Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 3 Jul 2023 17:59:42 +0200 Subject: [PATCH 2/2] use transformer instead of post-model --- includes/activity/class-activity.php | 38 ++ includes/activity/class-base-object.php | 15 + includes/class-activity-dispatcher.php | 96 ++-- includes/class-activitypub.php | 1 + includes/class-admin.php | 2 - includes/class-scheduler.php | 8 +- includes/collection/class-followers.php | 2 +- includes/model/class-activity.php | 244 ---------- includes/model/class-user.php | 1 - includes/rest/class-inbox.php | 2 +- includes/rest/class-outbox.php | 20 +- includes/rest/class-users.php | 4 +- .../{model => transformer}/class-post.php | 420 ++++++------------ includes/transformer/class-wp-user.php | 76 ---- templates/author-json.php | 2 +- templates/blog-json.php | 2 +- templates/post-json.php | 4 +- ...-class-activitypub-activity-dispatcher.php | 10 +- tests/test-class-activitypub-activity.php | 7 +- tests/test-class-activitypub-post.php | 4 +- ...typub-rest-post-signature-verification.php | 14 +- 21 files changed, 282 insertions(+), 690 deletions(-) delete mode 100644 includes/model/class-activity.php rename includes/{model => transformer}/class-post.php (55%) delete mode 100644 includes/transformer/class-wp-user.php diff --git a/includes/activity/class-activity.php b/includes/activity/class-activity.php index 592bbc1..a1bd3c5 100644 --- a/includes/activity/class-activity.php +++ b/includes/activity/class-activity.php @@ -7,6 +7,8 @@ namespace Activitypub\Activity; +use Activitypub\Activity\Base_Object; + /** * \Activitypub\Activity\Activity implements the common * attributes of an Activity. @@ -162,4 +164,40 @@ class Activity extends Base_Object { * | null */ protected $instrument; + + /** + * Set the object and copy Object properties to the Activity. + * + * Any to, bto, cc, bcc, and audience properties specified on the object + * MUST be copied over to the new Create activity by the server. + * + * @see https://www.w3.org/TR/activitypub/#object-without-create + * + * @param \Activitypub\Activity\Base_Object $object + * + * @return void + */ + public function set_object( Base_Object $object ) { + parent::set_object( $object ); + + foreach ( array( 'to', 'bto', 'cc', 'bcc', 'audience' ) as $i ) { + $this->set( $i, $object->get( $i ) ); + } + + if ( $object->get_published() && ! $this->get_published() ) { + $this->set( 'published', $object->get_published() ); + } + + if ( $object->get_updated() && ! $this->get_updated() ) { + $this->set( 'updated', $object->get_updated() ); + } + + if ( $object->attributed_to() && ! $this->get_actor() ) { + $this->set( 'actor', $object->attributed_to() ); + } + + if ( $object->get_id() && ! $this->get_id() ) { + $this->set( 'id', $object->get_id() . '#activity' ); + } + } } diff --git a/includes/activity/class-base-object.php b/includes/activity/class-base-object.php index 4343782..151ebf1 100644 --- a/includes/activity/class-base-object.php +++ b/includes/activity/class-base-object.php @@ -604,6 +604,10 @@ class Base_Object { $value = call_user_func( array( $this, 'get_' . $key ) ); } + if ( is_object( $value ) ) { + $value = $value->to_array(); + } + // if value is still empty, ignore it for the array and continue. if ( isset( $value ) ) { $array[ snake_to_camel_case( $key ) ] = $value; @@ -625,4 +629,15 @@ class Base_Object { return $array; } + + /** + * Convert Object to JSON. + * + * @return string The JSON string. + */ + public function to_json() { + $array = $this->to_array(); + + return \wp_json_encode( $array ); + } } diff --git a/includes/class-activity-dispatcher.php b/includes/class-activity-dispatcher.php index c7862c0..2a5444a 100644 --- a/includes/class-activity-dispatcher.php +++ b/includes/class-activity-dispatcher.php @@ -1,10 +1,11 @@ from_post( $activitypub_post ); + $object = Post::transform( $post )->to_object(); - $user_id = $activitypub_post->get_user_id(); + $activity = new Activity(); + $activity->set_type( $type ); + $activity->set_object( $object ); + + $user_id = $post->post_author; $follower_inboxes = Followers::get_inboxes( $user_id ); - $mentioned_inboxes = Mention::get_inboxes( $activitypub_activity->get_cc() ); + $mentioned_inboxes = Mention::get_inboxes( $activity->get_cc() ); $inboxes = array_merge( $follower_inboxes, $mentioned_inboxes ); $inboxes = array_unique( $inboxes ); - foreach ( $inboxes as $inbox ) { - $activity = $activitypub_activity->to_json(); + $array = $activity->to_json(); - safe_remote_post( $inbox, $activity, $user_id ); + foreach ( $inboxes as $inbox ) { + safe_remote_post( $inbox, $array, $user_id ); + } + } + + /** + * Send Activities to followers and mentioned users. + * + * @param WP_Post $post The ActivityPub Post. + * @param string $type The Activity-Type. + * + * @return void + */ + public static function send_blog_activity( WP_Post $post, $type ) { + // check if a migration is needed before sending new posts + Migration::maybe_migrate(); + + $user = Users::get_by_id( Users::BLOG_USER_ID ); + + $object = Post::transform( $post )->to_object(); + $object->set_attributed_to( $user->get_url() ); + + $activity = new Activity(); + $activity->set_type( $type ); + $activity->set_object( $object ); + + $follower_inboxes = Followers::get_inboxes( $user->get__id() ); + $mentioned_inboxes = Mention::get_inboxes( $activity->get_cc() ); + + $inboxes = array_merge( $follower_inboxes, $mentioned_inboxes ); + $inboxes = array_unique( $inboxes ); + + $array = $activity->to_array(); + + foreach ( $inboxes as $inbox ) { + safe_remote_post( $inbox, $array, $user_id ); } } } diff --git a/includes/class-activitypub.php b/includes/class-activitypub.php index 3b4d68a..507da58 100644 --- a/includes/class-activitypub.php +++ b/includes/class-activitypub.php @@ -2,6 +2,7 @@ namespace Activitypub; use Activitypub\Signature; +use Activitypub\Collection\Users; /** * ActivityPub Class diff --git a/includes/class-admin.php b/includes/class-admin.php index 1a94aa3..647805a 100644 --- a/includes/class-admin.php +++ b/includes/class-admin.php @@ -1,8 +1,6 @@ 'as:manuallyApprovesFollowers', - 'PropertyValue' => 'schema:PropertyValue', - 'schema' => 'http://schema.org#', - 'pt' => 'https://joinpeertube.org/ns#', - 'toot' => 'http://joinmastodon.org/ns#', - 'value' => 'schema:value', - 'Hashtag' => 'as:Hashtag', - 'featured' => array( - '@id' => 'toot:featured', - '@type' => '@id', - ), - 'featuredTags' => array( - '@id' => 'toot:featuredTags', - '@type' => '@id', - ), - ), - ); - - /** - * The JSON-LD context. - * - * @var array - */ - private $context = self::CONTEXT; - - /** - * The published date. - * - * @var string - */ - private $published = ''; - - /** - * The Activity-ID. - * - * @var string - */ - private $id = ''; - - /** - * The Activity-Type. - * - * @var string - */ - private $type = 'Create'; - - /** - * The Activity-Actor. - * - * @var string - */ - private $actor = ''; - - /** - * The Audience. - * - * @var array - */ - private $to = array( 'https://www.w3.org/ns/activitystreams#Public' ); - - /** - * The CC. - * - * @var array - */ - private $cc = array(); - - /** - * The Activity-Object. - * - * @var array - */ - private $object = null; - - /** - * The Class-Constructor. - * - * @param string $type The Activity-Type. - * @param boolean $context The JSON-LD context. - */ - public function __construct( $type = 'Create', $context = true ) { - if ( true !== $context ) { - $this->context = null; - } - - $this->type = \ucfirst( $type ); - $this->published = \gmdate( 'Y-m-d\TH:i:s\Z', \time() ); - } - - /** - * Magic Getter/Setter - * - * @param string $method The method name. - * @param string $params The method params. - * - * @return mixed The value. - */ - public function __call( $method, $params ) { - $var = \strtolower( \substr( $method, 4 ) ); - - if ( \strncasecmp( $method, 'get', 3 ) === 0 ) { - return $this->$var; - } - - if ( \strncasecmp( $method, 'set', 3 ) === 0 ) { - $this->$var = $params[0]; - } - - if ( \strncasecmp( $method, 'add', 3 ) === 0 ) { - if ( ! is_array( $this->$var ) ) { - $this->$var = $params[0]; - } - - if ( is_array( $params[0] ) ) { - $this->$var = array_merge( $this->$var, $params[0] ); - } else { - array_push( $this->$var, $params[0] ); - } - - $this->$var = array_unique( $this->$var ); - } - } - - /** - * Convert from a Post-Object. - * - * @param Post $post The Post-Object. - * - * @return void - */ - public function from_post( Post $post ) { - $this->object = $post->to_array(); - - if ( isset( $object['published'] ) ) { - $this->published = $object['published']; - } - - $path = sprintf( 'users/%d/followers', intval( $post->get_post_author() ) ); - $this->add_to( get_rest_url_by_path( $path ) ); - - if ( isset( $this->object['attributedTo'] ) ) { - $this->actor = $this->object['attributedTo']; - } - - foreach ( $post->get_tags() as $tag ) { - if ( 'Mention' === $tag['type'] ) { - $this->add_cc( $tag['href'] ); - } - } - - $type = \strtolower( $this->type ); - - if ( isset( $this->object['id'] ) ) { - $this->id = add_query_arg( 'activity', $type, $this->object['id'] ); - } - } - - public function from_comment( $object ) { - - } - - public function to_comment() { - - } - - public function from_remote_array( $array ) { - - } - - /** - * Convert to an Array. - * - * @return array The Array. - */ - public function to_array() { - $array = array_filter( \get_object_vars( $this ) ); - - if ( $this->context ) { - $array = array( '@context' => $this->context ) + $array; - } - - unset( $array['context'] ); - - return $array; - } - - /** - * Convert to JSON - * - * @return string The JSON. - */ - public function to_json() { - return \wp_json_encode( $this->to_array(), \JSON_HEX_TAG | \JSON_HEX_AMP | \JSON_HEX_QUOT ); - } - - /** - * Convert to a Simple Array. - * - * @return string The array. - */ - public function to_simple_array() { - $activity = array( - '@context' => $this->context, - 'type' => $this->type, - 'actor' => $this->actor, - 'object' => $this->object, - 'to' => $this->to, - 'cc' => $this->cc, - ); - - if ( $this->id ) { - $activity['id'] = $this->id; - } - - return $activity; - } - - /** - * Convert to a Simple JSON. - * - * @return string The JSON. - */ - public function to_simple_json() { - return \wp_json_encode( $this->to_simple_array(), \JSON_HEX_TAG | \JSON_HEX_AMP | \JSON_HEX_QUOT ); - } -} diff --git a/includes/model/class-user.php b/includes/model/class-user.php index c66e3d8..d641497 100644 --- a/includes/model/class-user.php +++ b/includes/model/class-user.php @@ -4,7 +4,6 @@ namespace Activitypub\Model; use WP_Query; use WP_Error; use Activitypub\Signature; -use Activitypub\Model\User; use Activitypub\Collection\Users; use Activitypub\Activity\Actor; diff --git a/includes/rest/class-inbox.php b/includes/rest/class-inbox.php index eee740c..4f0c3c3 100644 --- a/includes/rest/class-inbox.php +++ b/includes/rest/class-inbox.php @@ -5,7 +5,7 @@ use WP_Error; use WP_REST_Server; use WP_REST_Response; use Activitypub\Collection\Users; -use Activitypub\Model\Activity; +use Activitypub\Activity\Activity; use function Activitypub\get_context; use function Activitypub\url_to_authorid; diff --git a/includes/rest/class-outbox.php b/includes/rest/class-outbox.php index 3df982f..91af46d 100644 --- a/includes/rest/class-outbox.php +++ b/includes/rest/class-outbox.php @@ -5,9 +5,9 @@ use stdClass; use WP_Error; use WP_REST_Server; use WP_REST_Response; +use Activitypub\Activity\Activity; use Activitypub\Collection\Users; -use Activitypub\Model\Post; -use Activitypub\Model\Activity; +use Activitypub\Transformer\Post; use function Activitypub\get_context; use function Activitypub\get_rest_url_by_path; @@ -73,9 +73,9 @@ class Outbox { $json->{'@context'} = get_context(); $json->id = \home_url( \add_query_arg( null, null ) ); $json->generator = 'http://wordpress.org/?v=' . \get_bloginfo_rss( 'version' ); - $json->actor = $user->get_id(); + //$json->actor = $user->get_id(); $json->type = 'OrderedCollectionPage'; - $json->partOf = get_rest_url_by_path( sprintf( 'users/%d/outbox', $user->get__id() ) ); // phpcs:ignore + $json->partOf = get_rest_url_by_path( sprintf( 'users/%d/outbox', $user_id ) ); // phpcs:ignore $json->totalItems = 0; // phpcs:ignore // phpcs:ignore @@ -97,18 +97,20 @@ class Outbox { $posts = \get_posts( array( 'posts_per_page' => 10, - 'author' => $user->get__id(), + 'author' => $user_id, 'offset' => ( $page - 1 ) * 10, 'post_type' => $post_types, ) ); foreach ( $posts as $post ) { - $activitypub_post = new Post( $post ); - $activitypub_activity = new Activity( 'Create', false ); + $post = Post::transform( $post )->to_object(); + $activity = new Activity(); + $activity->set_type( 'Create' ); + $activity->set_context( null ); + $activity->set_object( $post ); - $activitypub_activity->from_post( $activitypub_post ); - $json->orderedItems[] = $activitypub_activity->to_array(); // phpcs:ignore + $json->orderedItems[] = $activity->to_array(); // phpcs:ignore } } diff --git a/includes/rest/class-users.php b/includes/rest/class-users.php index dac7792..2017036 100644 --- a/includes/rest/class-users.php +++ b/includes/rest/class-users.php @@ -4,8 +4,8 @@ namespace Activitypub\Rest; use WP_Error; use WP_REST_Server; use WP_REST_Response; -use \Activitypub\Model\Activity; -use Activitypub\Collection\User_Collection; +use \Activitypub\Activity\Activity; +use Activitypub\Collection\Users as User_Collection; use function Activitypub\is_activitypub_request; diff --git a/includes/model/class-post.php b/includes/transformer/class-post.php similarity index 55% rename from includes/model/class-post.php rename to includes/transformer/class-post.php index 1aa862a..ca35949 100644 --- a/includes/model/class-post.php +++ b/includes/transformer/class-post.php @@ -1,84 +1,37 @@ array( 'href' => array(), 'title' => array(), @@ -126,185 +79,70 @@ class Post { ); /** - * List of audience + * Static function to Transform a WP_Post Object. * - * Also used for visibility + * This helps to chain the output of the Transformer. * - * @var array - */ - private $to = array( 'https://www.w3.org/ns/activitystreams#Public' ); - - /** - * List of audience - * - * Also used for visibility - * - * @var array - */ - private $cc = array(); - - /** - * Constructor - * - * @param WP_Post $post - * @param int $post_author - */ - public function __construct( $post, $post_author = null ) { - $this->post = \get_post( $post ); - - if ( $post_author ) { - $this->post_author = $post_author; - } else { - $this->post_author = $this->post->post_author; - } - - $path = sprintf( 'users/%d/followers', intval( $this->get_post_author() ) ); - $this->add_to( get_rest_url_by_path( $path ) ); - } - - /** - * Magic function to implement getter and setter - * - * @param string $method - * @param string $params + * @param WP_Post $wp_post The WP_Post object * * @return void */ - public function __call( $method, $params ) { - $var = \strtolower( \substr( $method, 4 ) ); - - if ( \strncasecmp( $method, 'get', 3 ) === 0 ) { - if ( empty( $this->$var ) && ! empty( $this->post->$var ) ) { - return $this->post->$var; - } - return $this->$var; - } - - if ( \strncasecmp( $method, 'set', 3 ) === 0 ) { - $this->$var = $params[0]; - } - - if ( \strncasecmp( $method, 'add', 3 ) === 0 ) { - if ( ! is_array( $this->$var ) ) { - $this->$var = $params[0]; - } - - if ( is_array( $params[0] ) ) { - $this->$var = array_merge( $this->$var, $params[0] ); - } else { - array_push( $this->$var, $params[0] ); - } - - $this->$var = array_unique( $this->$var ); - } + public static function transform( WP_Post $wp_post ) { + return new self( $wp_post ); } /** - * Returns the User ID. * - * @return int the User ID. + * + * @param WP_Post $wp_post */ - public function get_user_id() { - return apply_filters( 'activitypub_post_user_id', $this->get_post_author(), $this->post ); + public function __construct( WP_Post $wp_post ) { + $this->wp_post = $wp_post; } /** - * Converts this Object into an Array. + * Transforms the WP_Post object to an ActivityPub Object * - * @return array the array representation of a Post. + * @see \Activitypub\Activity\Base_Object + * + * @return \Activitypub\Activity\Base_Object The ActivityPub Object */ - public function to_array() { - $post = $this->post; + public function to_object() { + $wp_post = $this->wp_post; + $object = new Base_Object(); - $array = array( - 'id' => $this->get_id(), - 'url' => $this->get_url(), - 'type' => $this->get_object_type(), - 'published' => \gmdate( 'Y-m-d\TH:i:s\Z', \strtotime( $post->post_date_gmt ) ), - 'attributedTo' => $this->get_actor(), - 'summary' => $this->get_summary(), - 'inReplyTo' => null, - 'content' => $this->get_content(), - 'contentMap' => array( + $object->set_id( \esc_url( \get_permalink( $wp_post->ID ) ) ); + $object->set_url( \esc_url( \get_permalink( $wp_post->ID ) ) ); + $object->set_type( $this->get_object_type() ); + $object->set_published( \gmdate( 'Y-m-d\TH:i:s\Z', \strtotime( $wp_post->post_date_gmt ) ) ); + $object->attributed_to( Users::get_by_id( $wp_post->post_author )->get_url() ); + $object->set_content( $this->get_content() ); + $object->set_content_map( + array( \strstr( \get_locale(), '_', true ) => $this->get_content(), - ), - 'to' => $this->get_to(), - 'cc' => $this->get_cc(), - 'attachment' => $this->get_attachments(), - 'tag' => $this->get_tags(), + ) ); + $path = sprintf( 'users/%d/followers', intval( $wp_post->post_author ) ); - return \apply_filters( 'activitypub_post', $array, $this->post ); + $object->set_to( + array( + 'https://www.w3.org/ns/activitystreams#Public', + get_rest_url_by_path( $path ), + ) + ); + $object->set_cc( $this->get_cc() ); + $object->set_attachment( $this->get_attachments() ); + $object->set_tag( $this->get_tags() ); + + return $object; } /** - * Returns the Actor of this Object. + * Generates all Image Attachments for a Post. * - * @return string The URL of the Actor. + * @return array The Image Attachments. */ - public function get_actor() { - $user = Users::get_by_id( $this->get_user_id() ); - - return $user->get_url(); - } - - /** - * Converts this Object into a JSON String - * - * @return string - */ - public function to_json() { - return \wp_json_encode( $this->to_array(), \JSON_HEX_TAG | \JSON_HEX_AMP | \JSON_HEX_QUOT ); - } - - /** - * Returns the URL of an Activity Object - * - * @return string - */ - public function get_url() { - if ( $this->url ) { - return $this->url; - } - - $post = $this->post; - - if ( 'trash' === get_post_status( $post ) ) { - $permalink = \get_post_meta( $post->ID, 'activitypub_canonical_url', true ); - } else { - $permalink = \get_permalink( $post ); - } - - $this->url = $permalink; - - return $permalink; - } - - /** - * Returns the ID of an Activity Object - * - * @return string - */ - public function get_id() { - if ( $this->id ) { - return $this->id; - } - - $this->id = $this->get_url(); - - return $this->id; - } - - /** - * Returns a list of Image Attachments - * - * @return array - */ - public function get_attachments() { - if ( $this->attachments ) { - return $this->attachments; - } - + protected function get_attachments() { $max_images = intval( \apply_filters( 'activitypub_max_image_attachments', \get_option( 'activitypub_max_image_attachments', ACTIVITYPUB_MAX_IMAGE_ATTACHMENTS ) ) ); $images = array(); @@ -314,7 +152,7 @@ class Post { return $images; } - $id = $this->post->ID; + $id = $this->wp_post->ID; $image_ids = array(); @@ -393,7 +231,7 @@ class Post { * * @return array|false Array of image data, or boolean false if no image is available. */ - public function get_image( $id, $image_size = 'full' ) { + protected function get_image( $id, $image_size = 'full' ) { /** * Hook into the image retrieval process. Before image retrieval. * @@ -416,64 +254,22 @@ class Post { } /** - * Returns a list of Tags, used in the Post + * Returns the ActivityStreams 2.0 Object-Type for a Post based on the + * settings and the Post-Type. * - * @return array - */ - public function get_tags() { - if ( $this->tags ) { - return $this->tags; - } - - $tags = array(); - - $post_tags = \get_the_tags( $this->post->ID ); - if ( $post_tags ) { - foreach ( $post_tags as $post_tag ) { - $tag = array( - 'type' => 'Hashtag', - 'href' => \get_tag_link( $post_tag->term_id ), - 'name' => '#' . $post_tag->slug, - ); - $tags[] = $tag; - } - } - - $mentions = apply_filters( 'activitypub_extract_mentions', array(), $this->post->post_content, $this ); - if ( $mentions ) { - foreach ( $mentions as $mention => $url ) { - $tag = array( - 'type' => 'Mention', - 'href' => $url, - 'name' => $mention, - ); - $tags[] = $tag; - } - } - - $this->tags = $tags; - - return $tags; - } - - /** - * Returns the as2 object-type for a given post + * @see https://www.w3.org/TR/activitystreams-vocabulary/#activity-types * - * @return string the object-type + * @return string The Object-Type. */ - public function get_object_type() { - if ( $this->object_type ) { - return $this->object_type; - } - + protected function get_object_type() { if ( 'wordpress-post-format' !== \get_option( 'activitypub_object_type', 'note' ) ) { return \ucfirst( \get_option( 'activitypub_object_type', 'note' ) ); } - $post_type = \get_post_type( $this->post ); + $post_type = \get_post_type( $this->wp_post ); switch ( $post_type ) { case 'post': - $post_format = \get_post_format( $this->post ); + $post_format = \get_post_format( $this->wp_post ); switch ( $post_format ) { case 'aside': case 'status': @@ -519,25 +315,78 @@ class Post { break; } - $this->object_type = $object_type; - return $object_type; } + /** + * 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(); + + $mentions = $this->get_mentions(); + if ( $mentions ) { + foreach ( $mentions as $mention => $url ) { + $cc[] = $url; + } + } + + return $cc; + } + + /** + * Returns a list of Tags, used in the Post. + * + * This includes Hash-Tags and Mentions. + * + * @return array The list of Tags. + */ + protected function get_tags() { + $tags = array(); + + $post_tags = \get_the_tags( $this->wp_post->ID ); + if ( $post_tags ) { + foreach ( $post_tags as $post_tag ) { + $tag = array( + 'type' => 'Hashtag', + 'href' => esc_url( \get_tag_link( $post_tag->term_id ) ), + 'name' => '#' . \esc_attr( $post_tag->slug ), + ); + $tags[] = $tag; + } + } + + $mentions = $this->get_mentions(); + if ( $mentions ) { + foreach ( $mentions as $mention => $url ) { + $tag = array( + 'type' => 'Mention', + 'href' => \esc_url( $url ), + 'name' => \esc_html( $mention ), + ); + $tags[] = $tag; + } + } + + return $tags; + } + /** * Returns the content for the ActivityPub Item. * - * @return string the content + * The content will be generated based on the user settings. + * + * @return string The content. */ - public function get_content() { + protected function get_content() { global $post; - if ( $this->content ) { - return $this->content; - } - // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited - $post = $this->post; + $post = $this->wp_post; $content = $this->get_post_content_template(); // Fill in the shortcodes. @@ -553,17 +402,15 @@ class Post { $content = \apply_filters( 'activitypub_the_content', $content, $post ); $content = \html_entity_decode( $content, \ENT_QUOTES, 'UTF-8' ); - $this->content = $content; - return $content; } /** * Gets the template to use to generate the content of the activitypub item. * - * @return string the template + * @return string The Template. */ - public function get_post_content_template() { + protected function get_post_content_template() { if ( 'excerpt' === \get_option( 'activitypub_post_content_type', 'content' ) ) { return "[ap_excerpt]\n\n[ap_permalink type=\"html\"]"; } @@ -578,4 +425,13 @@ class Post { return \get_option( 'activitypub_custom_post_content', ACTIVITYPUB_CUSTOM_POST_CONTENT ); } + + /** + * Helper function to get the @-Mentions from the post content. + * + * @return array The list of @-Mentions. + */ + protected function get_mentions() { + return apply_filters( 'activitypub_extract_mentions', array(), $this->wp_post->post_content, $this->wp_post ); + } } diff --git a/includes/transformer/class-wp-user.php b/includes/transformer/class-wp-user.php deleted file mode 100644 index 083b119..0000000 --- a/includes/transformer/class-wp-user.php +++ /dev/null @@ -1,76 +0,0 @@ -wp_user = $wp_user; - } - - public function to_user() { - $wp_user = $this->wp_user; - if ( - is_user_disabled( $user->ID ) || - ! get_user_by( 'id', $user->ID ) - ) { - return new WP_Error( - 'activitypub_user_not_found', - \__( 'User not found', 'activitypub' ), - array( 'status' => 404 ) - ); - } - - $user = new User(); - - $user->setwp_user->ID( \esc_url( \get_author_posts_url( $wp_user->ID ) ) ); - $user->set_url( \esc_url( \get_author_posts_url( $wp_user->ID ) ) ); - $user->set_summary( $this->get_summary() ); - $user->set_name( \esc_attr( $wp_user->display_name ) ); - $user->set_preferred_username( \esc_attr( $wp_user->login ) ); - - $user->set_icon( $this->get_icon() ); - $user->set_image( $this->get_image() ); - - return $user; - } - - public function get_summary() { - $description = get_user_meta( $this->wp_user->ID, 'activitypub_user_description', true ); - if ( empty( $description ) ) { - $description = $this->wp_user->description; - } - return \wpautop( \wp_kses( $description, 'default' ) ); - } - - public function get_icon() { - $icon = \esc_url( - \get_avatar_url( - $this->wp_user->ID, - array( 'size' => 120 ) - ) - ); - - return array( - 'type' => 'Image', - 'url' => $icon, - ); - } - - public function get_image() { - if ( \has_header_image() ) { - $image = \esc_url( \get_header_image() ); - return array( - 'type' => 'Image', - 'url' => $image, - ); - } - - return null; - } -} diff --git a/templates/author-json.php b/templates/author-json.php index 6c5f8ad..70fb43b 100644 --- a/templates/author-json.php +++ b/templates/author-json.php @@ -2,7 +2,7 @@ $user = \Activitypub\Collection\Users::get_by_id( \get_the_author_meta( 'ID' ) ); $user->set_context( - \Activitypub\Model\Activity::CONTEXT + \Activitypub\Activity\Activity::CONTEXT ); /* diff --git a/templates/blog-json.php b/templates/blog-json.php index 635e7d5..7ce6a27 100644 --- a/templates/blog-json.php +++ b/templates/blog-json.php @@ -2,7 +2,7 @@ $user = new \Activitypub\Model\Blog_User(); $user->set_context( - \Activitypub\Model\Activity::CONTEXT + \Activitypub\Activity\Activity::CONTEXT ); /* diff --git a/templates/post-json.php b/templates/post-json.php index 4c597d6..89467c4 100644 --- a/templates/post-json.php +++ b/templates/post-json.php @@ -2,8 +2,8 @@ // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited $post = \get_post(); -$activitypub_post = new \Activitypub\Model\Post( $post ); -$json = \array_merge( array( '@context' => \Activitypub\get_context() ), $activitypub_post->to_array() ); +$object = new \Activitypub\Transformer\Post( $post ); +$json = \array_merge( array( '@context' => \Activitypub\get_context() ), $object->to_object()->to_array() ); // filter output $json = \apply_filters( 'activitypub_json_post_array', $json ); diff --git a/tests/test-class-activitypub-activity-dispatcher.php b/tests/test-class-activitypub-activity-dispatcher.php index 61f8c2b..f028798 100644 --- a/tests/test-class-activitypub-activity-dispatcher.php +++ b/tests/test-class-activitypub-activity-dispatcher.php @@ -34,10 +34,7 @@ class Test_Activitypub_Activity_Dispatcher extends ActivityPub_TestCase_Cache_HT $pre_http_request = new MockAction(); add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 ); - $activitypub_post = new \Activitypub\Model\Post( $post ); - \Activitypub\Activity_Dispatcher::send_create_activity( $activitypub_post ); - - $this->assertNotEmpty( $activitypub_post->get_content() ); + \Activitypub\Activity_Dispatcher::send_user_activity( get_post( $post ), 'Create' ); $this->assertSame( 2, $pre_http_request->get_call_count() ); $all_args = $pre_http_request->get_args(); @@ -77,10 +74,7 @@ class Test_Activitypub_Activity_Dispatcher extends ActivityPub_TestCase_Cache_HT $pre_http_request = new MockAction(); add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 ); - $activitypub_post = new \Activitypub\Model\Post( $post ); - \Activitypub\Activity_Dispatcher::send_create_activity( $activitypub_post ); - - $this->assertNotEmpty( $activitypub_post->get_content() ); + \Activitypub\Activity_Dispatcher::send_user_activity( get_post( $post ), 'Create' ); $this->assertSame( 1, $pre_http_request->get_call_count() ); $all_args = $pre_http_request->get_args(); diff --git a/tests/test-class-activitypub-activity.php b/tests/test-class-activitypub-activity.php index 8262f6c..b25545c 100644 --- a/tests/test-class-activitypub-activity.php +++ b/tests/test-class-activitypub-activity.php @@ -17,10 +17,11 @@ class Test_Activitypub_Activity extends WP_UnitTestCase { 10 ); - $activitypub_post = new \Activitypub\Model\Post( $post ); + $activitypub_post = \Activitypub\Transformer\Post::transform( get_post( $post ) )->to_object(); - $activitypub_activity = new \Activitypub\Model\Activity( 'Create' ); - $activitypub_activity->from_post( $activitypub_post ); + $activitypub_activity = new \Activitypub\Activity\Activity(); + $activitypub_activity->set_type( 'Create' ); + $activitypub_activity->set_object( $activitypub_post ); $this->assertContains( \Activitypub\get_rest_url_by_path( 'users/1/followers' ), $activitypub_activity->get_to() ); $this->assertContains( 'https://example.com/alex', $activitypub_activity->get_cc() ); diff --git a/tests/test-class-activitypub-post.php b/tests/test-class-activitypub-post.php index 4f1c74e..e995afa 100644 --- a/tests/test-class-activitypub-post.php +++ b/tests/test-class-activitypub-post.php @@ -10,13 +10,13 @@ class Test_Activitypub_Post extends WP_UnitTestCase { $permalink = \get_permalink( $post ); - $activitypub_post = new \Activitypub\Model\Post( $post ); + $activitypub_post = \Activitypub\Transformer\Post::transform( get_post( $post ) )->to_object(); $this->assertEquals( $permalink, $activitypub_post->get_id() ); \wp_trash_post( $post ); - $activitypub_post = new \Activitypub\Model\Post( $post ); + $activitypub_post = \Activitypub\Transformer\Post::transform( get_post( $post ) )->to_object(); $this->assertEquals( $permalink, $activitypub_post->get_id() ); } diff --git a/tests/test-class-activitypub-rest-post-signature-verification.php b/tests/test-class-activitypub-rest-post-signature-verification.php index f39927d..97f78f9 100644 --- a/tests/test-class-activitypub-rest-post-signature-verification.php +++ b/tests/test-class-activitypub-rest-post-signature-verification.php @@ -10,9 +10,10 @@ class Test_Activitypub_Signature_Verification extends WP_UnitTestCase { ) ); $remote_actor = \get_author_posts_url( 2 ); - $activitypub_post = new \Activitypub\Model\Post( $post ); - $activitypub_activity = new Activitypub\Model\Activity( 'Create' ); - $activitypub_activity->from_post( $activitypub_post ); + $activitypub_post = \Activitypub\Transformer\Post::transform( get_post( $post ) )->to_object(); + $activitypub_activity = new Activitypub\Activity\Activity( 'Create' ); + $activitypub_activity->set_type( 'Create' ); + $activitypub_activity->set_object( $activitypub_post ); $activitypub_activity->add_cc( $remote_actor ); $activity = $activitypub_activity->to_json(); @@ -81,9 +82,10 @@ class Test_Activitypub_Signature_Verification extends WP_UnitTestCase { ); $remote_actor = \get_author_posts_url( 2 ); $remote_actor_inbox = Activitypub\get_rest_url_by_path( '/inbox' ); - $activitypub_post = new \Activitypub\Model\Post( $post ); - $activitypub_activity = new Activitypub\Model\Activity( 'Create' ); - $activitypub_activity->from_post( $activitypub_post ); + $activitypub_post = \Activitypub\Transformer\Post::transform( \get_post( $post ) )->to_object(); + $activitypub_activity = new Activitypub\Activity\Activity(); + $activitypub_activity->set_type( 'Create' ); + $activitypub_activity->set_object( $activitypub_post ); $activitypub_activity->add_cc( $remote_actor_inbox ); $activity = $activitypub_activity->to_json();