From 43f347bc7c3edd2d39936e6a8f3983842146baa9 Mon Sep 17 00:00:00 2001 From: Greg Date: Fri, 6 Jan 2023 20:04:05 -0500 Subject: [PATCH 1/8] Make the excerpt code actually crop the excerpt at 400 characters. The existing implementation crops at words and may return very short strings based upon filters, or very long strings based upon user inputted excerpts. Make sure we never return a excerpt longer than we expect. --- includes/model/class-post.php | 58 ++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/includes/model/class-post.php b/includes/model/class-post.php index e885199..84ed4fd 100644 --- a/includes/model/class-post.php +++ b/includes/model/class-post.php @@ -286,12 +286,62 @@ class Post { $excerpt = \apply_filters( 'the_content', $excerpt ); $excerpt = \str_replace( ']]>', ']]>', $excerpt ); - $excerpt_length = \apply_filters( 'excerpt_length', $excerpt_length ); + } + } - /** This filter is documented in wp-includes/formatting.php */ - $excerpt_more = \apply_filters( 'excerpt_more', ' [...]' ); + // Strip out any remaining tags. + $excerpt = \wp_strip_all_tags( $excerpt ); - $excerpt = \wp_trim_words( $excerpt, $excerpt_length, $excerpt_more ); + /** This filter is documented in wp-includes/formatting.php */ + $excerpt_more = \apply_filters( 'excerpt_more', ' [...]' ); + $excerpt_more_len = strlen( $excerpt_more ); + + // We now have a excerpt, but we need to check it's length, it may be longer than we want for two reasons: + // + // * The user has entered a manual excerpt which is longer that what we want. + // * No manual excerpt exists so we've used the content which might be longer than we want. + // + // Either way, let's trim it up if we need too. Also, don't forget to take into account the more indicator + // as part of the total length. + // + + // Setup a variable to hold the current excerpts length. + $current_excerpt_length = strlen( $excerpt ); + + // Setup a variable to keep track of our target length. + $target_excerpt_length = $current_excerpt_length - $excerpt_more_len; + + // Setup a variable to keep track of the current max length. + $current_expcerpt_max = $target_excerpt_length; + + // This is a loop since we can't calculate word break the string after 'the_excpert' filter has run (we would break + // all kinds of html tags), so we have to cut the excerpt down a bit at a time until we hit our target length. + while( $current_excerpt_length > $target_excerpt_length && $current_expcerpt_max > 0 ) { + // Trim the excerpt based on wordwrap() positioning. + // Note: we're using
as the linebreak just in case there are any newlines existing in the excerpt from the user. + // There won't be any
left after we've run wp_strip_all_tags() in the code above, so they're + // safe to use here. It won't be included in the final excerpt as the substr() will trim it off. + $excerpt = substr( $excerpt, 0, strpos( wordwrap( $excerpt, $current_expcerpt_max, '
' ), '
' ) ); + + // If something went wrong, or we're in a language that wordwrap() doesn't understand, + // just chop it off and don't worry about breaking in the middle of a word. + if( strlen( $excerpt ) > $excerpt_length - $excerpt_more_len ) { + $excerpt = substr( $excerpt, 0, $current_expcerpt_max ); + } + + // Add in the more indicator. + $excerpt = $excerpt . $excerpt_more; + + // Run it through the excerpt filter which will add some html tags back in. + $excerpt_filtered = apply_filters( 'the_excerpt', $excerpt ); + + // Now set the current excerpt length to this new filtered length. + $current_excerpt_length = strlen( $excerpt_filtered ); + + // Check to see if we're over the target length. + if( $current_excerpt_length > $target_excerpt_length ) { + // If so, remove 20 characters from the current max and run the loop again. + $current_expcerpt_max = $current_expcerpt_max - 20; } } From 27aeaeb4e40893fed62380ef4f2391f36a8ddd6b Mon Sep 17 00:00:00 2001 From: Greg Date: Fri, 13 Jan 2023 11:02:16 -0500 Subject: [PATCH 2/8] Fix incorrect setting of target length and spelling mistake. --- includes/model/class-post.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/includes/model/class-post.php b/includes/model/class-post.php index 84ed4fd..7f9c9e9 100644 --- a/includes/model/class-post.php +++ b/includes/model/class-post.php @@ -309,24 +309,24 @@ class Post { $current_excerpt_length = strlen( $excerpt ); // Setup a variable to keep track of our target length. - $target_excerpt_length = $current_excerpt_length - $excerpt_more_len; + $target_excerpt_length = $excerpt_length - $excerpt_more_len; // Setup a variable to keep track of the current max length. - $current_expcerpt_max = $target_excerpt_length; + $current_excerpt_max = $target_excerpt_length; // This is a loop since we can't calculate word break the string after 'the_excpert' filter has run (we would break // all kinds of html tags), so we have to cut the excerpt down a bit at a time until we hit our target length. - while( $current_excerpt_length > $target_excerpt_length && $current_expcerpt_max > 0 ) { + while( $current_excerpt_length > $target_excerpt_length && $current_excerpt_max > 0 ) { // Trim the excerpt based on wordwrap() positioning. // Note: we're using
as the linebreak just in case there are any newlines existing in the excerpt from the user. // There won't be any
left after we've run wp_strip_all_tags() in the code above, so they're // safe to use here. It won't be included in the final excerpt as the substr() will trim it off. - $excerpt = substr( $excerpt, 0, strpos( wordwrap( $excerpt, $current_expcerpt_max, '
' ), '
' ) ); + $excerpt = substr( $excerpt, 0, strpos( wordwrap( $excerpt, $current_excerpt_max, '
' ), '
' ) ); // If something went wrong, or we're in a language that wordwrap() doesn't understand, // just chop it off and don't worry about breaking in the middle of a word. if( strlen( $excerpt ) > $excerpt_length - $excerpt_more_len ) { - $excerpt = substr( $excerpt, 0, $current_expcerpt_max ); + $excerpt = substr( $excerpt, 0, $current_excerpt_max ); } // Add in the more indicator. @@ -341,7 +341,7 @@ class Post { // Check to see if we're over the target length. if( $current_excerpt_length > $target_excerpt_length ) { // If so, remove 20 characters from the current max and run the loop again. - $current_expcerpt_max = $current_expcerpt_max - 20; + $current_excerpt_max = $current_excerpt_max - 20; } } From e4eda45e9f4e906af5026bda5cebdea52ccb3bf2 Mon Sep 17 00:00:00 2001 From: Greg Date: Fri, 13 Jan 2023 20:17:51 -0500 Subject: [PATCH 3/8] Give the notice boxes some margin so they have some space. --- assets/css/activitypub-admin.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/css/activitypub-admin.css b/assets/css/activitypub-admin.css index a6cc390..cd1808c 100644 --- a/assets/css/activitypub-admin.css +++ b/assets/css/activitypub-admin.css @@ -1,6 +1,7 @@ .settings_page_activitypub .notice { max-width: 800px; - margin: 0 auto; + margin: auto; + margin-top: 10px; } .activitypub-settings-header { From 2f0dbde2a41ac71240fb1f30521b761499b033d7 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 16 Jan 2023 15:28:10 +0100 Subject: [PATCH 4/8] fix phpcs issues --- includes/model/class-post.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/model/class-post.php b/includes/model/class-post.php index aa207e9..9140b07 100644 --- a/includes/model/class-post.php +++ b/includes/model/class-post.php @@ -302,7 +302,7 @@ class Post { /** This filter is documented in wp-includes/formatting.php */ $excerpt_more = \apply_filters( 'excerpt_more', ' [...]' ); - $excerpt_more_len = strlen( $excerpt_more ); + $excerpt_more_len = strlen( $excerpt_more ); // We now have a excerpt, but we need to check it's length, it may be longer than we want for two reasons: // @@ -324,7 +324,7 @@ class Post { // This is a loop since we can't calculate word break the string after 'the_excpert' filter has run (we would break // all kinds of html tags), so we have to cut the excerpt down a bit at a time until we hit our target length. - while( $current_excerpt_length > $target_excerpt_length && $current_excerpt_max > 0 ) { + while ( $current_excerpt_length > $target_excerpt_length && $current_excerpt_max > 0 ) { // Trim the excerpt based on wordwrap() positioning. // Note: we're using
as the linebreak just in case there are any newlines existing in the excerpt from the user. // There won't be any
left after we've run wp_strip_all_tags() in the code above, so they're @@ -333,7 +333,7 @@ class Post { // If something went wrong, or we're in a language that wordwrap() doesn't understand, // just chop it off and don't worry about breaking in the middle of a word. - if( strlen( $excerpt ) > $excerpt_length - $excerpt_more_len ) { + if ( strlen( $excerpt ) > $excerpt_length - $excerpt_more_len ) { $excerpt = substr( $excerpt, 0, $current_excerpt_max ); } @@ -347,7 +347,7 @@ class Post { $current_excerpt_length = strlen( $excerpt_filtered ); // Check to see if we're over the target length. - if( $current_excerpt_length > $target_excerpt_length ) { + if ( $current_excerpt_length > $target_excerpt_length ) { // If so, remove 20 characters from the current max and run the loop again. $current_excerpt_max = $current_excerpt_max - 20; } From 47bd6eb3b4a1ebda67cae83f299f2014a2058617 Mon Sep 17 00:00:00 2001 From: Greg Date: Mon, 16 Jan 2023 13:19:26 -0500 Subject: [PATCH 5/8] Move the activitypub endpoint rule to the main rewrite addition function. This is for two reasons: - No need to add the endpoint every time the plugin loads. - The old code didn't flush the rewrite rules, making the endpoint non-functional until something did (like the user saving the permalink settings) --- activitypub.php | 2 ++ includes/class-activitypub.php | 8 -------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/activitypub.php b/activitypub.php index d9f2a61..9dd8f82 100644 --- a/activitypub.php +++ b/activitypub.php @@ -116,6 +116,8 @@ function add_rewrite_rules() { \add_rewrite_rule( '^.well-known/nodeinfo', 'index.php?rest_route=/activitypub/1.0/nodeinfo/discovery', 'top' ); \add_rewrite_rule( '^.well-known/x-nodeinfo2', 'index.php?rest_route=/activitypub/1.0/nodeinfo2', 'top' ); } + + \add_rewrite_endpoint( 'activitypub', EP_AUTHORS | EP_PERMALINK | EP_PAGES ); } \add_action( 'init', '\Activitypub\add_rewrite_rules', 1 ); diff --git a/includes/class-activitypub.php b/includes/class-activitypub.php index ea3532a..00b413f 100644 --- a/includes/class-activitypub.php +++ b/includes/class-activitypub.php @@ -13,7 +13,6 @@ class Activitypub { public static function init() { \add_filter( 'template_include', array( '\Activitypub\Activitypub', 'render_json_template' ), 99 ); \add_filter( 'query_vars', array( '\Activitypub\Activitypub', 'add_query_vars' ) ); - \add_action( 'init', array( '\Activitypub\Activitypub', 'add_rewrite_endpoint' ) ); \add_filter( 'pre_get_avatar_data', array( '\Activitypub\Activitypub', 'pre_get_avatar_data' ), 11, 2 ); // Add support for ActivityPub to custom post types @@ -96,13 +95,6 @@ class Activitypub { return $vars; } - /** - * Add our rewrite endpoint to permalinks and pages. - */ - public static function add_rewrite_endpoint() { - \add_rewrite_endpoint( 'activitypub', EP_AUTHORS | EP_PERMALINK | EP_PAGES ); - } - /** * Schedule Activities. * From 3dfdf2ac0a94e55e73b9e010abf940d40b791788 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 16 Jan 2023 20:12:14 +0100 Subject: [PATCH 6/8] Use a single page to explain all topics (glossar) --- includes/help.php | 42 +++++++++--------------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/includes/help.php b/includes/help.php index 16ffbea..f84ccaf 100644 --- a/includes/help.php +++ b/includes/help.php @@ -2,45 +2,21 @@ \get_current_screen()->add_help_tab( array( - 'id' => 'fediverse', - 'title' => \__( 'Fediverse', 'activitypub' ), + 'id' => 'glossar', + 'title' => \__( 'Glossar', 'activitypub' ), 'content' => - '

' . \__( 'What is the Fediverse?', 'activitypub' ) . '

' . + '

' . \__( 'Fediverse', 'activitypub' ) . '

' . '

' . \__( 'The Fediverse is a new word made of two words: "federation" + "universe"', 'activitypub' ) . '

' . '

' . \__( 'It is a federated social network running on free open software on a myriad of computers across the globe. Many independent servers are interconnected and allow people to interact with one another. There\'s no one central site: you choose a server to register. This ensures some decentralization and sovereignty of data. Fediverse (also called Fedi) has no built-in advertisements, no tricky algorithms, no one big corporation dictating the rules. Instead we have small cozy communities of like-minded people. Welcome!', 'activitypub' ) . '

