From 120d5714f818138378a71b844338856a8079a5bf Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 24 Sep 2018 20:47:15 +0200 Subject: [PATCH] basic outbox implementation --- README.md | 57 +++++++++- includes/class-activitypub-outbox.php | 103 +++++++++++++++++- includes/class-activitypub.php | 3 +- includes/functions.php | 1 + languages/activitypub.pot | 7 +- readme.txt | 57 +++++++++- templates/{author-profile.php => profile.php} | 8 +- 7 files changed, 219 insertions(+), 17 deletions(-) rename templates/{author-profile.php => profile.php} (89%) diff --git a/README.md b/README.md index 385e5d0..22fb483 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,64 @@ **Tags:** OStatus, fediverse, activitypub, activitystream **Requires at least:** 4.7 **Tested up to:** 4.9.8 -**Stable tag:** 1.0.0 +**Stable tag:** 0.0.1 **Requires PHP:** 5.3 **License:** MIT **License URI:** http://opensource.org/licenses/MIT The ActivityPub protocol is a decentralized social networking protocol based upon the ActivityStreams 2.0 data format. + +## Description ## + +This plugin enables ActivityPub for your Blog. Your readers will be able to follow your Blogposts on Mastodon and other Federated Plattforms that support ActivityPub. + +## Frequently Asked Questions ## + +### Why does the plugin not support following and other social network stuff ### + +If you want to have a **decentralized social network**, please use [Mastodon](https://joinmastodon.org/) or [GNU.social](https://gnu.io/social/). + + +## Changelog ## + +### 0.0.1 ### + +* initial + +## Installation ## + +Follow the normal instructions for [installing WordPress plugins](https://codex.wordpress.org/Managing_Plugins#Installing_Plugins). + +### Automatic Plugin Installation ### + +To add a WordPress Plugin using the [built-in plugin installer](https://codex.wordpress.org/Administration_Screens#Add_New_Plugins): + +1. Go to [Plugins](https://codex.wordpress.org/Administration_Screens#Plugins) > [Add New](https://codex.wordpress.org/Plugins_Add_New_Screen). +1. Type "`activitypub`" into the **Search Plugins** box. +1. Find the WordPress Plugin you wish to install. + 1. Click **Details** for more information about the Plugin and instructions you may wish to print or save to help setup the Plugin. + 1. Click **Install Now** to install the WordPress Plugin. +1. The resulting installation screen will list the installation as successful or note any problems during the install. +1. If successful, click **Activate Plugin** to activate it, or **Return to Plugin Installer** for further actions. + +### Manual Plugin Installation ### + +There are a few cases when manually installing a WordPress Plugin is appropriate. + +* If you wish to control the placement and the process of installing a WordPress Plugin. +* If your server does not permit automatic installation of a WordPress Plugin. +* If you want to try the [latest development version](https://github.com/pfefferle/wordpress-activitypub). + +Installation of a WordPress Plugin manually requires FTP familiarity and the awareness that you may put your site at risk if you install a WordPress Plugin incompatible with the current version or from an unreliable source. + +Backup your site completely before proceeding. + +To install a WordPress Plugin manually: + +* Download your WordPress Plugin to your desktop. + * Download from [the WordPress directory](https://wordpress.org/plugins/activitypub/) + * Download from [GitHub](https://github.com/pfefferle/wordpress-activitypub/releases) +* If downloaded as a zip archive, extract the Plugin folder to your desktop. +* With your FTP program, upload the Plugin folder to the `wp-content/plugins` folder in your WordPress directory online. +* Go to [Plugins screen](https://codex.wordpress.org/Administration_Screens#Plugins) and find the newly uploaded Plugin in the list. +* Click **Activate** to activate it. diff --git a/includes/class-activitypub-outbox.php b/includes/class-activitypub-outbox.php index 5dd7ea2..9a4e383 100644 --- a/includes/class-activitypub-outbox.php +++ b/includes/class-activitypub-outbox.php @@ -6,29 +6,120 @@ */ class Activitypub_Outbox { /** - * Register the Route. + * Register routes */ public static function register_routes() { register_rest_route( - 'activitypub/1.0', '/outbox', array( + 'activitypub/1.0', '/users/(?P\d+)/outbox', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( 'Activitypub_Outbox', 'get' ), + 'args' => self::request_parameters(), ), ) ); } public static function get( $request ) { - $outbox = new stdClass(); + $author_id = $request->get_param( 'id' ); + $author = get_user_by( 'ID', $author_id ); - $outbox->{'@context'} = array( + if ( ! $author ) { + return new WP_Error( 'rest_invalid_param', __( 'User not found', 'activitypub' ), array( + 'status' => 404, 'params' => array( + 'user_id' => __( 'User not found', 'activitypub' ) + ) + ) ); + } + + $page = $request->get_param( 'page', 0 ); + + /* + * Action triggerd prior to the ActivityPub profile being created and sent to the client + */ + do_action( 'activitypub_outbox_pre' ); + + $json = new stdClass(); + + $json->{'@context'} = array( 'https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1', ); - //var_dump($request->get_param('page')); + $json->generator = 'http://wordpress.org/?v=' . get_bloginfo_rss( 'version' ); + $json->actor = get_author_posts_url( $author_id ); + $json->type = 'OrderedCollectionPage'; + $json->partOf = get_rest_url( null, "/activitypub/1.0/users/$author_id/outbox" ); // phpcs:ignore - return new WP_REST_Response( $outbox, 200 ); + $count_posts = wp_count_posts(); + $json->totalItems = $count_posts->publish; + + $posts = get_posts( array( + 'author' => $author_id, + 'offset' => $page, + ) ); + + $json->first = add_query_arg( 'page', 0, $json->partOf ); + $json->last = add_query_arg( 'page', ( $json->totalItems%10 )-1, $json->partOf ); + if ( $json->last < $page ) { + $json->next = add_query_arg( 'page', ++$page, $json->partOf ); + } + + foreach ( $posts as $post ) { + $json->orderedItems[] = self::post_to_json( $post ); // phpcs:ignore + } + + // filter output + $json = apply_filters( 'activitypub_outbox_array', $json ); + + /* + * Action triggerd after the ActivityPub profile has been created and sent to the client + */ + do_action( 'activitypub_outbox_post' ); + + $response = new WP_REST_Response( $json, 200 ); + + $response->header( 'Content-Type', 'application/activity-json' ); + + return $response; + } + + public static function post_to_json( $post ) { + $json = new stdClass(); + + $json->published = $post->post_date; + $json->id = $post->guid; + $json->type = 'Create'; + $json->actor = 'https://mastodon.social/users/pfefferle'; + $json->to = array( 'https://www.w3.org/ns/activitystreams#Public' ); + + $json->object = array( + 'id' => $post->guid, + 'type' => 'Note', + 'published' => $post->post_date, + 'to' => array( 'https://www.w3.org/ns/activitystreams#Public' ), + 'content' => $post->post_content, + 'contentMap' => array( + strstr( get_locale(), '_', true ) => $post->post_content, + ), + ); + + return $json; + } + + + public static function request_parameters() { + $params = array(); + + $params['page'] = array( + 'type' => 'integer', + ); + + $params['id'] = array( + 'required' => true, + 'type' => 'integer', + ); + + return $params; } } diff --git a/includes/class-activitypub.php b/includes/class-activitypub.php index 48beae9..8fedde9 100644 --- a/includes/class-activitypub.php +++ b/includes/class-activitypub.php @@ -6,7 +6,7 @@ class Activitypub { return $template; } - $json_template = dirname( __FILE__ ) . '/../templates/author-profile.php'; + $json_template = dirname( __FILE__ ) . '/../templates/profile.php'; global $wp_query; @@ -61,6 +61,7 @@ class Activitypub { */ public static function add_query_vars( $vars ) { $vars[] = 'activitypub'; + return $vars; } diff --git a/includes/functions.php b/includes/functions.php index e69de29..b3d9bbc 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -0,0 +1 @@ +\n" "X-Generator: grunt-wp-i18n1.0.2\n" +#: includes/class-activitypub-outbox.php:28 +#: includes/class-activitypub-outbox.php:30 +msgid "User not found" +msgstr "" + #. Plugin Name of the plugin/theme msgid "ActivityPub" msgstr "" diff --git a/readme.txt b/readme.txt index fb24cbf..e6d2d23 100644 --- a/readme.txt +++ b/readme.txt @@ -4,9 +4,64 @@ Donate link: https://notiz.blog/donate/ Tags: OStatus, fediverse, activitypub, activitystream Requires at least: 4.7 Tested up to: 4.9.8 -Stable tag: 1.0.0 +Stable tag: 0.0.1 Requires PHP: 5.3 License: MIT License URI: http://opensource.org/licenses/MIT The ActivityPub protocol is a decentralized social networking protocol based upon the ActivityStreams 2.0 data format. + +== Description == + +This plugin enables ActivityPub for your Blog. Your readers will be able to follow your Blogposts on Mastodon and other Federated Plattforms that support ActivityPub. + +== Frequently Asked Questions == + += Why does the plugin not support following and other social network stuff = + +If you want to have a **decentralized social network**, please use [Mastodon](https://joinmastodon.org/) or [GNU.social](https://gnu.io/social/). + + +== Changelog == + += 0.0.1 = + +* initial + +== Installation == + +Follow the normal instructions for [installing WordPress plugins](https://codex.wordpress.org/Managing_Plugins#Installing_Plugins). + += Automatic Plugin Installation = + +To add a WordPress Plugin using the [built-in plugin installer](https://codex.wordpress.org/Administration_Screens#Add_New_Plugins): + +1. Go to [Plugins](https://codex.wordpress.org/Administration_Screens#Plugins) > [Add New](https://codex.wordpress.org/Plugins_Add_New_Screen). +1. Type "`activitypub`" into the **Search Plugins** box. +1. Find the WordPress Plugin you wish to install. + 1. Click **Details** for more information about the Plugin and instructions you may wish to print or save to help setup the Plugin. + 1. Click **Install Now** to install the WordPress Plugin. +1. The resulting installation screen will list the installation as successful or note any problems during the install. +1. If successful, click **Activate Plugin** to activate it, or **Return to Plugin Installer** for further actions. + += Manual Plugin Installation = + +There are a few cases when manually installing a WordPress Plugin is appropriate. + +* If you wish to control the placement and the process of installing a WordPress Plugin. +* If your server does not permit automatic installation of a WordPress Plugin. +* If you want to try the [latest development version](https://github.com/pfefferle/wordpress-activitypub). + +Installation of a WordPress Plugin manually requires FTP familiarity and the awareness that you may put your site at risk if you install a WordPress Plugin incompatible with the current version or from an unreliable source. + +Backup your site completely before proceeding. + +To install a WordPress Plugin manually: + +* Download your WordPress Plugin to your desktop. + * Download from [the WordPress directory](https://wordpress.org/plugins/activitypub/) + * Download from [GitHub](https://github.com/pfefferle/wordpress-activitypub/releases) +* If downloaded as a zip archive, extract the Plugin folder to your desktop. +* With your FTP program, upload the Plugin folder to the `wp-content/plugins` folder in your WordPress directory online. +* Go to [Plugins screen](https://codex.wordpress.org/Administration_Screens#Plugins) and find the newly uploaded Plugin in the list. +* Click **Activate** to activate it. diff --git a/templates/author-profile.php b/templates/profile.php similarity index 89% rename from templates/author-profile.php rename to templates/profile.php index d38157c..cc17587 100644 --- a/templates/author-profile.php +++ b/templates/profile.php @@ -1,10 +1,4 @@ outbox = get_rest_url( null, '/activitypub/1.0/outbox' ); +$json->outbox = get_rest_url( null, "/activitypub/1.0/users/$author_id/outbox" ); if ( method_exists( 'Magic_Sig', 'get_public_key' ) ) { // phpcs:ignore