diff --git a/README.md b/README.md index 58e7acf..9b5f18b 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ **Donate link:** https://notiz.blog/donate/ **Tags:** OStatus, fediverse, activitypub, activitystream **Requires at least:** 4.7 -**Tested up to:** 5.0.3 -**Stable tag:** 0.2.1 +**Tested up to:** 5.1.0 +**Stable tag:** 0.3.0 **Requires PHP:** 5.6 **License:** MIT **License URI:** http://opensource.org/licenses/MIT @@ -58,7 +58,9 @@ Project maintained on github at [pfefferle/wordpress-activitypub](https://github ### 0.3.0 ### * basic hashtag support -* temporarily deactived likes and boosts +* temporarily deactived likes and boosts +* added support for actor objects +* fixed encoding issue ### 0.2.1 ### diff --git a/activitypub.php b/activitypub.php index a0b5bec..c6d85bd 100644 --- a/activitypub.php +++ b/activitypub.php @@ -3,7 +3,7 @@ * Plugin Name: ActivityPub * Plugin URI: https://github.com/pfefferle/wordpress-activitypub/ * Description: The ActivityPub protocol is a decentralized social networking protocol based upon the ActivityStreams 2.0 data format. - * Version: 0.2.1 + * Version: 0.3.0 * Author: Matthias Pfefferle * Author URI: https://notiz.blog/ * License: MIT @@ -19,11 +19,14 @@ function activitypub_init() { defined( 'ACTIVITYPUB_HASHTAGS_REGEXP' ) || define( 'ACTIVITYPUB_HASHTAGS_REGEXP', '(^|\s|>)#([^\s<>]+)\b' ); require_once dirname( __FILE__ ) . '/includes/class-activitypub-signature.php'; - require_once dirname( __FILE__ ) . '/includes/class-activitypub-post.php'; require_once dirname( __FILE__ ) . '/includes/class-activitypub-activity.php'; require_once dirname( __FILE__ ) . '/includes/class-db-activitypub-followers.php'; require_once dirname( __FILE__ ) . '/includes/functions.php'; + require_once dirname( __FILE__ ) . '/includes/class-activitypub-post.php'; + add_filter( 'activitypub_the_excerpt', array( 'Activitypub_Post', 'add_backlink' ), 10, 2 ); + add_filter( 'activitypub_the_content', array( 'Activitypub_Post', 'add_backlink' ), 10, 2 ); + require_once dirname( __FILE__ ) . '/includes/class-activitypub.php'; add_filter( 'template_include', array( 'Activitypub', 'render_json_template' ), 99 ); add_filter( 'query_vars', array( 'Activitypub', 'add_query_vars' ) ); diff --git a/includes/class-activitypub-activity.php b/includes/class-activitypub-activity.php index 68e1b92..d6182bc 100644 --- a/includes/class-activitypub-activity.php +++ b/includes/class-activitypub-activity.php @@ -65,7 +65,7 @@ class Activitypub_Activity { } public function to_json() { - return wp_json_encode( $this->to_array() ); + return wp_json_encode( $this->to_array(), JSON_UNESCAPED_UNICODE ); } public function to_simple_array() { @@ -79,6 +79,6 @@ class Activitypub_Activity { } public function to_simple_json() { - return wp_json_encode( $this->to_simple_array() ); + return wp_json_encode( $this->to_simple_array(), JSON_UNESCAPED_UNICODE ); } } diff --git a/includes/class-activitypub-post.php b/includes/class-activitypub-post.php index 02d06df..d4da38d 100644 --- a/includes/class-activitypub-post.php +++ b/includes/class-activitypub-post.php @@ -27,7 +27,7 @@ class Activitypub_Post { 'type' => $this->get_object_type(), 'published' => date( 'Y-m-d\TH:i:s\Z', strtotime( $post->post_date ) ), 'attributedTo' => get_author_posts_url( $post->post_author ), - 'summary' => ( $this->get_object_type() == 'Article' ) ? $this->get_the_post_excerpt( 400, false ) : null, + 'summary' => $this->get_the_summary(), 'inReplyTo' => null, 'content' => $this->get_the_content(), 'contentMap' => array( @@ -43,7 +43,7 @@ class Activitypub_Post { } public function to_json() { - return wp_json_encode( $this->to_array() ); + return wp_json_encode( $this->to_array(), JSON_UNESCAPED_UNICODE ); } public function get_attachments() { @@ -196,12 +196,20 @@ class Activitypub_Post { public function get_the_content() { if ( 'excerpt' === get_option( 'activitypub_post_content_type', 'excerpt' ) ) { - return $this->get_the_post_excerpt(); + return $this->get_the_post_summary(); } return $this->get_the_post_content(); } + public function get_the_summary() { + if ( 'Article' === $this->get_object_type() ) { + return $this->get_the_post_excerpt( 400 ); + } + + return null; + } + /** * Get the excerpt for a post for use outside of the loop. * @@ -209,7 +217,7 @@ class Activitypub_Post { * * @return string The excerpt. */ - public function get_the_post_excerpt( $excerpt_length = 400, $with_link = true ) { + public function get_the_post_excerpt( $excerpt_length = 400 ) { $post = $this->post; $excerpt = get_post_field( 'post_excerpt', $post ); @@ -236,23 +244,7 @@ class Activitypub_Post { } } - $filtered_excerpt = apply_filters( 'the_excerpt', $excerpt ); - - if ( $with_link ) { - $link = ''; - - if ( get_option( 'activitypub_use_shortlink', 0 ) ) { - $link = esc_url( wp_get_shortlink( $this->post->ID ) ); - } else { - $link = esc_url( get_permalink( $this->post->ID ) ); - } - - $filtered_excerpt = $filtered_excerpt . "\n\n" . '' . $link . ''; - } - - $allowed_html = apply_filters( 'activitypub_allowed_html', '' ); - - return trim( preg_replace( '/[\r\n]{2,}/', "\n\n", strip_tags( $filtered_excerpt, $allowed_html ) ) ); + return html_entity_decode( $excerpt, ENT_QUOTES, 'UTF-8' ); } /** @@ -266,21 +258,44 @@ class Activitypub_Post { $content = get_post_field( 'post_content', $post ); $filtered_content = apply_filters( 'the_content', $content ); + $filtered_content = apply_filters( 'activitypub_the_content', $filtered_content, $this->post ); - if ( $with_link ) { - $link = ''; - - if ( get_option( 'activitypub_use_shortlink', 0 ) ) { - $link = esc_url( wp_get_shortlink( $this->post->ID ) ); - } else { - $link = esc_url( get_permalink( $this->post->ID ) ); - } - - $filtered_content = $filtered_content . "\n\n" . '' . $link . ''; - } + $decoded_content = html_entity_decode( $filtered_content, ENT_QUOTES, 'UTF-8' ); $allowed_html = apply_filters( 'activitypub_allowed_html', '' ); - return trim( preg_replace( '/[\r\n]{2,}/', "\n\n", strip_tags( $filtered_content, $allowed_html ) ) ); + return trim( preg_replace( '/[\r\n]{2,}/', "\n\n", strip_tags( $decoded_content, $allowed_html) ) ); + } + + /** + * Get the excerpt for a post for use outside of the loop. + * + * @param int Optional excerpt length. + * + * @return string The excerpt. + */ + public function get_the_post_summary( $summary_length = 400 ) { + $summary = $this->get_the_post_excerpt( $summary_length ); + + $filtered_summary = apply_filters( 'the_excerpt', $summary ); + $filtered_summary = apply_filters( 'activitypub_the_summary', $filtered_summary, $this->post ); + + $decoded_summary = html_entity_decode( $filtered_summary, ENT_QUOTES, 'UTF-8' ); + + $allowed_html = apply_filters( 'activitypub_allowed_html', '' ); + + return trim( preg_replace( '/[\r\n]{2,}/', "\n\n", strip_tags( $decoded_summary, $allowed_html) ) ); + } + + public static function add_backlink( $content, $post ) { + $link = ''; + + if ( get_option( 'activitypub_use_shortlink', 0 ) ) { + $link = esc_url( wp_get_shortlink( $post->ID ) ); + } else { + $link = esc_url( get_permalink( $post->ID ) ); + } + + return $content . "\n\n" . '' . $link . ''; } } diff --git a/includes/class-db-activitypub-followers.php b/includes/class-db-activitypub-followers.php index 7caba32..a9b61f9 100644 --- a/includes/class-db-activitypub-followers.php +++ b/includes/class-db-activitypub-followers.php @@ -9,6 +9,22 @@ class Db_Activitypub_Followers { public static function add_follower( $actor, $author_id ) { $followers = get_user_option( 'activitypub_followers', $author_id ); + if ( ! is_string( $actor ) ) { + if ( + is_array( $actor ) && + isset( $actor['type'] ) && + 'Person' === $actor['type'] && + isset( $actor['id'] ) && + true === filter_var( $actor['id'], FILTER_VALIDATE_URL ) + ) { + $actor = $actor['id']; + } + + return new WP_Error( 'invalid_actor_object', __( 'Unknown Actor schema', 'activitypub' ), array( + 'status' => 404 + ) ); + } + if ( ! is_array( $followers ) ) { $followers = array( $actor ); } else { diff --git a/languages/activitypub.pot b/languages/activitypub.pot index 0dac094..3dfc702 100644 --- a/languages/activitypub.pot +++ b/languages/activitypub.pot @@ -2,9 +2,9 @@ # This file is distributed under the MIT. msgid "" msgstr "" -"Project-Id-Version: ActivityPub 0.2.1\n" +"Project-Id-Version: ActivityPub 0.3.0\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/activitypub\n" -"POT-Creation-Date: 2019-01-22 20:17:45+00:00\n" +"POT-Creation-Date: 2019-02-02 22:55:56+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -65,6 +65,10 @@ msgstr "" msgid "Fediverse" msgstr "" +#: includes/class-db-activitypub-followers.php:23 +msgid "Unknown Actor schema" +msgstr "" + #: includes/class-rest-activitypub-followers.php:24 #: includes/class-rest-activitypub-followers.php:26 #: includes/class-rest-activitypub-outbox.php:35 diff --git a/readme.txt b/readme.txt index abc411c..5b14f93 100644 --- a/readme.txt +++ b/readme.txt @@ -3,8 +3,8 @@ Contributors: pfefferle Donate link: https://notiz.blog/donate/ Tags: OStatus, fediverse, activitypub, activitystream Requires at least: 4.7 -Tested up to: 5.0.3 -Stable tag: 0.2.1 +Tested up to: 5.1.0 +Stable tag: 0.3.0 Requires PHP: 5.6 License: MIT License URI: http://opensource.org/licenses/MIT @@ -58,7 +58,9 @@ Project maintained on github at [pfefferle/wordpress-activitypub](https://github = 0.3.0 = * basic hashtag support -* temporarily deactived likes and boosts +* temporarily deactived likes and boosts +* added support for actor objects +* fixed encoding issue = 0.2.1 = diff --git a/templates/json-author.php b/templates/json-author.php index 8401a0a..809deb4 100644 --- a/templates/json-author.php +++ b/templates/json-author.php @@ -93,6 +93,8 @@ if ( get_query_var( 'pretty' ) ) { $options |= JSON_PRETTY_PRINT; // phpcs:ignore } +$options |= JSON_UNESCAPED_UNICODE; + /* * Options to be passed to json_encode() * diff --git a/templates/json-post.php b/templates/json-post.php index 9be5709..38a4cdb 100644 --- a/templates/json-post.php +++ b/templates/json-post.php @@ -19,6 +19,8 @@ if ( get_query_var( 'pretty' ) ) { $options |= JSON_PRETTY_PRINT; // phpcs:ignore } +$options |= JSON_UNESCAPED_UNICODE; + /* * Options to be passed to json_encode() *