' . - '

' . \__( 'For more informations please visit fediverse.party', 'activitypub' ) . '

', - ) -); - -\get_current_screen()->add_help_tab( - array( - 'id' => 'activitypub', - 'title' => \__( 'ActivityPub', 'activitypub' ), - 'content' => - '

' . \__( 'What is ActivityPub?', 'activitypub' ) . '

' . - '

' . \__( 'ActivityPub is a decentralized social networking protocol based on the ActivityStreams 2.0 data format. ActivityPub is an official W3C recommended standard published by the W3C Social Web Working Group. It provides a client to server API for creating, updating and deleting content, as well as a federated server to server API for delivering notifications and subscribing to content.', 'activitypub' ) . '

', - ) -); - -\get_current_screen()->add_help_tab( - array( - 'id' => 'webfinger', - 'title' => \__( 'WebFinger', 'activitypub' ), - 'content' => - '

' . \__( 'What is WebFinger?', 'activitypub' ) . '

' . + '

' . \__( 'For more informations please visit fediverse.party', 'activitypub' ) . '

' . + '

' . \__( 'ActivityPub', 'activitypub' ) . '

' . + '

' . \__( 'ActivityPub is a decentralized social networking protocol based on the ActivityStreams 2.0 data format. ActivityPub is an official W3C recommended standard published by the W3C Social Web Working Group. It provides a client to server API for creating, updating and deleting content, as well as a federated server to server API for delivering notifications and subscribing to content.', 'activitypub' ) . '

