PluginProbe
ActivityPub / 7.8.4
ActivityPub v7.8.4
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 / rest / class-interaction-controller.php

class-interaction-controller.php in ActivityPub 7.8.4, at includes/rest/class-interaction-controller.php

201 lines 5.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ActivityPub Interaction Controller file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Rest;
9
10 use Activitypub\Activity\Activity;
11 use Activitypub\Collection\Actors;
12 use Activitypub\Http;
13
14 use function Activitypub\user_can_activitypub;
15
16 /**
17 * Interaction Controller.
18 */
19 class Interaction_Controller extends \WP_REST_Controller {
20 /**
21 * The namespace of this controller's route.
22 *
23 * @var string
24 */
25 protected $namespace = ACTIVITYPUB_REST_NAMESPACE;
26
27 /**
28 * The base of this controller's route.
29 *
30 * @var string
31 */
32 protected $rest_base = 'interactions';
33
34 /**
35 * Register routes.
36 */
37 public function register_routes() {
38 \register_rest_route(
39 $this->namespace,
40 '/' . $this->rest_base,
41 array(
42 array(
43 'methods' => \WP_REST_Server::READABLE,
44 'callback' => array( $this, 'get_item' ),
45 'permission_callback' => '__return_true',
46 'args' => array(
47 'uri' => array(
48 'description' => 'The URI or webfinger ID of the object to interact with.',
49 'type' => 'string',
50 'required' => true,
51 'sanitize_callback' => array( $this, 'sanitize_uri' ),
52 ),
53 'intent' => array(
54 'description' => 'The intent of the interaction, e.g., follow, reply, import.',
55 'type' => 'string',
56 'enum' => array_map( 'Activitypub\camel_to_snake_case', Activity::TYPES ),
57 ),
58 ),
59 ),
60 )
61 );
62 }
63
64 /**
65 * Sanitize the URI parameter.
66 *
67 * @param string $uri The URI or webfinger ID of the object to interact with.
68 *
69 * @return string Sanitized URI.
70 */
71 public function sanitize_uri( $uri ) {
72 // Remove "acct:" prefix if present.
73 if ( str_starts_with( $uri, 'acct:' ) ) {
74 $uri = \substr( $uri, 5 );
75 }
76
77 // Remove "@" prefix if present.
78 $uri = \ltrim( $uri, '@' );
79
80 if ( is_email( $uri ) ) {
81 return \sanitize_text_field( $uri );
82 }
83
84 return \sanitize_url( $uri );
85 }
86
87 /**
88 * Retrieves the interaction URL for a given URI.
89 *
90 * @param \WP_REST_Request $request The request object.
91 *
92 * @return \WP_REST_Response Response object on success, dies on failure.
93 */
94 public function get_item( $request ) {
95 $uri = $request->get_param( 'uri' );
96 $redirect_url = '';
97 $object = Http::get_remote_object( $uri );
98
99 if ( \is_wp_error( $object ) || ! isset( $object['type'] ) ) {
100 // Use wp_die as this can be called from the front-end. See https://github.com/Automattic/wordpress-activitypub/pull/1149/files#r1915297109.
101 \wp_die(
102 esc_html__( 'The URL is not supported!', 'activitypub' ),
103 '',
104 array(
105 'response' => 400,
106 'back_link' => true,
107 )
108 );
109 }
110
111 if ( ! empty( $object['id'] ) ) {
112 $uri = \esc_url( $object['id'] );
113 }
114
115 // Prepare URL parameter.
116 $url_param = \rawurlencode( $uri );
117
118 switch ( $object['type'] ) {
119 case 'Group':
120 case 'Person':
121 case 'Service':
122 case 'Application':
123 case 'Organization':
124 if ( \get_option( 'activitypub_following_ui', '0' ) ) {
125 if ( user_can_activitypub( \get_current_user_id() ) ) {
126 $redirect_url = \admin_url( 'users.php?page=activitypub-following-list&resource=' . $url_param );
127 } elseif ( user_can_activitypub( Actors::BLOG_USER_ID ) ) {
128 $redirect_url = \admin_url( 'options-general.php?page=activitypub&tab=following&resource=' . $url_param );
129 }
130 }
131
132 /**
133 * Filters the URL used for following an ActivityPub actor.
134 *
135 * @param string $redirect_url The URL to redirect to.
136 * @param string $uri The URI of the actor to follow.
137 * @param array $object The full actor object data.
138 */
139 $redirect_url = \apply_filters( 'activitypub_interactions_follow_url', $redirect_url, $uri, $object );
140 break;
141 case 'Collection':
142 case 'CollectionPage':
143 case 'OrderedCollection':
144 case 'OrderedCollectionPage':
145 if ( \get_option( 'activitypub_following_ui', '0' ) ) {
146 $redirect_url = \admin_url( 'admin.php?import=starter-kit&url=' . $url_param );
147 }
148
149 /**
150 * Filters the URL used for importing a Starter Kit collection.
151 *
152 * @param string $redirect_url The URL to redirect to.
153 * @param string $uri The URI of the collection to import.
154 * @param array $object The full collection object data.
155 */
156 $redirect_url = \apply_filters( 'activitypub_interactions_starter_kit_url', $redirect_url, $uri, $object );
157 break;
158 default:
159 $redirect_url = \admin_url( 'post-new.php?in_reply_to=' . $url_param );
160
161 /**
162 * Filters the URL used for replying to an ActivityPub object.
163 *
164 * By default, this redirects to the WordPress post editor with the in_reply_to parameter set.
165 *
166 * @param string $redirect_url The URL to redirect to.
167 * @param string $uri The URI of the object to reply to.
168 * @param array $object The full object data being replied to.
169 */
170 $redirect_url = \apply_filters( 'activitypub_interactions_reply_url', $redirect_url, $uri, $object );
171 }
172
173 /**
174 * Filters the redirect URL.
175 *
176 * This filter runs after the type-specific filters and allows for final modifications
177 * to the interaction URL regardless of the object type.
178 *
179 * @param string $redirect_url The URL to redirect to.
180 * @param string $uri The URI of the object.
181 * @param array $object The object being interacted with.
182 */
183 $redirect_url = \apply_filters( 'activitypub_interactions_url', $redirect_url, $uri, $object );
184
185 // Check if hook is implemented.
186 if ( ! $redirect_url ) {
187 // Use wp_die as this can be called from the front-end. See https://github.com/Automattic/wordpress-activitypub/pull/1149/files#r1915297109.
188 \wp_die(
189 esc_html__( 'This Interaction type is not supported yet!', 'activitypub' ),
190 '',
191 array(
192 'response' => 400,
193 'back_link' => true,
194 )
195 );
196 }
197
198 return new \WP_REST_Response( null, 302, array( 'Location' => $redirect_url ) );
199 }
200 }
201