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

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

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