' . + '

' . \__( 'WebFinger', 'activitypub' ) . '

' . '

' . \__( 'WebFinger is used to discover information about people or other entities on the Internet that are identified by a URI using standard Hypertext Transfer Protocol (HTTP) methods over a secure transport. A WebFinger resource returns a JavaScript Object Notation (JSON) object describing the entity that is queried. The JSON object is referred to as the JSON Resource Descriptor (JRD).', 'activitypub' ) . '

' . '

' . \__( 'For a person, the type of information that might be discoverable via WebFinger includes a personal profile address, identity service, telephone number, or preferred avatar. For other entities on the Internet, a WebFinger resource might return JRDs containing link relations that enable a client to discover, for example, that a printer can print in color on A4 paper, the physical location of a server, or other static information.', 'activitypub' ) . '

' . '

' . \__( 'On Mastodon [and other Plattforms], user profiles can be hosted either locally on the same website as yours, or remotely on a completely different website. The same username may be used on a different domain. Therefore, a Mastodon user\'s full mention consists of both the username and the domain, in the form @username@domain. In practical terms, @user@example.com is not the same as @user@example.org. If the domain is not included, Mastodon will try to find a local user named @username. However, in order to deliver to someone over ActivityPub, the @username@domain mention is not enough – mentions must be translated to an HTTPS URI first, so that the remote actor\'s inbox and outbox can be found. (This paragraph is copied from the Mastodon Documentation)', 'activitypub' ) . '

