PluginProbe
ActivityPub / trunk
ActivityPub vtrunk
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 trunk, at includes/rest/class-interaction-controller.php

206 lines 6.2 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 $intent = $request->get_param( 'intent' );
97 $redirect_url = '';
98 $object = Http::get_remote_object( $uri );
99
100 if ( \is_wp_error( $object ) || ! isset( $object['type'] ) ) {
101 // Use wp_die as this can be called from the front-end. See https://github.com/Automattic/wordpress-activitypub/pull/1149/files#r1915297109.
102 \wp_die(
103 \esc_html__( 'The URL is not supported!', 'activitypub' ),
104 '',
105 array(
106 'response' => 400,
107 'back_link' => true,
108 )
109 );
110 }
111
112 if ( ! empty( $object['id'] ) ) {
113 $uri = \esc_url_raw( $object['id'] );
114 }
115
116 // Prepare URL parameter.
117 $url_param = \rawurlencode( $uri );
118
119 switch ( $object['type'] ) {
120 case 'Group':
121 case 'Person':
122 case 'Service':
123 case 'Application':
124 case 'Organization':
125 if ( \get_option( 'activitypub_following_ui', '0' ) ) {
126 if ( user_can_activitypub( \get_current_user_id() ) ) {
127 $redirect_url = \admin_url( 'users.php?page=activitypub-following-list&resource=' . $url_param );
128 } elseif ( user_can_activitypub( Actors::BLOG_USER_ID ) ) {
129 $redirect_url = \admin_url( 'options-general.php?page=activitypub&tab=following&resource=' . $url_param );
130 }
131 }
132
133 /**
134 * Filters the URL used for following an ActivityPub actor.
135 *
136 * @param string $redirect_url The URL to redirect to.
137 * @param string $uri The URI of the actor to follow.
138 * @param array $object The full actor object data.
139 * @param string $intent The intent of the interaction.
140 */
141 $redirect_url = \apply_filters( 'activitypub_interactions_follow_url', $redirect_url, $uri, $object, $intent );
142 break;
143 case 'Collection':
144 case 'CollectionPage':
145 case 'OrderedCollection':
146 case 'OrderedCollectionPage':
147 if ( \get_option( 'activitypub_following_ui', '0' ) ) {
148 $redirect_url = \admin_url( 'admin.php?import=starter-kit&url=' . $url_param );
149 }
150
151 /**
152 * Filters the URL used for importing a Starter Kit collection.
153 *
154 * @param string $redirect_url The URL to redirect to.
155 * @param string $uri The URI of the collection to import.
156 * @param array $object The full collection object data.
157 * @param string $intent The intent of the interaction.
158 */
159 $redirect_url = \apply_filters( 'activitypub_interactions_starter_kit_url', $redirect_url, $uri, $object, $intent );
160 break;
161 default:
162 $redirect_url = \admin_url( 'post-new.php?in_reply_to=' . $url_param );
163
164 /**
165 * Filters the URL used for replying to an ActivityPub object.
166 *
167 * By default, this redirects to the WordPress post editor with the in_reply_to parameter set.
168 *
169 * @param string $redirect_url The URL to redirect to.
170 * @param string $uri The URI of the object to reply to.
171 * @param array $object The full object data being replied to.
172 * @param string $intent The intent of the interaction.
173 */
174 $redirect_url = \apply_filters( 'activitypub_interactions_reply_url', $redirect_url, $uri, $object, $intent );
175 }
176
177 /**
178 * Filters the redirect URL.
179 *
180 * This filter runs after the type-specific filters and allows for final modifications
181 * to the interaction URL regardless of the object type.
182 *
183 * @param string $redirect_url The URL to redirect to.
184 * @param string $uri The URI of the object.
185 * @param array $object The object being interacted with.
186 * @param string $intent The intent of the interaction.
187 */
188 $redirect_url = \apply_filters( 'activitypub_interactions_url', $redirect_url, $uri, $object, $intent );
189
190 // Check if hook is implemented.
191 if ( ! $redirect_url ) {
192 // Use wp_die as this can be called from the front-end. See https://github.com/Automattic/wordpress-activitypub/pull/1149/files#r1915297109.
193 \wp_die(
194 \esc_html__( 'This Interaction type is not supported yet!', 'activitypub' ),
195 '',
196 array(
197 'response' => 400,
198 'back_link' => true,
199 )
200 );
201 }
202
203 return new \WP_REST_Response( null, 302, array( 'Location' => $redirect_url ) );
204 }
205 }
206