PluginProbe
ActivityPub / 2.5.0
ActivityPub v2.5.0
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
activitypub / includes / transformer / class-comment.php

class-comment.php in ActivityPub 2.5.0, at includes/transformer/class-comment.php

293 lines 7.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Activitypub\Transformer;
3
4 use WP_Comment;
5 use WP_Comment_Query;
6
7 use Activitypub\Webfinger;
8 use Activitypub\Comment as Comment_Utils;
9 use Activitypub\Model\Blog;
10 use Activitypub\Collection\Users;
11 use Activitypub\Transformer\Base;
12
13 use function Activitypub\is_single_user;
14 use function Activitypub\get_rest_url_by_path;
15 use function Activitypub\get_comment_ancestors;
16
17 /**
18 * WordPress Comment Transformer
19 *
20 * The Comment Transformer is responsible for transforming a WP_Comment object into different
21 * Object-Types.
22 *
23 * Currently supported are:
24 *
25 * - Activitypub\Activity\Base_Object
26 */
27 class Comment extends Base {
28 /**
29 * Returns the User-ID of the WordPress Comment.
30 *
31 * @return int The User-ID of the WordPress Comment
32 */
33 public function get_wp_user_id() {
34 return $this->wp_object->user_id;
35 }
36
37 /**
38 * Change the User-ID of the WordPress Comment.
39 *
40 * @return int The User-ID of the WordPress Comment
41 */
42 public function change_wp_user_id( $user_id ) {
43 $this->wp_object->user_id = $user_id;
44 }
45
46 /**
47 * Transforms the WP_Comment object to an ActivityPub Object
48 *
49 * @see \Activitypub\Activity\Base_Object
50 *
51 * @return \Activitypub\Activity\Base_Object The ActivityPub Object
52 */
53 public function to_object() {
54 $comment = $this->wp_object;
55 $object = parent::to_object();
56
57 $object->set_url( $this->get_id() );
58 $object->set_type( 'Note' );
59
60 $published = \strtotime( $comment->comment_date_gmt );
61 $object->set_published( \gmdate( 'Y-m-d\TH:i:s\Z', $published ) );
62
63 $updated = \get_comment_meta( $comment->comment_ID, 'activitypub_comment_modified', true );
64 if ( $updated > $published ) {
65 $object->set_updated( \gmdate( 'Y-m-d\TH:i:s\Z', $updated ) );
66 }
67
68 $object->set_content_map(
69 array(
70 $this->get_locale() => $this->get_content(),
71 )
72 );
73 $path = sprintf( 'actors/%d/followers', intval( $comment->comment_author ) );
74
75 $object->set_to(
76 array(
77 'https://www.w3.org/ns/activitystreams#Public',
78 get_rest_url_by_path( $path ),
79 )
80 );
81
82 return $object;
83 }
84
85 /**
86 * Returns the User-URL of the Author of the Post.
87 *
88 * If `single_user` mode is enabled, the URL of the Blog-User is returned.
89 *
90 * @return string The User-URL.
91 */
92 protected function get_attributed_to() {
93 if ( is_single_user() ) {
94 $user = new Blog();
95 return $user->get_url();
96 }
97
98 return Users::get_by_id( $this->wp_object->user_id )->get_url();
99 }
100
101 /**
102 * Returns the content for the ActivityPub Item.
103 *
104 * The content will be generated based on the user settings.
105 *
106 * @return string The content.
107 */
108 protected function get_content() {
109 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
110 $comment = $this->wp_object;
111 $content = $comment->comment_content;
112
113 $content = \apply_filters( 'comment_text', $content, $comment, array() );
114 $content = \preg_replace( '/[\n\r\t]/', '', $content );
115 $content = \trim( $content );
116 $content = \apply_filters( 'activitypub_the_content', $content, $comment );
117
118 return $content;
119 }
120
121 /**
122 * Returns the in-reply-to for the ActivityPub Item.
123 *
124 * @return int The URL of the in-reply-to.
125 */
126 protected function get_in_reply_to() {
127 $comment = $this->wp_object;
128
129 $parent_comment = null;
130 $in_reply_to = null;
131
132 if ( $comment->comment_parent ) {
133 $parent_comment = \get_comment( $comment->comment_parent );
134 }
135
136 if ( $parent_comment ) {
137 $comment_meta = \get_comment_meta( $parent_comment->comment_ID );
138
139 if ( ! empty( $comment_meta['source_id'][0] ) ) {
140 $in_reply_to = $comment_meta['source_id'][0];
141 } elseif ( ! empty( $comment_meta['source_url'][0] ) ) {
142 $in_reply_to = $comment_meta['source_url'][0];
143 } elseif ( ! empty( $parent_comment->user_id ) ) {
144 $in_reply_to = Comment_Utils::generate_id( $parent_comment );
145 }
146 } else {
147 $in_reply_to = \get_permalink( $comment->comment_post_ID );
148 }
149
150 return $in_reply_to;
151 }
152
153 /**
154 * Returns the ID of the ActivityPub Object.
155 *
156 * @see https://www.w3.org/TR/activitypub/#obj-id
157 * @see https://github.com/tootsuite/mastodon/issues/13879
158 *
159 * @return string ActivityPub URI for comment
160 */
161 protected function get_id() {
162 $comment = $this->wp_object;
163 return Comment_Utils::generate_id( $comment );
164 }
165
166 /**
167 * Returns a list of Mentions, used in the Comment.
168 *
169 * @see https://docs.joinmastodon.org/spec/activitypub/#Mention
170 *
171 * @return array The list of Mentions.
172 */
173 protected function get_cc() {
174 $cc = array();
175
176 $mentions = $this->get_mentions();
177 if ( $mentions ) {
178 foreach ( $mentions as $url ) {
179 $cc[] = $url;
180 }
181 }
182
183 return array_unique( $cc );
184 }
185
186 /**
187 * Returns a list of Tags, used in the Comment.
188 *
189 * This includes Hash-Tags and Mentions.
190 *
191 * @return array The list of Tags.
192 */
193 protected function get_tag() {
194 $tags = array();
195
196 $mentions = $this->get_mentions();
197 if ( $mentions ) {
198 foreach ( $mentions as $mention => $url ) {
199 $tag = array(
200 'type' => 'Mention',
201 'href' => \esc_url( $url ),
202 'name' => \esc_html( $mention ),
203 );
204 $tags[] = $tag;
205 }
206 }
207
208 return \array_unique( $tags, SORT_REGULAR );
209 }
210
211 /**
212 * Helper function to get the @-Mentions from the comment content.
213 *
214 * @return array The list of @-Mentions.
215 */
216 protected function get_mentions() {
217 \add_filter( 'activitypub_extract_mentions', array( $this, 'extract_reply_context' ) );
218
219 return apply_filters( 'activitypub_extract_mentions', array(), $this->wp_object->comment_content, $this->wp_object );
220 }
221
222 /**
223 * Gets the ancestors of the comment, but only the ones that are ActivityPub comments.
224 *
225 * @return array The list of ancestors.
226 */
227 protected function get_comment_ancestors() {
228 $ancestors = get_comment_ancestors( $this->wp_object );
229
230 // Now that we have the full tree of ancestors, only return the ones received from the fediverse
231 return array_filter(
232 $ancestors,
233 function ( $comment_id ) {
234 return \get_comment_meta( $comment_id, 'protocol', true ) === 'activitypub';
235 }
236 );
237 }
238
239 /**
240 * Collect all other Users that participated in this comment-thread
241 * to send them a notification about the new reply.
242 *
243 * @param array $mentions The already mentioned ActivityPub users
244 *
245 * @return array The list of all Repliers.
246 */
247 public function extract_reply_context( $mentions ) {
248 // Check if `$this->wp_object` is a WP_Comment
249 if ( 'WP_Comment' !== get_class( $this->wp_object ) ) {
250 return $mentions;
251 }
252
253 $ancestors = $this->get_comment_ancestors();
254 if ( ! $ancestors ) {
255 return $mentions;
256 }
257
258 foreach ( $ancestors as $comment_id ) {
259 $comment = \get_comment( $comment_id );
260 if ( $comment && ! empty( $comment->comment_author_url ) ) {
261 $acct = Webfinger::uri_to_acct( $comment->comment_author_url );
262 if ( $acct && ! is_wp_error( $acct ) ) {
263 $acct = str_replace( 'acct:', '@', $acct );
264 $mentions[ $acct ] = $comment->comment_author_url;
265 }
266 }
267 }
268
269 return $mentions;
270 }
271
272 /**
273 * Returns the locale of the post.
274 *
275 * @return string The locale of the post.
276 */
277 public function get_locale() {
278 $comment_id = $this->wp_object->ID;
279 $lang = \strtolower( \strtok( \get_locale(), '_-' ) );
280
281 /**
282 * Filter the locale of the comment.
283 *
284 * @param string $lang The locale of the comment.
285 * @param int $comment_id The comment ID.
286 * @param WP_Post $post The comment object.
287 *
288 * @return string The filtered locale of the comment.
289 */
290 return apply_filters( 'activitypub_comment_locale', $lang, $comment_id, $this->wp_object );
291 }
292 }
293