PluginProbe
ActivityPub / 1.0.5
ActivityPub v1.0.5
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-hashtag.php

class-hashtag.php in ActivityPub 1.0.5, at includes/class-hashtag.php

116 lines 3.0 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 /**
5 * ActivityPub Hashtag Class
6 *
7 * @author Matthias Pfefferle
8 */
9 class Hashtag {
10 /**
11 * Initialize the class, registering WordPress hooks
12 */
13 public static function init() {
14 if ( '1' === \get_option( 'activitypub_use_hashtags', '1' ) ) {
15 \add_filter( 'wp_insert_post', array( self::class, 'insert_post' ), 10, 2 );
16 \add_filter( 'the_content', array( self::class, 'the_content' ), 10, 2 );
17 }
18 }
19
20 /**
21 * Filter to save #tags as real WordPress tags
22 *
23 * @param int $id the rev-id
24 * @param WP_Post $post the post
25 *
26 * @return
27 */
28 public static function insert_post( $id, $post ) {
29 if ( \preg_match_all( '/' . ACTIVITYPUB_HASHTAGS_REGEXP . '/i', $post->post_content, $match ) ) {
30 $tags = \implode( ', ', $match[1] );
31
32 \wp_add_post_tags( $post->post_parent, $tags );
33 }
34
35 return $id;
36 }
37
38 /**
39 * Filter to replace the #tags in the content with links
40 *
41 * @param string $the_content the post-content
42 *
43 * @return string the filtered post-content
44 */
45 public static function the_content( $the_content ) {
46 $tag_stack = array();
47 $protected_tags = array(
48 'pre',
49 'code',
50 'textarea',
51 'style',
52 'a',
53 );
54 $content_with_links = '';
55 $in_protected_tag = false;
56 foreach ( wp_html_split( $the_content ) as $chunk ) {
57 if ( preg_match( '#^<!--[\s\S]*-->$#i', $chunk, $m ) ) {
58 $content_with_links .= $chunk;
59 continue;
60 }
61
62 if ( preg_match( '#^<(/)?([a-z-]+)\b[^>]*>$#i', $chunk, $m ) ) {
63 $tag = strtolower( $m[2] );
64 if ( '/' === $m[1] ) {
65 // Closing tag.
66 $i = array_search( $tag, $tag_stack );
67 // We can only remove the tag from the stack if it is in the stack.
68 if ( false !== $i ) {
69 $tag_stack = array_slice( $tag_stack, 0, $i );
70 }
71 } else {
72 // Opening tag, add it to the stack.
73 $tag_stack[] = $tag;
74 }
75
76 // If we're in a protected tag, the tag_stack contains at least one protected tag string.
77 // The protected tag state can only change when we encounter a start or end tag.
78 $in_protected_tag = array_intersect( $tag_stack, $protected_tags );
79
80 // Never inspect tags.
81 $content_with_links .= $chunk;
82 continue;
83 }
84
85 if ( $in_protected_tag ) {
86 // Don't inspect a chunk inside an inspected tag.
87 $content_with_links .= $chunk;
88 continue;
89 }
90
91 // Only reachable when there is no protected tag in the stack.
92 $content_with_links .= \preg_replace_callback( '/' . ACTIVITYPUB_HASHTAGS_REGEXP . '/i', array( '\Activitypub\Hashtag', 'replace_with_links' ), $chunk );
93 }
94
95 return $content_with_links;
96 }
97
98 /**
99 * A callback for preg_replace to build the term links
100 *
101 * @param array $result the preg_match results
102 * @return string the final string
103 */
104 public static function replace_with_links( $result ) {
105 $tag = $result[1];
106 $tag_object = \get_term_by( 'name', $tag, 'post_tag' );
107
108 if ( $tag_object ) {
109 $link = \get_term_link( $tag_object, 'post_tag' );
110 return \sprintf( '<a rel="tag" class="hashtag u-tag u-category" href="%s">#%s</a>', $link, $tag );
111 }
112
113 return '#' . $tag;
114 }
115 }
116