PluginProbe
ActivityPub / 8.0.2
ActivityPub v8.0.2
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 / trait-collection.php

trait-collection.php in ActivityPub 8.0.2, at includes/rest/trait-collection.php

164 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Collection Trait file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Rest;
9
10 /**
11 * Collection Trait.
12 *
13 * Provides methods for handling ActivityPub Collections, including pagination
14 * and type transitions between Collection and CollectionPage.
15 */
16 trait Collection {
17 /**
18 * The JSON-LD context for ActivityPub collections.
19 *
20 * @var array
21 */
22 private $json_ld_context = array(
23 'https://www.w3.org/ns/activitystreams',
24 );
25
26 /**
27 * Prepares a collection response by adding navigation links and handling pagination.
28 *
29 * Adds first, last, next, and previous page links to a collection response
30 * based on the current page and total items. Also handles the transformation
31 * between Collection and CollectionPage types.
32 *
33 * @param array $response The collection response array.
34 * @param \WP_REST_Request $request The request object.
35 *
36 * @return array|\WP_Error The response array with navigation links or WP_Error on invalid page.
37 */
38 public function prepare_collection_response( $response, $request ) {
39 $page = $request->get_param( 'page' );
40 $per_page = \max( 1, \absint( $request->get_param( 'per_page' ) ) );
41 $max_pages = \max( 1, \ceil( $response['totalItems'] / $per_page ) );
42
43 if ( $page > $max_pages ) {
44 return new \WP_Error(
45 'rest_post_invalid_page_number',
46 'The page number requested is larger than the number of pages available.',
47 array( 'status' => 400 )
48 );
49 }
50
51 // Set the JSON-LD context if not already set.
52 if ( empty( $response['@context'] ) ) {
53 // Ensure the context is the first element in the response.
54 $response = array( '@context' => $this->json_ld_context ) + $response;
55 }
56
57 if ( empty( $response['items'] ) && empty( $response['orderedItems'] ) ) {
58 // Skip pagination metadata when items are intentionally hidden or collection is empty.
59 return $response;
60 }
61
62 $response['id'] = \add_query_arg( $request->get_query_params(), $response['id'] );
63 $response['first'] = \add_query_arg( 'page', 1, $response['id'] );
64 $response['last'] = \add_query_arg( 'page', $max_pages, $response['id'] );
65
66 // If this is a Collection request, return early.
67 if ( null === $page ) {
68 // No items in Collections, only links to CollectionPages.
69 unset( $response['items'], $response['orderedItems'] );
70
71 return $response;
72 }
73
74 // Still here, so this is a Page request. Append the type.
75 $response['type'] .= 'Page';
76 $response['partOf'] = \remove_query_arg( 'page', $response['id'] );
77
78 if ( $max_pages > $page ) {
79 $response['next'] = \add_query_arg( 'page', $page + 1, $response['partOf'] );
80 }
81
82 if ( $page > 1 ) {
83 $response['prev'] = \add_query_arg( 'page', $page - 1, $response['partOf'] );
84 }
85
86 return $response;
87 }
88
89 /**
90 * Get the schema for an ActivityPub Collection.
91 *
92 * Returns a schema definition for ActivityPub (Ordered)Collection and (Ordered)CollectionPage
93 * that controllers can use to compose their full schema by passing in their item schema.
94 *
95 * @param array $item_schema Optional. The schema for the items in the collection. Default empty array.
96 *
97 * @return array The collection schema.
98 */
99 public function get_collection_schema( $item_schema = array() ) {
100 $collection_schema = array(
101 '$schema' => 'http://json-schema.org/draft-04/schema#',
102 'title' => 'collection',
103 'type' => 'object',
104 'properties' => array(
105 '@context' => array(
106 'description' => 'The JSON-LD context of the OrderedCollection.',
107 'type' => array( 'string', 'array', 'object' ),
108 ),
109 'id' => array(
110 'description' => 'The unique identifier for the OrderedCollection.',
111 'type' => 'string',
112 'format' => 'uri',
113 ),
114 'type' => array(
115 'description' => 'The type of the object. Either OrderedCollection or OrderedCollectionPage.',
116 'type' => 'string',
117 'enum' => array( 'Collection', 'CollectionPage', 'OrderedCollection', 'OrderedCollectionPage' ),
118 ),
119 'totalItems' => array(
120 'description' => 'The total number of items in the collection.',
121 'type' => 'integer',
122 'minimum' => 0,
123 ),
124 'orderedItems' => array(
125 'description' => 'The ordered items in the collection.',
126 'type' => 'array',
127 ),
128 'first' => array(
129 'description' => 'Link to the first page of the collection.',
130 'type' => 'string',
131 'format' => 'uri',
132 ),
133 'last' => array(
134 'description' => 'Link to the last page of the collection.',
135 'type' => 'string',
136 'format' => 'uri',
137 ),
138 'next' => array(
139 'description' => 'Link to the next page of the collection.',
140 'type' => 'string',
141 'format' => 'uri',
142 ),
143 'prev' => array(
144 'description' => 'Link to the previous page of the collection.',
145 'type' => 'string',
146 'format' => 'uri',
147 ),
148 'partOf' => array(
149 'description' => 'The OrderedCollection to which this OrderedCollectionPage belongs.',
150 'type' => 'string',
151 'format' => 'uri',
152 ),
153 ),
154 );
155
156 // Add the orderedItems property based on the provided item schema.
157 if ( ! empty( $item_schema ) ) {
158 $collection_schema['properties']['orderedItems']['items'] = $item_schema;
159 }
160
161 return $collection_schema;
162 }
163 }
164