' . - '

' . \__( 'For more informations please visit webfinger.net', 'activitypub' ) . '

', - ) -); - -\get_current_screen()->add_help_tab( - array( - 'id' => 'nodeinfo', - 'title' => \__( 'NodeInfo', 'activitypub' ), - 'content' => - '

' . \__( 'What is NodeInfo?', 'activitypub' ) . '

' . + '

' . \__( 'For more informations please visit webfinger.net', 'activitypub' ) . '

' . + '

' . \__( 'NodeInfo', 'activitypub' ) . '

' . '

' . \__( 'NodeInfo is an effort to create a standardized way of exposing metadata about a server running one of the distributed social networks. The two key goals are being able to get better insights into the user base of distributed social networking and the ability to build tools that allow users to choose the best fitting software and server for their needs.', 'activitypub' ) . '

' . '

' . \__( 'For more informations please visit nodeinfo.diaspora.software', 'activitypub' ) . '

', ) From f412e83f0f7c1732b32d6aacda7970b6ac973067 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 16 Jan 2023 20:23:05 +0100 Subject: [PATCH 7/8] hashtag support is experimental --- templates/settings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/settings.php b/templates/settings.php index 9450195..809ab15 100644 --- a/templates/settings.php +++ b/templates/settings.php @@ -132,11 +132,11 @@ - +

