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
activitypub / includes / collection / class-extra-fields.php

class-extra-fields.php in ActivityPub 5.3.1, at includes/collection/class-extra-fields.php

301 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Extra Fields collection file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Collection;
9
10 use Activitypub\Link;
11
12 use function Activitypub\site_supports_blocks;
13
14 /**
15 * Extra Fields collection.
16 */
17 class Extra_Fields {
18
19 const USER_POST_TYPE = 'ap_extrafield';
20 const BLOG_POST_TYPE = 'ap_extrafield_blog';
21
22 /**
23 * Get the extra fields for a user.
24 *
25 * @param int $user_id The user ID.
26 *
27 * @return \WP_Post[] The extra fields.
28 */
29 public static function get_actor_fields( $user_id ) {
30 $is_blog = self::is_blog( $user_id );
31 $post_type = $is_blog ? self::BLOG_POST_TYPE : self::USER_POST_TYPE;
32 $args = array(
33 'post_type' => $post_type,
34 'nopaging' => true,
35 'orderby' => 'menu_order',
36 'order' => 'ASC',
37 );
38 if ( ! $is_blog ) {
39 $args['author'] = $user_id;
40 }
41
42 $query = new \WP_Query( $args );
43 $fields = $query->posts ?? array();
44
45 /**
46 * Filters the extra fields for an ActivityPub actor.
47 *
48 * This filter allows developers to modify or add custom fields to an actor's
49 * profile.
50 *
51 * @param \WP_Post[] $fields Array of WP_Post objects representing the extra fields.
52 * @param int $user_id The ID of the user whose fields are being retrieved.
53 */
54 return apply_filters( 'activitypub_get_actor_extra_fields', $fields, $user_id );
55 }
56
57 /**
58 * Get formatted content for an extra field.
59 *
60 * @param \WP_Post $post The post.
61 *
62 * @return string The formatted content.
63 */
64 public static function get_formatted_content( $post ) {
65 $content = \get_the_content( null, false, $post );
66 $content = Link::the_content( $content, true );
67 if ( site_supports_blocks() ) {
68 $content = \do_blocks( $content );
69 }
70 $content = \wptexturize( $content );
71 $content = \wp_filter_content_tags( $content );
72
73 // Replace script and style elements.
74 $content = \preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $content );
75 $content = \strip_shortcodes( $content );
76 $content = \trim( \preg_replace( '/[\n\r\t]/', '', $content ) );
77
78 /**
79 * Filters the content of an extra field.
80 *
81 * @param string $content The content.
82 * @param \WP_Post $post The post.
83 */
84 return \apply_filters( 'activitypub_extra_field_content', $content, $post );
85 }
86
87 /**
88 * Transforms the Extra Fields (Custom Post Types) to ActivityPub Actor-Attachments.
89 *
90 * @param \WP_Post[] $fields The extra fields.
91 *
92 * @return array ActivityPub attachments.
93 */
94 public static function fields_to_attachments( $fields ) {
95 $attachments = array();
96 \add_filter( 'activitypub_link_rel', array( self::class, 'add_rel_me' ) );
97
98 foreach ( $fields as $post ) {
99 $content = self::get_formatted_content( $post );
100 $attachments[] = array(
101 'type' => 'PropertyValue',
102 'name' => \get_the_title( $post ),
103 'value' => \html_entity_decode(
104 $content,
105 \ENT_QUOTES,
106 'UTF-8'
107 ),
108 );
109
110 $attachment = false;
111
112 // Add support for FEP-fb2a, for more information see FEDERATION.md.
113 $link_content = \trim( \strip_tags( $content, '<a>' ) );
114 if (
115 \stripos( $link_content, '<a' ) === 0 &&
116 \stripos( $link_content, '<a', 3 ) === false &&
117 \stripos( $link_content, '</a>', \strlen( $link_content ) - 4 ) !== false &&
118 \class_exists( '\WP_HTML_Tag_Processor' )
119 ) {
120 $tags = new \WP_HTML_Tag_Processor( $link_content );
121 $tags->next_tag( 'A' );
122
123 if ( 'A' === $tags->get_tag() ) {
124 $attachment = array(
125 'type' => 'Link',
126 'name' => \get_the_title( $post ),
127 'href' => \esc_url( $tags->get_attribute( 'href' ) ),
128 );
129
130 $rel = $tags->get_attribute( 'rel' );
131
132 if ( $rel && \is_string( $rel ) ) {
133 $attachment['rel'] = \explode( ' ', $rel );
134 }
135 }
136 }
137
138 if ( ! $attachment ) {
139 $attachment = array(
140 'type' => 'Note',
141 'name' => \get_the_title( $post ),
142 'content' => \html_entity_decode(
143 $content,
144 \ENT_QUOTES,
145 'UTF-8'
146 ),
147 );
148 }
149
150 $attachments[] = $attachment;
151 }
152
153 \remove_filter( 'activitypub_link_rel', array( self::class, 'add_rel_me' ) );
154
155 return $attachments;
156 }
157
158 /**
159 * Check if a post type is an extra fields post type.
160 *
161 * @param string $post_type The post type.
162 *
163 * @return bool True if the post type is an extra fields post type, otherwise false.
164 */
165 public static function is_extra_fields_post_type( $post_type ) {
166 return \in_array( $post_type, array( self::USER_POST_TYPE, self::BLOG_POST_TYPE ), true );
167 }
168
169 /**
170 * Check if a post type is the `ap_extrafield` post type.
171 *
172 * @param string $post_type The post type.
173 *
174 * @return bool True if the post type is `ap_extrafield`, otherwise false.
175 */
176 public static function is_extra_field_post_type( $post_type ) {
177 return self::USER_POST_TYPE === $post_type;
178 }
179
180 /**
181 * Check if a post type is the `ap_extrafield_blog` post type.
182 *
183 * @param string $post_type The post type.
184 *
185 * @return bool True if the post type is `ap_extrafield_blog`, otherwise false.
186 */
187 public static function is_extra_field_blog_post_type( $post_type ) {
188 return self::BLOG_POST_TYPE === $post_type;
189 }
190
191 /**
192 * Add default extra fields to an actor.
193 *
194 * @param array $extra_fields The extra fields.
195 * @param int $user_id The User-ID.
196 *
197 * @return array The extra fields.
198 */
199 public static function default_actor_extra_fields( $extra_fields, $user_id ) {
200 // We'll only take action when there are none yet.
201 if ( ! empty( $extra_fields ) ) {
202 return $extra_fields;
203 }
204
205 $is_blog = self::is_blog( $user_id );
206 $already_migrated = $is_blog
207 ? \get_option( 'activitypub_default_extra_fields' )
208 : \get_user_meta( $user_id, 'activitypub_default_extra_fields', true );
209
210 if ( $already_migrated ) {
211 return $extra_fields;
212 }
213
214 \add_filter(
215 'activitypub_link_rel',
216 function ( $rel ) {
217 $rel .= ' me';
218
219 return $rel;
220 }
221 );
222
223 $defaults = array(
224 \__( 'Blog', 'activitypub' ) => \home_url( '/' ),
225 );
226
227 if ( ! $is_blog ) {
228 $author_url = \get_the_author_meta( 'user_url', $user_id );
229 $author_posts_url = \get_author_posts_url( $user_id );
230
231 $defaults[ \__( 'Profile', 'activitypub' ) ] = $author_posts_url;
232 if ( $author_url !== $author_posts_url ) {
233 $defaults[ \__( 'Homepage', 'activitypub' ) ] = $author_url;
234 }
235 }
236
237 $post_type = $is_blog ? self::BLOG_POST_TYPE : self::USER_POST_TYPE;
238 $menu_order = 10;
239
240 foreach ( $defaults as $title => $url ) {
241 if ( ! $url ) {
242 continue;
243 }
244
245 $extra_field = array(
246 'post_type' => $post_type,
247 'post_title' => $title,
248 'post_status' => 'publish',
249 'post_author' => $user_id,
250 'post_content' => self::make_paragraph_block( Link::the_content( $url ) ),
251 'comment_status' => 'closed',
252 'menu_order' => $menu_order,
253 );
254
255 $menu_order += 10;
256 $extra_field_id = wp_insert_post( $extra_field );
257 $extra_fields[] = get_post( $extra_field_id );
258 }
259
260 $is_blog
261 ? \update_option( 'activitypub_default_extra_fields', true )
262 : \update_user_meta( $user_id, 'activitypub_default_extra_fields', true );
263
264 return $extra_fields;
265 }
266
267 /**
268 * Create a paragraph block.
269 *
270 * @param string $content The content.
271 *
272 * @return string The paragraph block.
273 */
274 public static function make_paragraph_block( $content ) {
275 if ( ! site_supports_blocks() ) {
276 return $content;
277 }
278 return '<!-- wp:paragraph --><p>' . $content . '</p><!-- /wp:paragraph -->';
279 }
280
281 /**
282 * Add the 'me' rel to the link.
283 *
284 * @param string $rel The rel attribute.
285 * @return string The modified rel attribute.
286 */
287 public static function add_rel_me( $rel ) {
288 return $rel . ' me';
289 }
290
291 /**
292 * Checks if the user is the blog user.
293 *
294 * @param int $user_id The user ID.
295 * @return bool True if the user is the blog user, otherwise false.
296 */
297 private static function is_blog( $user_id ) {
298 return Actors::BLOG_USER_ID === $user_id;
299 }
300 }
301