PluginProbe
ActivityPub / 9.2.1
ActivityPub v9.2.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 +63 -86 1.2.09.2.1 View file →
@@ -1,118 +1,95 @@
1 1 <?php
2 +/**
3 + * Mention class file.
4 + *
5 + * @package Activitypub
6 + */
7 +
2 8 namespace Activitypub;
3 9
4 -use WP_Error;
5 -use Activitypub\Webfinger;
10 +use Activitypub\Collection\Remote_Actors;
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 - \add_filter( 'the_content', array( self::class, 'the_content' ), 99, 2 );
22 + \add_filter( 'the_content', array( self::class, 'the_content' ), 99 );
23 + \add_filter( 'comment_text', array( self::class, 'the_content' ) );
24 + \add_filter( 'activitypub_extra_field_content', array( self::class, 'the_content' ) );
18 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 );
19 27 }
20 28
21 29 /**
22 - * 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.
23 32 *
24 - * @param string $the_content the post-content
33 + * @param array $object_array Array of activity.
25 34 *
26 - * @return string the filtered post-content
35 + * @return array The activity object array.
27 36 */
28 - public static function the_content( $the_content ) {
29 - // small protection against execution timeouts: limit to 1 MB
30 - if ( mb_strlen( $the_content ) > MB_IN_BYTES ) {
31 - 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'] );
32 40 }
33 - $tag_stack = array();
34 - $protected_tags = array(
35 - 'pre',
36 - 'code',
37 - 'textarea',
38 - 'style',
39 - 'a',
40 - );
41 - $content_with_links = '';
42 - $in_protected_tag = false;
43 - foreach ( wp_html_split( $the_content ) as $chunk ) {
44 - if ( preg_match( '#^<!--[\s\S]*-->$#i', $chunk, $m ) ) {
45 - $content_with_links .= $chunk;
46 - continue;
47 - }
48 41
49 - if ( preg_match( '#^<(/)?([a-z-]+)\b[^>]*>$#i', $chunk, $m ) ) {
50 - $tag = strtolower( $m[2] );
51 - if ( '/' === $m[1] ) {
52 - // Closing tag.
53 - $i = array_search( $tag, $tag_stack );
54 - // We can only remove the tag from the stack if it is in the stack.
55 - if ( false !== $i ) {
56 - $tag_stack = array_slice( $tag_stack, 0, $i );
57 - }
58 - } else {
59 - // Opening tag, add it to the stack.
60 - $tag_stack[] = $tag;
61 - }
42 + if ( ! empty( $object_array['content'] ) ) {
43 + $object_array['content'] = self::the_content( $object_array['content'] );
44 + }
62 45
63 - // If we're in a protected tag, the tag_stack contains at least one protected tag string.
64 - // The protected tag state can only change when we encounter a start or end tag.
65 - $in_protected_tag = array_intersect( $tag_stack, $protected_tags );
46 + return $object_array;
47 + }
66 48
67 - // Never inspect tags.
68 - $content_with_links .= $chunk;
69 - continue;
70 - }
71 -
72 - if ( $in_protected_tag ) {
73 - // Don't inspect a chunk inside an inspected tag.
74 - $content_with_links .= $chunk;
75 - continue;
76 - }
77 -
78 - // Only reachable when there is no protected tag in the stack.
79 - $content_with_links .= \preg_replace_callback( '/@' . ACTIVITYPUB_USERNAME_REGEXP . '/', array( self::class, 'replace_with_links' ), $chunk );
80 - }
81 -
82 - 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' ) );
83 58 }
84 59
85 60 /**
86 - * A callback for preg_replace to build the user links
61 + * A callback for preg_replace to build the user links.
87 62 *
88 - * @param array $result the preg_match results
63 + * @param array $result The preg_match results.
89 64 *
90 - * @return string the final string
65 + * @return string The final string.
91 66 */
92 67 public static function replace_with_links( $result ) {
93 - $metadata = get_remote_metadata_by_actor( $result[0] );
68 + $post = Remote_Actors::fetch_by_acct( $result[0] );
94 69
95 - if ( ! empty( $metadata ) && ! is_wp_error( $metadata ) && ! empty( $metadata['url'] ) ) {
96 - $username = ltrim( $result[0], '@' );
97 - if ( ! empty( $metadata['name'] ) ) {
98 - $username = $metadata['name'];
99 - }
100 - if ( ! empty( $metadata['preferredUsername'] ) ) {
101 - $username = $metadata['preferredUsername'];
102 - }
103 - return \sprintf( '<a rel="mention" class="u-url mention" href="%s">@<span>%s</span></a>', esc_url( $metadata['url'] ), esc_html( $username ) );
70 + if ( \is_wp_error( $post ) ) {
71 + return $result[0];
104 72 }
105 73
106 - return $result[0];
74 + $actor = Remote_Actors::get_actor( $post );
75 +
76 + if ( \is_wp_error( $actor ) ) {
77 + return $result[0];
78 + }
79 +
80 + $username = $actor->get_preferred_username() ?: $actor->get_name() ?: Sanitize::webfinger( $result[0] );
81 + $url = object_to_uri( $actor->get_url() ?: $actor->get_id() );
82 +
83 + return \sprintf( '<a rel="mention" class="u-url mention" href="%1$s">@%2$s</a>', \esc_url( $url ), \esc_html( $username ) );
107 84 }
108 85
109 86 /**
110 - * Get the Inboxes for the mentioned Actors
87 + * Get the Inboxes for the mentioned Actors.
111 88 *
112 - * @param array $mentioned The list of Actors that were mentioned
89 + * @param array $mentioned The list of Actors that were mentioned.
113 90 *
114 - * @return array The list of Inboxes
91 + * @return array The list of Inboxes.
115 92 */
116 93 public static function get_inboxes( $mentioned ) {
117 94 $inboxes = array();
118 95
@@ -118,9 +95,9 @@
118 95
119 96 foreach ( $mentioned as $actor ) {
120 97 $inbox = self::get_inbox_by_mentioned_actor( $actor );
121 98
122 - if ( ! is_wp_error( $inbox ) && $inbox ) {
99 + if ( ! \is_wp_error( $inbox ) && $inbox ) {
123 100 $inboxes[] = $inbox;
124 101 }
125 102 }
126 103
@@ -127,13 +104,13 @@
127 104 return $inboxes;
128 105 }
129 106
130 107 /**
131 - * Get the inbox from the Remote-Profile of a mentioned Actor
108 + * Get the inbox from the Remote-Profile of a mentioned Actor.
132 109 *
133 - * @param string $actor The Actor-URL
110 + * @param string $actor The Actor URL.
134 111 *
135 - * @return string The Inbox-URL
112 + * @return string|\WP_Error The Inbox-URL or WP_Error if not found.
136 113 */
137 114 public static function get_inbox_by_mentioned_actor( $actor ) {
138 115 $metadata = get_remote_metadata_by_actor( $actor );
139 116
@@ -140,9 +117,9 @@
140 117 if ( \is_wp_error( $metadata ) ) {
141 118 return $metadata;
142 119 }
143 120
144 - if ( isset( $metadata['endpoints'] ) && isset( $metadata['endpoints']['sharedInbox'] ) ) {
121 + if ( isset( $metadata['endpoints']['sharedInbox'] ) ) {
145 122 return $metadata['endpoints']['sharedInbox'];
146 123 }
147 124
148 125 if ( \array_key_exists( 'inbox', $metadata ) ) {
@@ -148,26 +125,26 @@
148 125 if ( \array_key_exists( 'inbox', $metadata ) ) {
149 126 return $metadata['inbox'];
150 127 }
151 128
152 - return new WP_Error( 'activitypub_no_inbox', \__( 'No "Inbox" found', 'activitypub' ), $metadata );
129 + return new \WP_Error( 'activitypub_no_inbox', \__( 'No "Inbox" found', 'activitypub' ), $metadata );
153 130 }
154 131
155 132 /**
156 133 * Extract the mentions from the post_content.
157 134 *
158 - * @param array $mentions The already found mentions.
135 + * @param array $mentions The already found mentions.
159 136 * @param string $post_content The post content.
160 137 *
161 - * @return mixed The discovered mentions.
138 + * @return array The discovered mentions.
162 139 */
163 140 public static function extract_mentions( $mentions, $post_content ) {
164 141 \preg_match_all( '/@' . ACTIVITYPUB_USERNAME_REGEXP . '/i', $post_content, $matches );
165 142 foreach ( $matches[0] as $match ) {
166 143 $link = Webfinger::resolve( $match );
167 - if ( ! is_wp_error( $link ) ) {
144 + if ( ! \is_wp_error( $link ) ) {
168 145 $mentions[ $match ] = $link;
169 146 }
170 147 }
171 - return $mentions;
148 + return \array_unique( $mentions );
172 149 }
173 150 }