PluginProbe
ActivityPub / 1.1.0
ActivityPub v1.1.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 / class-shortcodes.php

class-shortcodes.php in ActivityPub 1.1.0, at includes/class-shortcodes.php

585 lines 14.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Activitypub;
3
4 use function Activitypub\esc_hashtag;
5
6 class Shortcodes {
7 /**
8 * Register the shortcodes
9 */
10 public static function register() {
11 foreach ( get_class_methods( self::class ) as $shortcode ) {
12 if ( 'init' !== $shortcode ) {
13 add_shortcode( 'ap_' . $shortcode, array( self::class, $shortcode ) );
14 }
15 }
16 }
17
18 /**
19 * Unregister the shortcodes
20 */
21 public static function unregister() {
22 foreach ( get_class_methods( self::class ) as $shortcode ) {
23 if ( 'init' !== $shortcode ) {
24 remove_shortcode( 'ap_' . $shortcode );
25 }
26 }
27 }
28
29 /**
30 * Generates output for the 'ap_hashtags' shortcode
31 *
32 * @param array $atts The Shortcode attributes.
33 * @param string $content The ActivityPub post-content.
34 * @param string $tag The tag/name of the Shortcode.
35 *
36 * @return string The post tags as hashtags.
37 */
38 public static function hashtags( $atts, $content, $tag ) {
39 $item = self::get_item();
40
41 if ( ! $item ) {
42 return '';
43 }
44
45 $tags = \get_the_tags( $item->ID );
46
47 if ( ! $tags ) {
48 return '';
49 }
50
51 $hash_tags = array();
52
53 foreach ( $tags as $tag ) {
54 $hash_tags[] = \sprintf(
55 '<a rel="tag" class="hashtag u-tag u-category" href="%s">%s</a>',
56 \esc_url( \get_tag_link( $tag ) ),
57 esc_hashtag( $tag->name )
58 );
59 }
60
61 return \implode( ' ', $hash_tags );
62 }
63
64 /**
65 * Generates output for the 'ap_title' Shortcode
66 *
67 * @param array $atts The Shortcode attributes.
68 * @param string $content The ActivityPub post-content.
69 * @param string $tag The tag/name of the Shortcode.
70 *
71 * @return string The post title.
72 */
73 public static function title( $atts, $content, $tag ) {
74 $item = self::get_item();
75
76 if ( ! $item ) {
77 return '';
78 }
79
80 return \wp_strip_all_tags( \get_the_title( $item->ID ), true );
81 }
82
83 /**
84 * Generates output for the 'ap_excerpt' Shortcode
85 *
86 * @param array $atts The Shortcode attributes.
87 * @param string $content The ActivityPub post-content.
88 * @param string $tag The tag/name of the Shortcode.
89 *
90 * @return string The post excerpt.
91 */
92 public static function excerpt( $atts, $content, $tag ) {
93 $item = self::get_item();
94
95 if ( ! $item ) {
96 return '';
97 }
98
99 $atts = shortcode_atts(
100 array( 'length' => ACTIVITYPUB_EXCERPT_LENGTH ),
101 $atts,
102 $tag
103 );
104
105 $excerpt_length = intval( $atts['length'] );
106
107 if ( 0 === $excerpt_length ) {
108 $excerpt_length = ACTIVITYPUB_EXCERPT_LENGTH;
109 }
110
111 $excerpt = \get_post_field( 'post_excerpt', $item );
112
113 if ( '' === $excerpt ) {
114
115 $content = \get_post_field( 'post_content', $item );
116
117 // An empty string will make wp_trim_excerpt do stuff we do not want.
118 if ( '' !== $content ) {
119 $excerpt = \strip_shortcodes( $content );
120
121 /** This filter is documented in wp-includes/post-template.php */
122 $excerpt = \apply_filters( 'the_content', $excerpt );
123 $excerpt = \str_replace( ']]>', ']]&gt;', $excerpt );
124 }
125 }
126
127 // Strip out any remaining tags.
128 $excerpt = \wp_strip_all_tags( $excerpt );
129
130 /** This filter is documented in wp-includes/formatting.php */
131 $excerpt_more = \apply_filters( 'excerpt_more', ' [...]' );
132 $excerpt_more_len = strlen( $excerpt_more );
133
134 // We now have a excerpt, but we need to check it's length, it may be longer than we want for two reasons:
135 //
136 // * The user has entered a manual excerpt which is longer that what we want.
137 // * No manual excerpt exists so we've used the content which might be longer than we want.
138 //
139 // Either way, let's trim it up if we need too. Also, don't forget to take into account the more indicator
140 // as part of the total length.
141 //
142
143 // Setup a variable to hold the current excerpts length.
144 $current_excerpt_length = strlen( $excerpt );
145
146 // Setup a variable to keep track of our target length.
147 $target_excerpt_length = $excerpt_length - $excerpt_more_len;
148
149 // Setup a variable to keep track of the current max length.
150 $current_excerpt_max = $target_excerpt_length;
151
152 // This is a loop since we can't calculate word break the string after 'the_excpert' filter has run (we would break
153 // all kinds of html tags), so we have to cut the excerpt down a bit at a time until we hit our target length.
154 while ( $current_excerpt_length > $target_excerpt_length && $current_excerpt_max > 0 ) {
155 // Trim the excerpt based on wordwrap() positioning.
156 // Note: we're using <br> as the linebreak just in case there are any newlines existing in the excerpt from the user.
157 // There won't be any <br> left after we've run wp_strip_all_tags() in the code above, so they're
158 // safe to use here. It won't be included in the final excerpt as the substr() will trim it off.
159 $excerpt = substr( $excerpt, 0, strpos( wordwrap( $excerpt, $current_excerpt_max, '<br>' ), '<br>' ) );
160
161 // If something went wrong, or we're in a language that wordwrap() doesn't understand,
162 // just chop it off and don't worry about breaking in the middle of a word.
163 if ( strlen( $excerpt ) > $excerpt_length - $excerpt_more_len ) {
164 $excerpt = substr( $excerpt, 0, $current_excerpt_max );
165 }
166
167 // Add in the more indicator.
168 $excerpt = $excerpt . $excerpt_more;
169
170 // Run it through the excerpt filter which will add some html tags back in.
171 $excerpt_filtered = apply_filters( 'the_excerpt', $excerpt );
172
173 // Now set the current excerpt length to this new filtered length.
174 $current_excerpt_length = strlen( $excerpt_filtered );
175
176 // Check to see if we're over the target length.
177 if ( $current_excerpt_length > $target_excerpt_length ) {
178 // If so, remove 20 characters from the current max and run the loop again.
179 $current_excerpt_max = $current_excerpt_max - 20;
180 }
181 }
182
183 return \apply_filters( 'the_excerpt', $excerpt );
184 }
185
186 /**
187 * Generates output for the 'ap_content' Shortcode
188 *
189 * @param array $atts The Shortcode attributes.
190 * @param string $content The ActivityPub post-content.
191 * @param string $tag The tag/name of the Shortcode.
192 *
193 * @return string The post content.
194 */
195 public static function content( $atts, $content, $tag ) {
196 $item = self::get_item();
197
198 if ( ! $item ) {
199 return '';
200 }
201
202 // prevent inception
203 remove_shortcode( 'ap_content' );
204
205 $atts = shortcode_atts(
206 array( 'apply_filters' => 'yes' ),
207 $atts,
208 $tag
209 );
210
211 $content = \get_post_field( 'post_content', $item );
212
213 if ( 'yes' === $atts['apply_filters'] ) {
214 $content = \apply_filters( 'the_content', $content );
215 } else {
216 $content = do_blocks( $content );
217 $content = wptexturize( $content );
218 $content = wp_filter_content_tags( $content );
219 }
220
221 // replace script and style elements
222 $content = \preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $content );
223 $content = strip_shortcodes( $content );
224 $content = \trim( \preg_replace( '/[\n\r\t]/', '', $content ) );
225
226 add_shortcode( 'ap_content', array( 'Activitypub\Shortcodes', 'content' ) );
227
228 return $content;
229 }
230
231 /**
232 * Generates output for the 'ap_permalink' Shortcode
233 *
234 * @param array $atts The Shortcode attributes.
235 * @param string $content The ActivityPub post-content.
236 * @param string $tag The tag/name of the Shortcode.
237 *
238 * @return string The post permalink.
239 */
240 public static function permalink( $atts, $content, $tag ) {
241 $item = self::get_item();
242
243 if ( ! $item ) {
244 return '';
245 }
246
247 $atts = shortcode_atts(
248 array(
249 'type' => 'url',
250 ),
251 $atts,
252 $tag
253 );
254
255 if ( 'url' === $atts['type'] ) {
256 return \esc_url( \get_permalink( $item->ID ) );
257 }
258
259 return \sprintf(
260 '<a href="%1$s">%1$s</a>',
261 \esc_url( \get_permalink( $item->ID ) )
262 );
263 }
264
265 /**
266 * Generates output for the 'ap_shortlink' Shortcode
267 *
268 * @param array $atts The Shortcode attributes.
269 * @param string $content The ActivityPub post-content.
270 * @param string $tag The tag/name of the Shortcode.
271 *
272 * @return string The post shortlink.
273 */
274 public static function shortlink( $atts, $content, $tag ) {
275 $item = self::get_item();
276
277 if ( ! $item ) {
278 return '';
279 }
280
281 $atts = shortcode_atts(
282 array(
283 'type' => 'url',
284 ),
285 $atts,
286 $tag
287 );
288
289 if ( 'url' === $atts['type'] ) {
290 return \esc_url( \wp_get_shortlink( $item->ID ) );
291 }
292
293 return \sprintf(
294 '<a href="%1$s">%1$s</a>',
295 \esc_url( \wp_get_shortlink( $item->ID ) )
296 );
297 }
298
299 /**
300 * Generates output for the 'ap_image' Shortcode
301 *
302 * @param array $atts The Shortcode attributes.
303 * @param string $content The ActivityPub post-content.
304 * @param string $tag The tag/name of the Shortcode.
305 *
306 * @return string
307 */
308 public static function image( $atts, $content, $tag ) {
309 $item = self::get_item();
310
311 if ( ! $item ) {
312 return '';
313 }
314
315 $atts = shortcode_atts(
316 array(
317 'type' => 'full',
318 ),
319 $atts,
320 $tag
321 );
322
323 $size = 'full';
324
325 if ( in_array(
326 $atts['type'],
327 array( 'thumbnail', 'medium', 'large', 'full' ),
328 true
329 ) ) {
330 $size = $atts['type'];
331 }
332
333 $image = \get_the_post_thumbnail_url( $item->ID, $size );
334
335 if ( ! $image ) {
336 return '';
337 }
338
339 return \esc_url( $image );
340 }
341
342 /**
343 * Generates output for the 'ap_hashcats' Shortcode
344 *
345 * @param array $atts The Shortcode attributes.
346 * @param string $content The ActivityPub post-content.
347 * @param string $tag The tag/name of the Shortcode.
348 *
349 * @return string The post categories as hashtags.
350 */
351 public static function hashcats( $atts, $content, $tag ) {
352 $item = self::get_item();
353
354 if ( ! $item ) {
355 return '';
356 }
357
358 $categories = \get_the_category( $item->ID );
359
360 if ( ! $categories ) {
361 return '';
362 }
363
364 $hash_tags = array();
365
366 foreach ( $categories as $category ) {
367 $hash_tags[] = \sprintf(
368 '<a rel="tag" class="hashtag u-tag u-category" href="%s">%s</a>',
369 \esc_url( \get_category_link( $category ) ),
370 esc_hashtag( $category->name )
371 );
372 }
373
374 return \implode( ' ', $hash_tags );
375 }
376
377 /**
378 * Generates output for the 'ap_author' Shortcode
379 *
380 * @param array $atts The Shortcode attributes.
381 * @param string $content The ActivityPub post-content.
382 * @param string $tag The tag/name of the Shortcode.
383 *
384 * @return string The author name.
385 */
386 public static function author( $atts, $content, $tag ) {
387 $item = self::get_item();
388
389 if ( ! $item ) {
390 return '';
391 }
392
393 $author_id = \get_post_field( 'post_author', $item->ID );
394 $name = \get_the_author_meta( 'display_name', $author_id );
395
396 if ( ! $name ) {
397 return '';
398 }
399
400 return wp_strip_all_tags( $name );
401 }
402
403 /**
404 * Generates output for the 'ap_authorurl' Shortcode
405 *
406 * @param array $atts The Shortcode attributes.
407 * @param string $content The ActivityPub post-content.
408 * @param string $tag The tag/name of the Shortcode.
409 *
410 * @return string The author URL.
411 */
412 public static function authorurl( $atts, $content, $tag ) {
413 $item = self::get_item();
414
415 if ( ! $item ) {
416 return '';
417 }
418
419 $author_id = \get_post_field( 'post_author', $item->ID );
420 $url = \get_the_author_meta( 'user_url', $author_id );
421
422 if ( ! $url ) {
423 return '';
424 }
425
426 return \esc_url( $url );
427 }
428
429 /**
430 * Generates output for the 'ap_blogurl' Shortcode
431 *
432 * @param array $atts The Shortcode attributes.
433 * @param string $content The ActivityPub post-content.
434 * @param string $tag The tag/name of the Shortcode.
435 *
436 * @return string The site URL.
437 */
438 public static function blogurl( $atts, $content, $tag ) {
439 return \esc_url( \get_bloginfo( 'url' ) );
440 }
441
442 /**
443 * Generates output for the 'ap_blogname' Shortcode
444 *
445 * @param array $atts The Shortcode attributes.
446 * @param string $content The ActivityPub post-content.
447 * @param string $tag The tag/name of the Shortcode.
448 *
449 * @return string
450 */
451 public static function blogname( $atts, $content, $tag ) {
452 return \wp_strip_all_tags( \get_bloginfo( 'name' ) );
453 }
454
455 /**
456 * Generates output for the 'ap_blogdesc' Shortcode
457 *
458 * @param array $atts The Shortcode attributes.
459 * @param string $content The ActivityPub post-content.
460 * @param string $tag The tag/name of the Shortcode.
461 *
462 * @return string The site description.
463 */
464 public static function blogdesc( $atts, $content, $tag ) {
465 return \wp_strip_all_tags( \get_bloginfo( 'description' ) );
466 }
467
468 /**
469 * Generates output for the 'ap_date' Shortcode
470 *
471 * @param array $atts The Shortcode attributes.
472 * @param string $content The ActivityPub post-content.
473 * @param string $tag The tag/name of the Shortcode.
474 *
475 * @return string The post date.
476 */
477 public static function date( $atts, $content, $tag ) {
478 $item = self::get_item();
479
480 if ( ! $item ) {
481 return '';
482 }
483
484 $datetime = \get_post_datetime( $item );
485 $dateformat = \get_option( 'date_format' );
486 $timeformat = \get_option( 'time_format' );
487
488 $date = $datetime->format( $dateformat );
489
490 if ( ! $date ) {
491 return '';
492 }
493
494 return $date;
495 }
496
497 /**
498 * Generates output for the 'ap_time' Shortcode
499 *
500 * @param array $atts The Shortcode attributes.
501 * @param string $content The ActivityPub post-content.
502 * @param string $tag The tag/name of the Shortcode.
503 *
504 * @return string The post time.
505 */
506 public static function time( $atts, $content, $tag ) {
507 $item = self::get_item();
508
509 if ( ! $item ) {
510 return '';
511 }
512
513 $datetime = \get_post_datetime( $item );
514 $dateformat = \get_option( 'date_format' );
515 $timeformat = \get_option( 'time_format' );
516
517 $date = $datetime->format( $timeformat );
518
519 if ( ! $date ) {
520 return '';
521 }
522
523 return $date;
524 }
525
526 /**
527 * Generates output for the 'ap_datetime' Shortcode
528 *
529 * @param array $atts The Shortcode attributes.
530 * @param string $content The ActivityPub post-content.
531 * @param string $tag The tag/name of the Shortcode.
532 *
533 * @return string The post date/time.
534 */
535 public static function datetime( $atts, $content, $tag ) {
536 $item = self::get_item();
537
538 if ( ! $item ) {
539 return '';
540 }
541
542 $datetime = \get_post_datetime( $item );
543 $dateformat = \get_option( 'date_format' );
544 $timeformat = \get_option( 'time_format' );
545
546 $date = $datetime->format( $dateformat . ' @ ' . $timeformat );
547
548 if ( ! $date ) {
549 return '';
550 }
551
552 return $date;
553 }
554
555 /**
556 * Get a WordPress item to federate.
557 *
558 * Checks if item (WP_Post) is "public", a supported post type
559 * and not password protected.
560 *
561 * @return null|WP_Post The WordPress item.
562 */
563 protected static function get_item() {
564 $post = \get_post();
565
566 if ( ! $post ) {
567 return null;
568 }
569
570 if ( 'publish' !== \get_post_status( $post ) ) {
571 return null;
572 }
573
574 if ( \post_password_required( $post ) ) {
575 return null;
576 }
577
578 if ( ! \in_array( \get_post_type( $post ), \get_post_types_by_support( 'activitypub' ), true ) ) {
579 return null;
580 }
581
582 return $post;
583 }
584 }
585