PluginProbe
ActivityPub / 5.3.1
ActivityPub v5.3.1
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-replies-controller.php

class-replies-controller.php in ActivityPub 5.3.1, at includes/rest/class-replies-controller.php

257 lines 6.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Replies_Controller file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Rest;
9
10 use Activitypub\Activity\Base_Object;
11 use Activitypub\Collection\Replies;
12 use Activitypub\Collection\Interactions;
13
14 use function Activitypub\get_rest_url_by_path;
15
16 /**
17 * ActivityPub Replies_Controller class.
18 */
19 class Replies_Controller extends \WP_REST_Controller {
20
21 /**
22 * The namespace of this controller's route.
23 *
24 * @var string
25 */
26 protected $namespace = ACTIVITYPUB_REST_NAMESPACE;
27
28 /**
29 * The base of this controller's route.
30 *
31 * @var string
32 */
33 protected $rest_base = '(?P<object_type>[\w\-\.]+)s/(?P<id>[\w\-\.]+)/(?P<type>[\w\-\.]+)';
34
35 /**
36 * Register routes.
37 */
38 public function register_routes() {
39 \register_rest_route(
40 $this->namespace,
41 '/' . $this->rest_base,
42 array(
43 'args' => array(
44 'object_type' => array(
45 'description' => 'The type of object to get replies for.',
46 'type' => 'string',
47 'enum' => array( 'post', 'comment' ),
48 'required' => true,
49 ),
50 'id' => array(
51 'description' => 'The ID of the object.',
52 'type' => 'string',
53 'required' => true,
54 ),
55 'type' => array(
56 'description' => 'The type of collection to query.',
57 'type' => 'string',
58 'enum' => array( 'replies', 'likes', 'shares' ),
59 'required' => true,
60 ),
61 ),
62 array(
63 'methods' => \WP_REST_Server::READABLE,
64 'callback' => array( $this, 'get_items' ),
65 'permission_callback' => '__return_true',
66 'args' => array(
67 'page' => array(
68 'description' => 'Current page of the collection.',
69 'type' => 'integer',
70 'default' => 1,
71 'minimum' => 1,
72 ),
73 ),
74 ),
75 'schema' => array( $this, 'get_item_schema' ),
76 )
77 );
78 }
79
80 /**
81 * Retrieves a collection of replies.
82 *
83 * @param \WP_REST_Request $request The request object.
84 *
85 * @return \WP_REST_Response|\WP_Error Response object or WP_Error object.
86 */
87 public function get_items( $request ) {
88 $object_type = $request->get_param( 'object_type' );
89 $id = (int) $request->get_param( 'id' );
90
91 if ( 'comment' === $object_type ) {
92 $wp_object = \get_comment( $id );
93 } else {
94 $wp_object = \get_post( $id );
95 }
96
97 if ( ! isset( $wp_object ) || \is_wp_error( $wp_object ) ) {
98 return new \WP_Error(
99 'activitypub_replies_collection_does_not_exist',
100 \sprintf(
101 // translators: %s: The type (post, comment, etc.) for which no replies collection exists.
102 \__( 'No reply collection exists for the type %s.', 'activitypub' ),
103 $object_type
104 ),
105 array( 'status' => 404 )
106 );
107 }
108
109 switch ( $request->get_param( 'type' ) ) {
110 case 'replies':
111 $response = $this->get_replies( $request, $wp_object );
112 break;
113
114 case 'likes':
115 $response = $this->get_likes( $request, $wp_object );
116 break;
117
118 case 'shares':
119 $response = $this->get_shares( $request, $wp_object );
120 break;
121
122 default:
123 $response = new \WP_Error( 'rest_unknown_collection_type', 'Unknown collection type.', array( 'status' => 404 ) );
124 }
125
126 // Prepend ActivityPub Context.
127 $response = array_merge( array( '@context' => Base_Object::JSON_LD_CONTEXT ), $response );
128 $response = \rest_ensure_response( $response );
129 $response->header( 'Content-Type', 'application/activity+json; charset=' . \get_option( 'blog_charset' ) );
130
131 return $response;
132 }
133
134 /**
135 * Retrieves a collection of replies.
136 *
137 * @param \WP_REST_Request $request The request object.
138 * @param \WP_Post|\WP_Comment $wp_object The WordPress object.
139 *
140 * @return array Response collection of replies.
141 */
142 public function get_replies( $request, $wp_object ) {
143 $page = $request->get_param( 'page' );
144
145 // If the request parameter page is present get the CollectionPage otherwise the Replies collection.
146 if ( $page <= 1 ) {
147 $response = Replies::get_collection( $wp_object );
148 } else {
149 $response = Replies::get_collection_page( $wp_object, $page );
150 }
151
152 return $response;
153 }
154
155 /**
156 * Retrieves a collection of likes.
157 *
158 * @param \WP_REST_Request $request The request object.
159 * @param \WP_Post|\WP_Comment $wp_object The WordPress object.
160 *
161 * @return array Response collection of likes.
162 */
163 public function get_likes( $request, $wp_object ) {
164 if ( $wp_object instanceof \WP_Post ) {
165 $likes = Interactions::count_by_type( $wp_object->ID, 'like' );
166 } else {
167 $likes = 0;
168 }
169
170 $response = array(
171 'id' => get_rest_url_by_path( sprintf( 'posts/%d/likes', $wp_object->ID ) ),
172 'type' => 'Collection',
173 'totalItems' => $likes,
174 );
175
176 return $response;
177 }
178
179 /**
180 * Retrieves a collection of shares.
181 *
182 * @param \WP_REST_Request $request The request object.
183 * @param \WP_Post|\WP_Comment $wp_object The WordPress object.
184 *
185 * @return array Response collection of shares.
186 */
187 public function get_shares( $request, $wp_object ) {
188 if ( $wp_object instanceof \WP_Post ) {
189 $shares = Interactions::count_by_type( $wp_object->ID, 'repost' );
190 } else {
191 $shares = 0;
192 }
193
194 $response = array(
195 'id' => get_rest_url_by_path( sprintf( 'posts/%d/shares', $wp_object->ID ) ),
196 'type' => 'Collection',
197 'totalItems' => $shares,
198 );
199
200 return $response;
201 }
202
203 /**
204 * Retrieves the schema for the Replies endpoint.
205 *
206 * @return array Schema data.
207 */
208 public function get_item_schema() {
209 if ( $this->schema ) {
210 return $this->add_additional_fields_schema( $this->schema );
211 }
212
213 $schema = array(
214 '$schema' => 'http://json-schema.org/draft-04/schema#',
215 'title' => 'replies',
216 'type' => 'object',
217 'properties' => array(
218 '@context' => array(
219 'type' => 'array',
220 'items' => array(
221 'type' => 'string',
222 ),
223 'required' => true,
224 ),
225 'id' => array(
226 'type' => 'string',
227 'format' => 'uri',
228 'required' => true,
229 ),
230 'type' => array(
231 'type' => 'string',
232 'enum' => array( 'Collection', 'OrderedCollection', 'CollectionPage', 'OrderedCollectionPage' ),
233 'required' => true,
234 ),
235 'first' => array(
236 'type' => 'string',
237 'format' => 'uri',
238 ),
239 'last' => array(
240 'type' => 'string',
241 'format' => 'uri',
242 ),
243 'items' => array(
244 'type' => 'array',
245 'items' => array(
246 'type' => 'object',
247 ),
248 ),
249 ),
250 );
251
252 $this->schema = $schema;
253
254 return $this->add_additional_fields_schema( $this->schema );
255 }
256 }
257