PluginProbe
ActivityPub / trunk
ActivityPub vtrunk
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 / functions-comment.php

functions-comment.php in ActivityPub trunk, at includes/functions-comment.php

246 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Comment functions.
4 *
5 * Functions for working with comments in ActivityPub context.
6 *
7 * @package Activitypub
8 */
9
10 namespace Activitypub;
11
12 /**
13 * Get the ActivityPub ID of a Comment by the WordPress Comment ID.
14 *
15 * @param int|\WP_Comment $id The WordPress Comment ID or object.
16 *
17 * @return string The ActivityPub ID (a URL) of the Comment.
18 */
19 function get_comment_id( $id ) {
20 return Comment::generate_id( $id );
21 }
22
23 /**
24 * Get the comment from an ActivityPub Object ID.
25 *
26 * @since 9.1.0 Added the `$args` parameter.
27 *
28 * @param string $id ActivityPub object ID (usually a URL) to check.
29 * @param array $args Optional. Additional WP_Comment_Query arguments.
30 *
31 * @return \WP_Comment|boolean Comment, or false on failure.
32 */
33 function object_id_to_comment( $id, $args = array() ) {
34 return Comment::object_id_to_comment( $id, $args );
35 }
36
37 /**
38 * Verify that URL is a local comment or a previously received remote comment.
39 * (For threading comments locally)
40 *
41 * @param string $url The URL to check.
42 *
43 * @return string|null Comment ID or null if not found
44 */
45 function url_to_commentid( $url ) {
46 return Comment::url_to_commentid( $url );
47 }
48
49 /**
50 * Check if a comment should be federated.
51 *
52 * We consider a comment should be federated if it is authored by a user that is
53 * not disabled for federation and if it is a reply directly to the post or to a
54 * federated comment.
55 *
56 * @param mixed $comment Comment object or ID.
57 *
58 * @return boolean True if the comment should be federated, false otherwise.
59 */
60 function should_comment_be_federated( $comment ) {
61 return Comment::should_be_federated( $comment );
62 }
63
64 /**
65 * Check if a comment was federated.
66 *
67 * This function checks if a comment was federated via ActivityPub.
68 *
69 * @param mixed $comment Comment object or ID.
70 *
71 * @return boolean True if the comment was federated, false otherwise.
72 */
73 function was_comment_sent( $comment ) {
74 return Comment::was_sent( $comment );
75 }
76
77 /**
78 * Check if a comment is federated.
79 *
80 * We consider a comment federated if comment was received via ActivityPub.
81 *
82 * Use this function to check if it is comment that was received via ActivityPub.
83 *
84 * @param mixed $comment Comment object or ID.
85 *
86 * @return boolean True if the comment is federated, false otherwise.
87 */
88 function was_comment_received( $comment ) {
89 return Comment::was_received( $comment );
90 }
91
92 /**
93 * Check if a comment is local only.
94 *
95 * This function checks if a comment is local only and was not sent or received via ActivityPub.
96 *
97 * @param mixed $comment Comment object or ID.
98 *
99 * @return boolean True if the comment is local only, false otherwise.
100 */
101 function is_local_comment( $comment ) {
102 return Comment::is_local( $comment );
103 }
104
105 /**
106 * Retrieves the IDs of the ancestors of a comment.
107 *
108 * Adaption of `get_post_ancestors` from WordPress core.
109 *
110 * @see https://developer.wordpress.org/reference/functions/get_post_ancestors/
111 *
112 * @param int|\WP_Comment $comment Comment ID or comment object.
113 *
114 * @return int[] Array of ancestor IDs.
115 */
116 function get_comment_ancestors( $comment ) {
117 $comment = \get_comment( $comment );
118
119 if ( ! $comment || empty( $comment->comment_parent ) || (int) $comment->comment_parent === (int) $comment->comment_ID ) {
120 return array();
121 }
122
123 $ancestors = array();
124
125 $id = (int) $comment->comment_parent;
126 $ancestors[] = $id;
127
128 while ( $id > 0 ) {
129 $ancestor = \get_comment( $id );
130
131 if ( ! $ancestor ) {
132 break;
133 }
134
135 $parent_id = (int) $ancestor->comment_parent;
136
137 // Loop detection: If the ancestor has been seen before, break.
138 if ( empty( $parent_id ) || ( $parent_id === (int) $comment->comment_ID ) || \in_array( $parent_id, $ancestors, true ) ) {
139 break;
140 }
141
142 $id = $parent_id;
143 $ancestors[] = $id;
144 }
145
146 return $ancestors;
147 }
148
149 /**
150 * Registers a ActivityPub comment type.
151 *
152 * @param string $comment_type Key for comment type.
153 * @param array $args Optional. Array of arguments for registering a comment type. Default empty array.
154 *
155 * @return array The registered Activitypub comment type.
156 */
157 function register_comment_type( $comment_type, $args = array() ) {
158 global $activitypub_comment_types;
159
160 if ( ! \is_array( $activitypub_comment_types ) ) {
161 $activitypub_comment_types = array();
162 }
163
164 // Sanitize comment type name.
165 $comment_type = \sanitize_key( $comment_type );
166
167 $activitypub_comment_types[ $comment_type ] = $args;
168
169 /**
170 * Fires after a ActivityPub comment type is registered.
171 *
172 * @param string $comment_type Comment type.
173 * @param array $args Arguments used to register the comment type.
174 */
175 \do_action( 'activitypub_registered_comment_type', $comment_type, $args );
176
177 return $args;
178 }
179
180 /**
181 * Get the reply intent URI as a JavaScript URI.
182 *
183 * @return string The reply intent URI.
184 */
185 function get_reply_intent_js() {
186 return \sprintf(
187 'javascript:(()=>{window.open(\'%s\'+encodeURIComponent(window.location.href));})();',
188 get_reply_intent_url()
189 );
190 }
191
192 /**
193 * Get the reply intent URI.
194 *
195 * @return string The reply intent URI.
196 */
197 function get_reply_intent_url() {
198 /**
199 * Filters the reply intent parameters.
200 *
201 * @param array $params The reply intent parameters.
202 */
203 $params = \apply_filters( 'activitypub_reply_intent_params', array() );
204
205 $params += array( 'in_reply_to' => '' );
206 $query = \http_build_query( $params );
207 $path = 'post-new.php?' . $query;
208 $url = \admin_url( $path );
209
210 /**
211 * Filters the reply intent URL.
212 *
213 * @param string $url The reply intent URL.
214 */
215 $url = \apply_filters( 'activitypub_reply_intent_url', $url );
216
217 return \esc_url_raw( $url );
218 }
219
220 /**
221 * Get a reaction author's display name as readable plain text.
222 *
223 * Shared by the reactions REST route and the block's server render so both produce the
224 * same value for the same comment: they feed the same Interactivity template, and
225 * `view.js` swaps the rendered items for the fetched ones wholesale.
226 *
227 * This reads the raw column rather than `get_comment_author()`, so it does not pick up
228 * the emoji rendering that the comment list applies. That is deliberate for a
229 * plain-text field.
230 *
231 * `wp_insert_comment()` callers bypass core's `pre_comment_author_name` chain, so the
232 * column is not guaranteed tag-free, which is why this cleans rather than just reads.
233 *
234 * @since 9.3.0
235 *
236 * @param \WP_Comment $comment The comment.
237 *
238 * @return string The author name as plain text. May contain `&` as a character,
239 * so it is safe for a text sink only, never for HTML.
240 */
241 function get_reaction_author_name( $comment ) {
242 // Core stores this column entity-escaped, so decode for the text sinks; stripping after the
243 // decode is what keeps an encoded tag from coming back to life.
244 return \wp_strip_all_tags( \html_entity_decode( $comment->comment_author, ENT_QUOTES, 'UTF-8' ) );
245 }
246