PluginProbe
ActivityPub / 1.0.9
ActivityPub v1.0.9
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.0.9, at includes/class-shortcodes.php

583 lines 14.3 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 $name = \get_the_author_meta( 'display_name', $item->post_author );
394
395 if ( ! $name ) {
396 return '';
397 }
398
399 return wp_strip_all_tags( $name );
400 }
401
402 /**
403 * Generates output for the 'ap_authorurl' Shortcode
404 *
405 * @param array $atts The Shortcode attributes.
406 * @param string $content The ActivityPub post-content.
407 * @param string $tag The tag/name of the Shortcode.
408 *
409 * @return string The author URL.
410 */
411 public static function authorurl( $atts, $content, $tag ) {
412 $item = self::get_item();
413
414 if ( ! $item ) {
415 return '';
416 }
417
418 $url = \get_the_author_meta( 'user_url', $item->post_author );
419
420 if ( ! $url ) {
421 return '';
422 }
423
424 return \esc_url( $url );
425 }
426
427 /**
428 * Generates output for the 'ap_blogurl' Shortcode
429 *
430 * @param array $atts The Shortcode attributes.
431 * @param string $content The ActivityPub post-content.
432 * @param string $tag The tag/name of the Shortcode.
433 *
434 * @return string The site URL.
435 */
436 public static function blogurl( $atts, $content, $tag ) {
437 return \esc_url( \get_bloginfo( 'url' ) );
438 }
439
440 /**
441 * Generates output for the 'ap_blogname' Shortcode
442 *
443 * @param array $atts The Shortcode attributes.
444 * @param string $content The ActivityPub post-content.
445 * @param string $tag The tag/name of the Shortcode.
446 *
447 * @return string
448 */
449 public static function blogname( $atts, $content, $tag ) {
450 return \wp_strip_all_tags( \get_bloginfo( 'name' ) );
451 }
452
453 /**
454 * Generates output for the 'ap_blogdesc' Shortcode
455 *
456 * @param array $atts The Shortcode attributes.
457 * @param string $content The ActivityPub post-content.
458 * @param string $tag The tag/name of the Shortcode.
459 *
460 * @return string The site description.
461 */
462 public static function blogdesc( $atts, $content, $tag ) {
463 return \wp_strip_all_tags( \get_bloginfo( 'description' ) );
464 }
465
466 /**
467 * Generates output for the 'ap_date' Shortcode
468 *
469 * @param array $atts The Shortcode attributes.
470 * @param string $content The ActivityPub post-content.
471 * @param string $tag The tag/name of the Shortcode.
472 *
473 * @return string The post date.
474 */
475 public static function date( $atts, $content, $tag ) {
476 $item = self::get_item();
477
478 if ( ! $item ) {
479 return '';
480 }
481
482 $datetime = \get_post_datetime( $item );
483 $dateformat = \get_option( 'date_format' );
484 $timeformat = \get_option( 'time_format' );
485
486 $date = $datetime->format( $dateformat );
487
488 if ( ! $date ) {
489 return '';
490 }
491
492 return $date;
493 }
494
495 /**
496 * Generates output for the 'ap_time' Shortcode
497 *
498 * @param array $atts The Shortcode attributes.
499 * @param string $content The ActivityPub post-content.
500 * @param string $tag The tag/name of the Shortcode.
501 *
502 * @return string The post time.
503 */
504 public static function time( $atts, $content, $tag ) {
505 $item = self::get_item();
506
507 if ( ! $item ) {
508 return '';
509 }
510
511 $datetime = \get_post_datetime( $item );
512 $dateformat = \get_option( 'date_format' );
513 $timeformat = \get_option( 'time_format' );
514
515 $date = $datetime->format( $timeformat );
516
517 if ( ! $date ) {
518 return '';
519 }
520
521 return $date;
522 }
523
524 /**
525 * Generates output for the 'ap_datetime' Shortcode
526 *
527 * @param array $atts The Shortcode attributes.
528 * @param string $content The ActivityPub post-content.
529 * @param string $tag The tag/name of the Shortcode.
530 *
531 * @return string The post date/time.
532 */
533 public static function datetime( $atts, $content, $tag ) {
534 $item = self::get_item();
535
536 if ( ! $item ) {
537 return '';
538 }
539
540 $datetime = \get_post_datetime( $item );
541 $dateformat = \get_option( 'date_format' );
542 $timeformat = \get_option( 'time_format' );
543
544 $date = $datetime->format( $dateformat . ' @ ' . $timeformat );
545
546 if ( ! $date ) {
547 return '';
548 }
549
550 return $date;
551 }
552
553 /**
554 * Get a WordPress item to federate.
555 *
556 * Checks if item (WP_Post) is "public", a supported post type
557 * and not password protected.
558 *
559 * @return null|WP_Post The WordPress item.
560 */
561 protected static function get_item() {
562 $post = \get_post();
563
564 if ( ! $post ) {
565 return null;
566 }
567
568 if ( 'publish' !== \get_post_status( $post ) ) {
569 return null;
570 }
571
572 if ( \post_password_required( $post ) ) {
573 return null;
574 }
575
576 if ( ! \in_array( \get_post_type( $post ), \get_post_types_by_support( 'activitypub' ), true ) ) {
577 return null;
578 }
579
580 return $post;
581 }
582 }
583