PluginProbe
ActivityPub / 5.7.0
ActivityPub v5.7.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
← All changes | includes/rest/class-following-controller.php +61 -112 9.2.0 → 5.7.0 View file →
@@ -6,14 +6,14 @@
6 6 */
7 7
8 8 namespace Activitypub\Rest;
9 9
10 -use Activitypub\Activity\Base_Object;
11 -use Activitypub\Collection\Following;
12 -use Activitypub\Collection\Remote_Actors;
10 +use Activitypub\Collection\Actors;
13 11
12 +use function Activitypub\get_context;
13 +use function Activitypub\is_single_user;
14 +use function Activitypub\get_rest_url_by_path;
14 15 use function Activitypub\get_masked_wp_version;
15 -use function Activitypub\get_rest_url_by_path;
16 16
17 17 /**
18 18 * Following_Controller class.
19 19 *
@@ -24,8 +24,15 @@
24 24 class Following_Controller extends Actors_Controller {
25 25 use Collection;
26 26
27 27 /**
28 + * Initialize the class, registering WordPress hooks.
29 + */
30 + public function __construct() {
31 + \add_filter( 'activitypub_rest_following', array( self::class, 'default_following' ), 10, 2 );
32 + }
33 +
34 + /**
28 35 * Register routes.
29 36 */
30 37 public function register_routes() {
31 38 \register_rest_route(
@@ -33,18 +40,18 @@
33 40 '/' . $this->rest_base . '/following',
34 41 array(
35 42 'args' => array(
36 43 'user_id' => array(
37 - 'description' => 'The ID of the actor.',
38 - 'type' => 'integer',
39 - 'required' => true,
40 - 'validate_callback' => array( $this, 'validate_user_id' ),
44 + 'description' => 'The ID or username of the actor.',
45 + 'type' => 'string',
46 + 'required' => true,
47 + 'pattern' => '[\w\-\.]+',
41 48 ),
42 49 ),
43 50 array(
44 51 'methods' => \WP_REST_Server::READABLE,
45 52 'callback' => array( $this, 'get_items' ),
46 - 'permission_callback' => array( $this, 'verify_signature' ),
53 + 'permission_callback' => array( 'Activitypub\Rest\Server', 'verify_signature' ),
47 54 'args' => array(
48 55 'page' => array(
49 56 'description' => 'Current page of the collection.',
50 57 'type' => 'integer',
@@ -57,20 +64,8 @@
57 64 'default' => 10,
58 65 'minimum' => 1,
59 66 'maximum' => 100,
60 67 ),
61 - 'order' => array(
62 - 'description' => 'Order sort attribute ascending or descending.',
63 - 'type' => 'string',
64 - 'default' => 'desc',
65 - 'enum' => array( 'asc', 'desc' ),
66 - ),
67 - 'context' => array(
68 - 'description' => 'The context in which the request is made.',
69 - 'type' => 'string',
70 - 'default' => 'simple',
71 - 'enum' => array( 'simple', 'full' ),
72 - ),
73 68 ),
74 69 ),
75 70 'schema' => array( $this, 'get_public_item_schema' ),
76 71 )
@@ -84,53 +79,40 @@
84 79 * @return \WP_REST_Response|\WP_Error Response object on success, or WP_Error object on failure.
85 80 */
86 81 public function get_items( $request ) {
87 82 $user_id = $request->get_param( 'user_id' );
83 + $user = Actors::get_by_various( $user_id );
88 84
85 + if ( \is_wp_error( $user ) ) {
86 + return $user;
87 + }
88 +
89 89 /**
90 90 * Action triggered prior to the ActivityPub profile being created and sent to the client.
91 91 */
92 92 \do_action( 'activitypub_rest_following_pre' );
93 93
94 - $order = $request->get_param( 'order' );
95 - $per_page = $request->get_param( 'per_page' );
96 - $page = $request->get_param( 'page' ) ?? 1;
97 - $context = $request->get_param( 'context' );
98 -
99 - $data = Following::query( $user_id, $per_page, $page, array( 'order' => \ucwords( $order ) ) );
100 -
101 94 $response = array(
102 - 'id' => get_rest_url_by_path( \sprintf( 'actors/%d/following', $user_id ) ),
103 - 'generator' => 'https://wordpress.org/?v=' . get_masked_wp_version(),
104 - 'type' => 'OrderedCollection',
105 - 'totalItems' => $data['total'],
95 + '@context' => get_context(),
96 + 'id' => get_rest_url_by_path( \sprintf( 'actors/%d/following', $user->get__id() ) ),
97 + 'generator' => 'https://wordpress.org/?v=' . get_masked_wp_version(),
98 + 'actor' => $user->get_id(),
99 + 'type' => 'OrderedCollection',
106 100 );
107 101
108 - if ( 'full' === $context ) {
109 - // Ensure the context is the first element in the response.
110 - $response = array( '@context' => Base_Object::JSON_LD_CONTEXT ) + $response;
111 - }
102 + /**
103 + * Filter the list of following urls.
104 + *
105 + * @param array $items The array of following urls.
106 + * @param \Activitypub\Model\User $user The user object.
107 + */
108 + $items = \apply_filters( 'activitypub_rest_following', array(), $user );
112 109
113 - if ( $this->show_social_graph( $request ) ) {
114 - $response['orderedItems'] = \array_filter(
115 - \array_map(
116 - static function ( $item ) use ( $context ) {
117 - if ( 'full' === $context ) {
118 - $actor = Remote_Actors::get_actor( $item );
119 - if ( \is_wp_error( $actor ) ) {
120 - return false;
121 - }
122 - return $actor->to_array( false );
123 - }
124 - return $item->guid;
125 - },
126 - $data['following']
127 - )
128 - );
129 - }
110 + $response['totalItems'] = \is_countable( $items ) ? \count( $items ) : 0;
111 + $response['orderedItems'] = $items;
130 112
131 113 $response = $this->prepare_collection_response( $response, $request );
132 - if ( \is_wp_error( $response ) ) {
114 + if ( is_wp_error( $response ) ) {
133 115 return $response;
134 116 }
135 117
136 118 $response = \rest_ensure_response( $response );
@@ -139,8 +121,31 @@
139 121 return $response;
140 122 }
141 123
142 124 /**
125 + * Add the Blog Authors to the following list of the Blog Actor
126 + * if Blog not in single mode.
127 + *
128 + * @param array $follow_list The array of following urls.
129 + * @param \Activitypub\Model\User $user The user object.
130 + *
131 + * @return array The array of following urls.
132 + */
133 + public static function default_following( $follow_list, $user ) {
134 + if ( 0 !== $user->get__id() || is_single_user() ) {
135 + return $follow_list;
136 + }
137 +
138 + $users = Actors::get_collection();
139 +
140 + foreach ( $users as $user ) {
141 + $follow_list[] = $user->get_id();
142 + }
143 +
144 + return $follow_list;
145 + }
146 +
147 + /**
143 148 * Retrieves the following schema, conforming to JSON Schema.
144 149 *
145 150 * @return array Item schema data.
146 151 */
@@ -148,67 +153,11 @@
148 153 if ( $this->schema ) {
149 154 return $this->add_additional_fields_schema( $this->schema );
150 155 }
151 156
152 - // Define the schema for items in the following collection.
153 157 $item_schema = array(
154 - 'oneOf' => array(
155 - array(
156 - 'type' => 'string',
157 - 'format' => 'uri',
158 - ),
159 - array(
160 - 'type' => 'object',
161 - 'properties' => array(
162 - 'id' => array(
163 - 'type' => 'string',
164 - 'format' => 'uri',
165 - ),
166 - 'type' => array(
167 - 'type' => 'string',
168 - ),
169 - 'name' => array(
170 - 'type' => 'string',
171 - ),
172 - 'icon' => array(
173 - 'type' => 'object',
174 - 'properties' => array(
175 - 'type' => array(
176 - 'type' => 'string',
177 - ),
178 - 'mediaType' => array(
179 - 'type' => 'string',
180 - ),
181 - 'url' => array(
182 - 'type' => 'string',
183 - 'format' => 'uri',
184 - ),
185 - ),
186 - ),
187 - 'published' => array(
188 - 'type' => 'string',
189 - 'format' => 'date-time',
190 - ),
191 - 'summary' => array(
192 - 'type' => 'string',
193 - ),
194 - 'updated' => array(
195 - 'type' => 'string',
196 - 'format' => 'date-time',
197 - ),
198 - 'url' => array(
199 - 'type' => 'string',
200 - 'format' => 'uri',
201 - ),
202 - 'streams' => array(
203 - 'type' => 'array',
204 - ),
205 - 'preferredUsername' => array(
206 - 'type' => 'string',
207 - ),
208 - ),
209 - ),
210 - ),
158 + 'type' => 'string',
159 + 'format' => 'uri',
211 160 );
212 161
213 162 $schema = $this->get_collection_schema( $item_schema );
214 163