PluginProbe
ActivityPub / 5.3.1
ActivityPub v5.3.1
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
← All changes | includes/class-mention.php +50 -76 2.1.05.3.1 View file →
@@ -1,100 +1,78 @@
1 1 <?php
2 +/**
3 + * Mention class file.
4 + *
5 + * @package Activitypub
6 + */
7 +
2 8 namespace Activitypub;
3 9
4 10 use WP_Error;
5 -use Activitypub\Webfinger;
6 11
7 12 /**
8 - * ActivityPub Mention Class
13 + * ActivityPub Mention Class.
9 14 *
10 15 * @author Alex Kirk
11 16 */
12 17 class Mention {
13 18 /**
14 - * Initialize the class, registering WordPress hooks
19 + * Initialize the class, registering WordPress hooks.
15 20 */
16 21 public static function init() {
17 22 \add_filter( 'the_content', array( self::class, 'the_content' ), 99, 1 );
18 23 \add_filter( 'comment_text', array( self::class, 'the_content' ), 10, 1 );
24 + \add_filter( 'activitypub_extra_field_content', array( self::class, 'the_content' ), 10, 1 );
19 25 \add_filter( 'activitypub_extract_mentions', array( self::class, 'extract_mentions' ), 99, 2 );
26 + \add_filter( 'activitypub_activity_object_array', array( self::class, 'filter_activity_object' ), 99 );
20 27 }
21 28
22 29 /**
23 - * Filter to replace the mentions in the content with links
30 + * Filter only the activity object and replace summery it with URLs
31 + * add tag to user.
24 32 *
25 - * @param string $the_content the post-content
33 + * @param array $object_array Array of activity.
26 34 *
27 - * @return string the filtered post-content
35 + * @return array The activity object array.
28 36 */
29 - public static function the_content( $the_content ) {
30 - // small protection against execution timeouts: limit to 1 MB
31 - if ( mb_strlen( $the_content ) > MB_IN_BYTES ) {
32 - return $the_content;
37 + public static function filter_activity_object( $object_array ) {
38 + if ( ! empty( $object_array['summary'] ) ) {
39 + $object_array['summary'] = self::the_content( $object_array['summary'] );
33 40 }
34 - $tag_stack = array();
35 - $protected_tags = array(
36 - 'pre',
37 - 'code',
38 - 'textarea',
39 - 'style',
40 - 'a',
41 - );
42 - $content_with_links = '';
43 - $in_protected_tag = false;
44 - foreach ( wp_html_split( $the_content ) as $chunk ) {
45 - if ( preg_match( '#^<!--[\s\S]*-->$#i', $chunk, $m ) ) {
46 - $content_with_links .= $chunk;
47 - continue;
48 - }
49 41
50 - if ( preg_match( '#^<(/)?([a-z-]+)\b[^>]*>$#i', $chunk, $m ) ) {
51 - $tag = strtolower( $m[2] );
52 - if ( '/' === $m[1] ) {
53 - // Closing tag.
54 - $i = array_search( $tag, $tag_stack );
55 - // We can only remove the tag from the stack if it is in the stack.
56 - if ( false !== $i ) {
57 - $tag_stack = array_slice( $tag_stack, 0, $i );
58 - }
59 - } else {
60 - // Opening tag, add it to the stack.
61 - $tag_stack[] = $tag;
62 - }
42 + if ( ! empty( $object_array['content'] ) ) {
43 + $object_array['content'] = self::the_content( $object_array['content'] );
44 + }
63 45
64 - // If we're in a protected tag, the tag_stack contains at least one protected tag string.
65 - // The protected tag state can only change when we encounter a start or end tag.
66 - $in_protected_tag = array_intersect( $tag_stack, $protected_tags );
46 + return $object_array;
47 + }
67 48
68 - // Never inspect tags.
69 - $content_with_links .= $chunk;
70 - continue;
71 - }
72 -
73 - if ( $in_protected_tag ) {
74 - // Don't inspect a chunk inside an inspected tag.
75 - $content_with_links .= $chunk;
76 - continue;
77 - }
78 -
79 - // Only reachable when there is no protected tag in the stack.
80 - $content_with_links .= \preg_replace_callback( '/@' . ACTIVITYPUB_USERNAME_REGEXP . '/', array( self::class, 'replace_with_links' ), $chunk );
81 - }
82 -
83 - return $content_with_links;
49 + /**
50 + * Filter to replace the mentions in the content with links.
51 + *
52 + * @param string $the_content The post content.
53 + *
54 + * @return string The filtered post-content.
55 + */
56 + public static function the_content( $the_content ) {
57 + return enrich_content_data( $the_content, '/@' . ACTIVITYPUB_USERNAME_REGEXP . '/', array( self::class, 'replace_with_links' ) );
84 58 }
85 59
86 60 /**
87 - * A callback for preg_replace to build the user links
61 + * A callback for preg_replace to build the user links.
88 62 *
89 - * @param array $result the preg_match results
63 + * @param array $result The preg_match results.
90 64 *
91 - * @return string the final string
65 + * @return string The final string.
92 66 */
93 67 public static function replace_with_links( $result ) {
94 68 $metadata = get_remote_metadata_by_actor( $result[0] );
95 69
96 - if ( ! empty( $metadata ) && ! is_wp_error( $metadata ) && ! empty( $metadata['url'] ) ) {
70 + if (
71 + ! empty( $metadata ) &&
72 + ! is_wp_error( $metadata ) &&
73 + ( ! empty( $metadata['id'] ) || ! empty( $metadata['url'] ) )
74 + ) {
97 75 $username = ltrim( $result[0], '@' );
98 76 if ( ! empty( $metadata['name'] ) ) {
99 77 $username = $metadata['name'];
100 78 }
@@ -101,14 +79,10 @@
101 79 if ( ! empty( $metadata['preferredUsername'] ) ) {
102 80 $username = $metadata['preferredUsername'];
103 81 }
104 82
105 - $url = isset( $metadata['url'] ) ? $metadata['url'] : $metadata['id'];
83 + $url = isset( $metadata['url'] ) ? object_to_uri( $metadata['url'] ) : object_to_uri( $metadata['id'] );
106 84
107 - if ( \is_array( $url ) ) {
108 - $url = $url[0];
109 - }
110 -
111 85 return \sprintf( '<a rel="mention" class="u-url mention" href="%s">@<span>%s</span></a>', esc_url( $url ), esc_html( $username ) );
112 86 }
113 87
114 88 return $result[0];
@@ -114,13 +88,13 @@
114 88 return $result[0];
115 89 }
116 90
117 91 /**
118 - * Get the Inboxes for the mentioned Actors
92 + * Get the Inboxes for the mentioned Actors.
119 93 *
120 - * @param array $mentioned The list of Actors that were mentioned
94 + * @param array $mentioned The list of Actors that were mentioned.
121 95 *
122 - * @return array The list of Inboxes
96 + * @return array The list of Inboxes.
123 97 */
124 98 public static function get_inboxes( $mentioned ) {
125 99 $inboxes = array();
126 100
@@ -135,13 +109,13 @@
135 109 return $inboxes;
136 110 }
137 111
138 112 /**
139 - * Get the inbox from the Remote-Profile of a mentioned Actor
113 + * Get the inbox from the Remote-Profile of a mentioned Actor.
140 114 *
141 - * @param string $actor The Actor-URL
115 + * @param string $actor The Actor URL.
142 116 *
143 - * @return string The Inbox-URL
117 + * @return string|WP_Error The Inbox-URL or WP_Error if not found.
144 118 */
145 119 public static function get_inbox_by_mentioned_actor( $actor ) {
146 120 $metadata = get_remote_metadata_by_actor( $actor );
147 121
@@ -148,9 +122,9 @@
148 122 if ( \is_wp_error( $metadata ) ) {
149 123 return $metadata;
150 124 }
151 125
152 - if ( isset( $metadata['endpoints'] ) && isset( $metadata['endpoints']['sharedInbox'] ) ) {
126 + if ( isset( $metadata['endpoints']['sharedInbox'] ) ) {
153 127 return $metadata['endpoints']['sharedInbox'];
154 128 }
155 129
156 130 if ( \array_key_exists( 'inbox', $metadata ) ) {
@@ -162,12 +136,12 @@
162 136
163 137 /**
164 138 * Extract the mentions from the post_content.
165 139 *
166 - * @param array $mentions The already found mentions.
140 + * @param array $mentions The already found mentions.
167 141 * @param string $post_content The post content.
168 142 *
169 - * @return mixed The discovered mentions.
143 + * @return array The discovered mentions.
170 144 */
171 145 public static function extract_mentions( $mentions, $post_content ) {
172 146 \preg_match_all( '/@' . ACTIVITYPUB_USERNAME_REGEXP . '/i', $post_content, $matches );
173 147 foreach ( $matches[0] as $match ) {
@@ -175,7 +149,7 @@
175 149 if ( ! is_wp_error( $link ) ) {
176 150 $mentions[ $match ] = $link;
177 151 }
178 152 }
179 - return $mentions;
153 + return \array_unique( $mentions );
180 154 }
181 155 }