diff --git a/includes/class-hashtag.php b/includes/class-hashtag.php
index 1d8ea755..8f441c4b 100644
--- a/includes/class-hashtag.php
+++ b/includes/class-hashtag.php
@@ -28,29 +28,14 @@ class Hashtag {
* @return array the activity object array
*/
public static function filter_activity_object( $object_array ) {
- if ( empty( $object_array['summary'] ) ) {
- return $object_array;
+ if ( ! empty( $object_array['summary'] ) ) {
+ $object_array['summary'] = self::the_content( $object_array['summary'] );
}
- \preg_match_all( '/' . ACTIVITYPUB_HASHTAGS_REGEXP . '/', $object_array['summary'], $matches );
- foreach ( $matches[0] as $match_id => $match ) {
- $tag_object = \get_term_by( 'name', $matches[1][ $match_id ], 'post_tag' );
- if ( ! $tag_object ) {
- $tag_object = \get_term_by( 'name', $matches[1][ $match_id ], 'category' );
- }
-
- if ( $tag_object ) {
- $link = \get_term_link( $tag_object, 'post_tag' );
- $object_array['tag'][] = [
- 'type' => 'Hashtag',
- 'href' => $link,
- 'name' => $match,
- ];
- }
+ if ( ! empty( $object_array['content'] ) ) {
+ $object_array['content'] = self::the_content( $object_array['content'] );
}
- $object_array['summary'] = self::the_content( $object_array['summary'] );
-
return $object_array;
}
@@ -63,12 +48,20 @@ class Hashtag {
* @return
*/
public static function insert_post( $id, $post ) {
- if ( \preg_match_all( '/' . ACTIVITYPUB_HASHTAGS_REGEXP . '/i', $post->post_content, $match ) ) {
- $tags = \implode( ', ', $match[1] );
+ $tags = array();
- \wp_add_post_tags( $post->post_parent, $tags );
+ if ( \preg_match_all( '/' . ACTIVITYPUB_HASHTAGS_REGEXP . '/i', $post->post_content, $match ) ) {
+ $tags = array_merge( $tags, $match[1] );
}
+ if ( \preg_match_all( '/' . ACTIVITYPUB_HASHTAGS_REGEXP . '/i', $post->post_excerpt, $match ) ) {
+ $tags = array_merge( $tags, $match[1] );
+ }
+
+ $tags = \implode( ', ', $tags );
+
+ \wp_add_post_tags( $post->ID, $tags );
+
return $id;
}
diff --git a/includes/class-link.php b/includes/class-link.php
index b8ec6769..378248d2 100644
--- a/includes/class-link.php
+++ b/includes/class-link.php
@@ -12,6 +12,7 @@ class Link {
* Initialize the class, registering WordPress hooks
*/
public static function init() {
+ \add_filter( 'activitypub_extra_field_content', array( self::class, 'the_content' ), 10, 1 );
\add_filter( 'activitypub_activity_object_array', array( self::class, 'filter_activity_object' ), 99 );
}
@@ -23,11 +24,13 @@ class Link {
* @return array the activity object array
*/
public static function filter_activity_object( $object_array ) {
- if ( empty( $object_array['summary'] ) ) {
- return $object_array;
+ if ( ! empty( $object_array['summary'] ) ) {
+ $object_array['summary'] = self::the_content( $object_array['summary'] );
}
- $object_array['summary'] = self::the_content( $object_array['summary'] );
+ if ( ! empty( $object_array['content'] ) ) {
+ $object_array['content'] = self::the_content( $object_array['content'] );
+ }
return $object_array;
}
diff --git a/includes/class-mention.php b/includes/class-mention.php
index 116ae2dc..1219b326 100644
--- a/includes/class-mention.php
+++ b/includes/class-mention.php
@@ -19,6 +19,7 @@ class Mention {
public static function init() {
\add_filter( 'the_content', array( self::class, 'the_content' ), 99, 1 );
\add_filter( 'comment_text', array( self::class, 'the_content' ), 10, 1 );
+ \add_filter( 'activitypub_extra_field_content', array( self::class, 'the_content' ), 10, 1 );
\add_filter( 'activitypub_extract_mentions', array( self::class, 'extract_mentions' ), 99, 2 );
\add_filter( 'activitypub_activity_object_array', array( self::class, 'filter_activity_object' ), 99 );
}
@@ -32,11 +33,13 @@ class Mention {
* @return array the activity object array
*/
public static function filter_activity_object( $object_array ) {
- if ( empty( $object_array['summary'] ) ) {
- return $object_array;
+ if ( ! empty( $object_array['summary'] ) ) {
+ $object_array['summary'] = self::the_content( $object_array['summary'] );
}
- $object_array['summary'] = self::the_content( $object_array['summary'] );
+ if ( ! empty( $object_array['content'] ) ) {
+ $object_array['content'] = self::the_content( $object_array['content'] );
+ }
return $object_array;
}
@@ -145,6 +148,6 @@ class Mention {
$mentions[ $match ] = $link;
}
}
- return $mentions;
+ return \array_unique( $mentions );
}
}
diff --git a/includes/class-shortcodes.php b/includes/class-shortcodes.php
index b32b91dd..16be96ab 100644
--- a/includes/class-shortcodes.php
+++ b/includes/class-shortcodes.php
@@ -2,6 +2,7 @@
namespace Activitypub;
use function Activitypub\esc_hashtag;
+use function Activitypub\generate_post_summary;
class Shortcodes {
/**
@@ -108,81 +109,7 @@ class Shortcodes {
$excerpt_length = ACTIVITYPUB_EXCERPT_LENGTH;
}
- $excerpt = \get_post_field( 'post_excerpt', $item );
-
- if ( 'attachment' === $item->post_type ) {
- // get title of attachment with fallback to alt text.
- $content = wp_get_attachment_caption( $item->ID );
- if ( empty( $content ) ) {
- $content = get_post_meta( $item->ID, '_wp_attachment_image_alt', true );
- }
- } elseif ( '' === $excerpt ) {
- $content = \get_post_field( 'post_content', $item );
-
- // An empty string will make wp_trim_excerpt do stuff we do not want.
- if ( '' !== $content ) {
- $excerpt = \strip_shortcodes( $content );
-
- /** This filter is documented in wp-includes/post-template.php */
- $excerpt = \apply_filters( 'the_content', $excerpt );
- $excerpt = \str_replace( ']]>', ']]>', $excerpt );
- }
- }
-
- // Strip out any remaining tags.
- $excerpt = \wp_strip_all_tags( $excerpt );
-
- $excerpt_more = \apply_filters( 'activitypub_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 = $excerpt_length - $excerpt_more_len;
-
- // Setup a variable to keep track of the current max 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_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_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_excerpt_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_excerpt_max = $current_excerpt_max - 20;
- }
- }
+ $excerpt = generate_post_summary( $item, $excerpt_length );
return \apply_filters( 'the_excerpt', $excerpt );
}
diff --git a/includes/collection/class-extra-fields.php b/includes/collection/class-extra-fields.php
index 6b011b69..6e4aad4b 100644
--- a/includes/collection/class-extra-fields.php
+++ b/includes/collection/class-extra-fields.php
@@ -37,6 +37,13 @@ class Extra_Fields {
return apply_filters( 'activitypub_get_actor_extra_fields', $fields, $user_id );
}
+ /**
+ * Transforms the Extra Fields (Cutom Post Types) to ActivityPub Actor-Attachments.
+ *
+ * @param \WP_Post[] $fields The extra fields.
+ *
+ * @return array ActivityPub attachments.
+ */
public static function fields_to_attachments( $fields ) {
$attachments = array();
\add_filter(
@@ -50,7 +57,6 @@ class Extra_Fields {
foreach ( $fields as $post ) {
$content = \get_the_content( null, false, $post );
- $content = Link::the_content( $content, true );
$content = \do_blocks( $content );
$content = \wptexturize( $content );
$content = \wp_filter_content_tags( $content );
@@ -58,6 +64,7 @@ class Extra_Fields {
$content = \preg_replace( '@<(script|style)[^>]*?>.*?\\1>@si', '', $content );
$content = \strip_shortcodes( $content );
$content = \trim( \preg_replace( '/[\n\r\t]/', '', $content ) );
+ $content = \apply_filters( 'activitypub_extra_field_content', $content, $post );
$attachments[] = array(
'type' => 'PropertyValue',
diff --git a/includes/functions.php b/includes/functions.php
index 473d7570..7624ef20 100644
--- a/includes/functions.php
+++ b/includes/functions.php
@@ -1116,3 +1116,62 @@ function enrich_content_data( $content, $regex, $regex_callback ) {
return $content_with_links;
}
+
+/**
+ * Generate a summary of a post.
+ *
+ * This function generates a summary of a post by extracting:
+ *
+ * 1. The post excerpt if it exists.
+ * 2. The first part of the post content if it contains the tag.
+ * 3. An excerpt of the post content if it is longer than the specified length.
+ *
+ * @param int|WP_Post $post The post ID or post object.
+ * @param integer $length The maximum length of the summary.
+ * Default is 500. It will ne ignored if the post excerpt
+ * and the content above the tag.
+ *
+ * @return string The generated post summary.
+ */
+function generate_post_summary( $post, $length = 500 ) {
+ $post = get_post( $post );
+
+ if ( ! $post ) {
+ return '';
+ }
+
+ $content = \sanitize_post_field( 'post_excerpt', $post->post_excerpt, $post->ID );
+
+ if ( $content ) {
+ return \apply_filters( 'the_excerpt', $content );
+ }
+
+ $content = \sanitize_post_field( 'post_content', $post->post_content, $post->ID );
+ $content_parts = \get_extended( $content );
+
+ $excerpt_more = \apply_filters( 'activitypub_excerpt_more', '[…]' );
+ $length = $length - strlen( $excerpt_more );
+
+ // Check for the tag.
+ if (
+ ! empty( $content_parts['extended'] ) &&
+ ! empty( $content_parts['main'] )
+ ) {
+ $content = $content_parts['main'] . ' ' . $excerpt_more;
+ $length = null;
+ }
+
+ $content = \html_entity_decode( $content );
+ $content = \wp_strip_all_tags( $content );
+ $content = \trim( $content );
+ $content = \preg_replace( '/\R+/m', "\n\n", $content );
+ $content = \preg_replace( '/[\r\t]/', '', $content );
+
+ if ( $length && \strlen( $content ) > $length ) {
+ $content = \wordwrap( $content, $length, '' );
+ $content = \explode( '', $content, 2 );
+ $content = $content[0] . ' ' . $excerpt_more;
+ }
+
+ return \apply_filters( 'the_excerpt', $content );
+}
diff --git a/includes/transformer/class-post.php b/includes/transformer/class-post.php
index a274dd7c..7a2c7c14 100644
--- a/includes/transformer/class-post.php
+++ b/includes/transformer/class-post.php
@@ -10,6 +10,7 @@ use Activitypub\Collection\Users;
use function Activitypub\esc_hashtag;
use function Activitypub\is_single_user;
use function Activitypub\get_enclosures;
+use function Activitypub\generate_post_summary;
use function Activitypub\get_rest_url_by_path;
use function Activitypub\site_supports_blocks;
@@ -733,24 +734,7 @@ class Post extends Base {
return \__( '(This post is being modified)', 'activitypub' );
}
- $content = \get_post_field( 'post_content', $this->wp_object->ID );
- $content = \html_entity_decode( $content );
- $content = \wp_strip_all_tags( $content );
- $content = \trim( $content );
- $content = \preg_replace( '/\R+/m', "\n\n", $content );
- $content = \preg_replace( '/[\r\t]/', '', $content );
-
- $excerpt_more = \apply_filters( 'activitypub_excerpt_more', '[...]' );
- $length = 500;
- $length = $length - strlen( $excerpt_more );
-
- if ( \strlen( $content ) > $length ) {
- $content = \wordwrap( $content, $length, '' );
- $content = \explode( '', $content, 2 );
- $content = $content[0];
- }
-
- return $content . ' ' . $excerpt_more;
+ return generate_post_summary( $this->wp_object );
}
/**
@@ -849,7 +833,8 @@ class Post extends Base {
$template = "[ap_content]\n\n[ap_permalink type=\"html\"]\n\n[ap_hashtags]";
break;
default:
- $template = \get_option( 'activitypub_custom_post_content', ACTIVITYPUB_CUSTOM_POST_CONTENT );
+ // phpcs:ignore Universal.Operators.DisallowShortTernary.Found
+ $template = \get_option( 'activitypub_custom_post_content', ACTIVITYPUB_CUSTOM_POST_CONTENT ) ?: ACTIVITYPUB_CUSTOM_POST_CONTENT;
break;
}
@@ -868,7 +853,12 @@ class Post extends Base {
* @return array The list of @-Mentions.
*/
protected function get_mentions() {
- return apply_filters( 'activitypub_extract_mentions', array(), $this->wp_object->post_content, $this->wp_object );
+ return apply_filters(
+ 'activitypub_extract_mentions',
+ array(),
+ $this->wp_object->post_content . ' ' . $this->wp_object->post_excerpt,
+ $this->wp_object
+ );
}
/**
diff --git a/tests/test-class-activitypub-shortcodes.php b/tests/test-class-activitypub-shortcodes.php
index d3e40703..2db2f2bb 100644
--- a/tests/test-class-activitypub-shortcodes.php
+++ b/tests/test-class-activitypub-shortcodes.php
@@ -89,7 +89,7 @@ class Test_Activitypub_Shortcodes extends WP_UnitTestCase {
$content = do_shortcode( $content );
wp_reset_postdata();
- $this->assertEquals( "
Lorem ipsum […]
\n", $content ); + $this->assertEquals( "Lorem ipsum dolor […]
\n", $content ); Shortcodes::unregister(); } }