- +

From 0d255d219b72c5c5fd43cd34f2f605b19769ca64 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Mon, 16 Jan 2023 20:28:45 +0100 Subject: [PATCH 8/8] change priority because of #182 --- includes/class-activitypub.php | 2 +- includes/class-hashtag.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/class-activitypub.php b/includes/class-activitypub.php index 00b413f..c04aedc 100644 --- a/includes/class-activitypub.php +++ b/includes/class-activitypub.php @@ -22,7 +22,7 @@ class Activitypub { \add_post_type_support( $post_type, 'activitypub' ); } - \add_action( 'transition_post_status', array( '\Activitypub\Activitypub', 'schedule_post_activity' ), 10, 3 ); + \add_action( 'transition_post_status', array( '\Activitypub\Activitypub', 'schedule_post_activity' ), 33, 3 ); \add_action( 'wp_trash_post', array( '\Activitypub\Activitypub', 'trash_post' ), 1 ); \add_action( 'untrash_post', array( '\Activitypub\Activitypub', 'untrash_post' ), 1 ); } diff --git a/includes/class-hashtag.php b/includes/class-hashtag.php index fbe2f3d..356cdb9 100644 --- a/includes/class-hashtag.php +++ b/includes/class-hashtag.php @@ -12,8 +12,8 @@ class Hashtag { */ public static function init() { if ( '1' === \get_option( 'activitypub_use_hashtags', '1' ) ) { - \add_filter( 'wp_insert_post', array( '\Activitypub\Hashtag', 'insert_post' ), 99, 2 ); - \add_filter( 'the_content', array( '\Activitypub\Hashtag', 'the_content' ), 99, 2 ); + \add_filter( 'wp_insert_post', array( '\Activitypub\Hashtag', 'insert_post' ), 10, 2 ); + \add_filter( 'the_content', array( '\Activitypub\Hashtag', 'the_content' ), 10, 2 ); } }