PluginProbe
ActivityPub / 1.0.0
ActivityPub v1.0.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-mention.php

class-mention.php in ActivityPub 1.0.0, at includes/class-mention.php

156 lines 4.1 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 WP_Error;
5
6 /**
7 * ActivityPub Mention Class
8 *
9 * @author Alex Kirk
10 */
11 class Mention {
12 /**
13 * Initialize the class, registering WordPress hooks
14 */
15 public static function init() {
16 \add_filter( 'the_content', array( self::class, 'the_content' ), 99, 2 );
17 \add_filter( 'activitypub_extract_mentions', array( self::class, 'extract_mentions' ), 99, 2 );
18 }
19
20 /**
21 * Filter to replace the mentions in the content with links
22 *
23 * @param string $the_content the post-content
24 *
25 * @return string the filtered post-content
26 */
27 public static function the_content( $the_content ) {
28 $protected_tags = array();
29 $protect = function( $m ) use ( &$protected_tags ) {
30 $c = \wp_rand( 100000, 999999 );
31 $protect = '!#!#PROTECT' . $c . '#!#!';
32 while ( isset( $protected_tags[ $protect ] ) ) {
33 $c = \wp_rand( 100000, 999999 );
34 $protect = '!#!#PROTECT' . $c . '#!#!';
35 }
36 $protected_tags[ $protect ] = $m[0];
37 return $protect;
38 };
39 $the_content = preg_replace_callback(
40 '#<!\[CDATA\[.*?\]\]>#is',
41 $protect,
42 $the_content
43 );
44 $the_content = preg_replace_callback(
45 '#<(pre|code|textarea|style)\b[^>]*>.*?</\1[^>]*>#is',
46 $protect,
47 $the_content
48 );
49 $the_content = preg_replace_callback(
50 '#<a.*?href=[^>]+>.*?</a>#i',
51 $protect,
52 $the_content
53 );
54
55 $the_content = preg_replace_callback(
56 '#<img.*?[^>]+>#i',
57 $protect,
58 $the_content
59 );
60
61 $the_content = \preg_replace_callback( '/@' . ACTIVITYPUB_USERNAME_REGEXP . '/', array( self::class, 'replace_with_links' ), $the_content );
62 $the_content = \str_replace( array_reverse( array_keys( $protected_tags ) ), array_reverse( array_values( $protected_tags ) ), $the_content );
63
64 return $the_content;
65 }
66
67 /**
68 * A callback for preg_replace to build the user links
69 *
70 * @param array $result the preg_match results
71 *
72 * @return string the final string
73 */
74 public static function replace_with_links( $result ) {
75 $metadata = get_remote_metadata_by_actor( $result[0] );
76
77 if ( ! empty( $metadata ) && ! is_wp_error( $metadata ) && ! empty( $metadata['url'] ) ) {
78 $username = ltrim( $result[0], '@' );
79 if ( ! empty( $metadata['name'] ) ) {
80 $username = $metadata['name'];
81 }
82 if ( ! empty( $metadata['preferredUsername'] ) ) {
83 $username = $metadata['preferredUsername'];
84 }
85 return \sprintf( '<a rel="mention" class="u-url mention" href="%s">@<span>%s</span></a>', esc_url( $metadata['url'] ), esc_html( $username ) );
86 }
87
88 return $result[0];
89 }
90
91 /**
92 * Get the Inboxes for the mentioned Actors
93 *
94 * @param array $mentioned The list of Actors that were mentioned
95 *
96 * @return array The list of Inboxes
97 */
98 public static function get_inboxes( $mentioned ) {
99 $inboxes = array();
100
101 foreach ( $mentioned as $actor ) {
102 $inbox = self::get_inbox_by_mentioned_actor( $actor );
103
104 if ( ! is_wp_error( $inbox ) && $inbox ) {
105 $inboxes[] = $inbox;
106 }
107 }
108
109 return $inboxes;
110 }
111
112 /**
113 * Get the inbox from the Remote-Profile of a mentioned Actor
114 *
115 * @param string $actor The Actor-URL
116 *
117 * @return string The Inbox-URL
118 */
119 public static function get_inbox_by_mentioned_actor( $actor ) {
120 $metadata = get_remote_metadata_by_actor( $actor );
121
122 if ( \is_wp_error( $metadata ) ) {
123 return $metadata;
124 }
125
126 if ( isset( $metadata['endpoints'] ) && isset( $metadata['endpoints']['sharedInbox'] ) ) {
127 return $metadata['endpoints']['sharedInbox'];
128 }
129
130 if ( \array_key_exists( 'inbox', $metadata ) ) {
131 return $metadata['inbox'];
132 }
133
134 return new WP_Error( 'activitypub_no_inbox', \__( 'No "Inbox" found', 'activitypub' ), $metadata );
135 }
136
137 /**
138 * Extract the mentions from the post_content.
139 *
140 * @param array $mentions The already found mentions.
141 * @param string $post_content The post content.
142 *
143 * @return mixed The discovered mentions.
144 */
145 public static function extract_mentions( $mentions, $post_content ) {
146 \preg_match_all( '/@' . ACTIVITYPUB_USERNAME_REGEXP . '/i', $post_content, $matches );
147 foreach ( $matches[0] as $match ) {
148 $link = Webfinger::resolve( $match );
149 if ( ! is_wp_error( $link ) ) {
150 $mentions[ $match ] = $link;
151 }
152 }
153 return $mentions;
154 }
155 }
156