PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.10
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.10
1.1.10 1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 All 34 releases
← All changes | includes/content-graph/rest.php +62 -74 0.9.31.1.10 View file →
@@ -1,17 +1,19 @@
1 1 <?php
2 2 /**
3 - * Desktop Mode — Content Graph: REST routes.
3 + * OpenStation — Content Graph: REST routes.
4 4 *
5 5 * Three endpoints under `desktop-mode/v1/content-graph`:
6 6 *
7 7 * GET /post-types
8 8 * Lists the types eligible for the graph (`slug`, `label`, `icon`,
9 - * `count`).
9 + * `count`, `taxonomies`).
10 10 *
11 11 * GET /nodes?types=post,page,...
12 - * Returns the full `{ nodes, edges, stats }` tuple. Cached server-
13 - * side, see graph-builder.php.
12 + * Returns the full `{ nodes, edges, groups, stats }` tuple. Cached
13 + * server-side, see graph-builder.php. `types` omitted means every
14 + * registered type; `types=` (present but empty) means none — the
15 + * shell sends the latter when every toolbar chip is off.
14 16 *
15 17 * GET /post/<id>
16 18 * Returns the side-panel detail bundle for one post:
17 19 * { post: {...}, author, contributors, comments, categories,
@@ -16,10 +18,9 @@
16 18 * Returns the side-panel detail bundle for one post:
17 19 * { post: {...}, author, contributors, comments, categories,
18 20 * attached_media, revisions }.
19 21 *
20 - * @package WPDesktopMode
21 - * @since 0.8.2
22 + * @package OpenStation
22 23 */
23 24
24 25 defined( 'ABSPATH' ) || exit;
25 26
@@ -25,29 +26,25 @@
25 26
26 27 /**
27 28 * Capability check shared across every endpoint.
28 29 *
29 - * @since 0.8.2
30 - *
31 30 * @return bool
32 31 */
33 -function desktop_mode_content_graph_rest_permission() {
34 - return desktop_mode_content_graph_user_can_use();
32 +function openstation_content_graph_rest_permission() {
33 + return openstation_content_graph_user_can_use();
35 34 }
36 35
37 36 /**
38 37 * Register the routes.
39 - *
40 - * @since 0.8.2
41 38 */
42 -function desktop_mode_content_graph_register_routes() {
39 +function openstation_content_graph_register_routes() {
43 40 register_rest_route(
44 41 'desktop-mode/v1',
45 42 '/content-graph/post-types',
46 43 array(
47 44 'methods' => WP_REST_Server::READABLE,
48 - 'callback' => 'desktop_mode_content_graph_rest_post_types',
49 - 'permission_callback' => 'desktop_mode_content_graph_rest_permission',
45 + 'callback' => 'openstation_content_graph_rest_post_types',
46 + 'permission_callback' => 'openstation_content_graph_rest_permission',
50 47 )
51 48 );
52 49 register_rest_route(
53 50 'desktop-mode/v1',
@@ -53,15 +50,20 @@
53 50 'desktop-mode/v1',
54 51 '/content-graph/nodes',
55 52 array(
56 53 'methods' => WP_REST_Server::READABLE,
57 - 'callback' => 'desktop_mode_content_graph_rest_nodes',
58 - 'permission_callback' => 'desktop_mode_content_graph_rest_permission',
54 + 'callback' => 'openstation_content_graph_rest_nodes',
55 + 'permission_callback' => 'openstation_content_graph_rest_permission',
59 56 'args' => array(
57 + // Deliberately no `default`: the dispatcher copies a
58 + // registered default into the request before the
59 + // callback runs, and `WP_REST_Request::has_param()`
60 + // sees it, so a default here would make an omitted
61 + // parameter indistinguishable from an explicitly empty
62 + // one — and the callback tells those two apart.
60 63 'types' => array(
61 - 'description' => 'Comma-separated list of post type slugs to include.',
64 + 'description' => 'Comma-separated list of post type slugs to include. Omit for every registered type; pass an empty value for none.',
62 65 'type' => 'string',
63 - 'default' => '',
64 66 ),
65 67 ),
66 68 )
67 69 );
@@ -69,10 +71,10 @@
69 71 'desktop-mode/v1',
70 72 '/content-graph/post/(?P<id>\d+)',
71 73 array(
72 74 'methods' => WP_REST_Server::READABLE,
73 - 'callback' => 'desktop_mode_content_graph_rest_post_detail',
74 - 'permission_callback' => 'desktop_mode_content_graph_rest_permission',
75 + 'callback' => 'openstation_content_graph_rest_post_detail',
76 + 'permission_callback' => 'openstation_content_graph_rest_permission',
75 77 'args' => array(
76 78 'id' => array(
77 79 'type' => 'integer',
78 80 'required' => true,
@@ -80,19 +82,17 @@
80 82 ),
81 83 )
82 84 );
83 85 }
84 -add_action( 'rest_api_init', 'desktop_mode_content_graph_register_routes' );
86 +add_action( 'rest_api_init', 'openstation_content_graph_register_routes' );
85 87
86 88 /**
87 89 * GET /post-types
88 90 *
89 - * @since 0.8.2
90 - *
91 91 * @return WP_REST_Response
92 92 */
93 -function desktop_mode_content_graph_rest_post_types() {
94 - $types = desktop_mode_content_graph_post_types();
93 +function openstation_content_graph_rest_post_types() {
94 + $types = openstation_content_graph_post_types();
95 95 $out = array();
96 96 foreach ( $types as $entry ) {
97 97 $slug = isset( $entry['slug'] ) ? (string) $entry['slug'] : '';
98 98 // 'readable' scopes the private bucket to posts the current
@@ -107,12 +107,13 @@
107 107 $count += (int) $counts->private;
108 108 }
109 109 }
110 110 $out[] = array(
111 - 'slug' => $slug,
112 - 'label' => isset( $entry['label'] ) ? (string) $entry['label'] : $slug,
113 - 'icon' => isset( $entry['icon'] ) ? (string) $entry['icon'] : 'dashicons-admin-post',
114 - 'count' => $count,
111 + 'slug' => $slug,
112 + 'label' => isset( $entry['label'] ) ? (string) $entry['label'] : $slug,
113 + 'icon' => isset( $entry['icon'] ) ? (string) $entry['icon'] : 'dashicons-admin-post',
114 + 'count' => $count,
115 + 'taxonomies' => $entry['taxonomies'],
115 116 );
116 117 }
117 118 return rest_ensure_response( $out );
118 119 }
@@ -119,20 +120,23 @@
119 120
120 121 /**
121 122 * GET /nodes
122 123 *
123 - * @since 0.8.2
124 + * An omitted `types` parameter selects every registered type; a
125 + * present-but-empty one selects none. The route registers no default
126 + * for the parameter so the two stay distinguishable through a real
127 + * dispatch (see the route registration above).
124 128 *
125 129 * @param WP_REST_Request $request
126 130 * @return WP_REST_Response
127 131 */
128 -function desktop_mode_content_graph_rest_nodes( WP_REST_Request $request ) {
129 - $raw = (string) $request->get_param( 'types' );
130 - $types = '' === $raw
131 - ? wp_list_pluck( desktop_mode_content_graph_post_types(), 'slug' )
132 - : array_map( 'trim', explode( ',', $raw ) );
133 - $payload = desktop_mode_content_graph_build( (array) $types );
134 - return rest_ensure_response( desktop_mode_content_graph_filter_payload_for_user( $payload ) );
132 +function openstation_content_graph_rest_nodes( WP_REST_Request $request ) {
133 + $raw = $request->get_param( 'types' );
134 + $types = $request->has_param( 'types' )
135 + ? array_map( 'trim', explode( ',', (string) $raw ) )
136 + : wp_list_pluck( openstation_content_graph_post_types(), 'slug' );
137 + $payload = openstation_content_graph_build( (array) $types );
138 + return rest_ensure_response( openstation_content_graph_filter_payload_for_user( $payload ) );
135 139 }
136 140
137 141 /**
138 142 * Strip revision-derived data the current user may not see from a
@@ -145,14 +149,12 @@
145 149 * were referenced only via stripped contributor ids are removed too.
146 150 * This runs at response time, not build time, because the cached
147 151 * payload is shared across users of the same privilege tier.
148 152 *
149 - * @since 0.9.2
150 - *
151 - * @param array $payload Payload from `desktop_mode_content_graph_build()`.
153 + * @param array $payload Payload from `openstation_content_graph_build()`.
152 154 * @return array
153 155 */
154 -function desktop_mode_content_graph_filter_payload_for_user( array $payload ) {
156 +function openstation_content_graph_filter_payload_for_user( array $payload ) {
155 157 if ( empty( $payload['nodes'] ) || ! is_array( $payload['nodes'] ) ) {
156 158 return $payload;
157 159 }
158 160
@@ -198,19 +200,17 @@
198 200
199 201 /**
200 202 * GET /post/<id>
201 203 *
202 - * @since 0.8.2
203 - *
204 204 * @param WP_REST_Request $request
205 205 * @return WP_REST_Response|WP_Error
206 206 */
207 -function desktop_mode_content_graph_rest_post_detail( WP_REST_Request $request ) {
207 +function openstation_content_graph_rest_post_detail( WP_REST_Request $request ) {
208 208 $id = (int) $request['id'];
209 209 $post = $id > 0 ? get_post( $id ) : null;
210 210 if ( ! $post ) {
211 211 return new WP_Error(
212 - 'desktop_mode_content_graph_post_not_found',
212 + 'openstation_content_graph_post_not_found',
213 213 __( 'Post not found.', 'desktop-mode' ),
214 214 array( 'status' => 404 )
215 215 );
216 216 }
@@ -215,9 +215,9 @@
215 215 );
216 216 }
217 217 if ( ! current_user_can( 'read_post', $id ) ) {
218 218 return new WP_Error(
219 - 'desktop_mode_content_graph_forbidden',
219 + 'openstation_content_graph_forbidden',
220 220 __( 'Insufficient permissions.', 'desktop-mode' ),
221 221 array( 'status' => 403 )
222 222 );
223 223 }
@@ -226,14 +226,14 @@
226 226 // edit-level data in core — wp/v2 only exposes revisions behind
227 227 // edit_post. Mirror that: readers get comment-author contributors
228 228 // only, no revision list.
229 229 $can_edit = current_user_can( 'edit_post', $post->ID );
230 - $author = desktop_mode_content_graph_format_user( (int) $post->post_author );
231 - $contributors = desktop_mode_content_graph_collect_contributors( $post, $can_edit );
232 - $comments = desktop_mode_content_graph_collect_comments( $post );
233 - $categories = desktop_mode_content_graph_collect_terms( $post );
234 - $attached = desktop_mode_content_graph_collect_attached_media( $post );
235 - $revisions = $can_edit ? desktop_mode_content_graph_collect_revisions( $post ) : array();
230 + $author = openstation_content_graph_format_user( (int) $post->post_author );
231 + $contributors = openstation_content_graph_collect_contributors( $post, $can_edit );
232 + $comments = openstation_content_graph_collect_comments( $post );
233 + $categories = openstation_content_graph_collect_terms( $post );
234 + $attached = openstation_content_graph_collect_attached_media( $post );
235 + $revisions = $can_edit ? openstation_content_graph_collect_revisions( $post ) : array();
236 236
237 237 return rest_ensure_response(
238 238 array(
239 239 'post' => array(
@@ -259,14 +259,12 @@
259 259
260 260 /**
261 261 * Format a user record for the side panel.
262 262 *
263 - * @since 0.8.2
264 - *
265 263 * @param int $user_id
266 264 * @return array|null
267 265 */
268 -function desktop_mode_content_graph_format_user( $user_id ) {
266 +function openstation_content_graph_format_user( $user_id ) {
269 267 $user_id = (int) $user_id;
270 268 if ( $user_id <= 0 ) {
271 269 return null;
272 270 }
@@ -287,10 +285,8 @@
287 285 * Collect contributors: distinct revision authors (excluding the
288 286 * current author) plus distinct comment authors who have a
289 287 * registered user account.
290 288 *
291 - * @since 0.8.2
292 - *
293 289 * @param WP_Post $post
294 290 * @param bool $include_revision_authors Whether to include revision
295 291 * authors. Pass false for users who cannot `edit_post`
296 292 * the post — revision authorship is edit-level data;
@@ -296,9 +292,9 @@
296 292 * the post — revision authorship is edit-level data;
297 293 * approved comment authors are public either way.
298 294 * @return array[]
299 295 */
300 -function desktop_mode_content_graph_collect_contributors( WP_Post $post, $include_revision_authors = true ) {
296 +function openstation_content_graph_collect_contributors( WP_Post $post, $include_revision_authors = true ) {
301 297 $author_id = (int) $post->post_author;
302 298 $ids = array();
303 299 if ( $include_revision_authors ) {
304 300 $revs = wp_get_post_revisions(
@@ -329,9 +325,9 @@
329 325 }
330 326 }
331 327 $out = array();
332 328 foreach ( array_keys( $ids ) as $uid ) {
333 - $entry = desktop_mode_content_graph_format_user( $uid );
329 + $entry = openstation_content_graph_format_user( $uid );
334 330 if ( $entry ) {
335 331 $out[] = $entry;
336 332 }
337 333 }
@@ -340,14 +336,12 @@
340 336
341 337 /**
342 338 * Collect approved comments (most recent first, capped at 50).
343 339 *
344 - * @since 0.8.2
345 - *
346 340 * @param WP_Post $post
347 341 * @return array[]
348 342 */
349 -function desktop_mode_content_graph_collect_comments( WP_Post $post ) {
343 +function openstation_content_graph_collect_comments( WP_Post $post ) {
350 344 $comments = get_comments(
351 345 array(
352 346 'post_id' => $post->ID,
353 347 'status' => 'approve',
@@ -355,9 +349,9 @@
355 349 'orderby' => 'comment_date_gmt',
356 350 'order' => 'DESC',
357 351 )
358 352 );
359 - $out = array();
353 + $out = array();
360 354 foreach ( $comments as $comment ) {
361 355 $out[] = array(
362 356 'id' => (int) $comment->comment_ID,
363 357 'author' => (string) $comment->comment_author,
@@ -373,14 +367,12 @@
373 367 /**
374 368 * Collect every taxonomy term attached to the post (categories, tags,
375 369 * and any custom taxonomy registered for the post type).
376 370 *
377 - * @since 0.8.2
378 - *
379 371 * @param WP_Post $post
380 372 * @return array[]
381 373 */
382 -function desktop_mode_content_graph_collect_terms( WP_Post $post ) {
374 +function openstation_content_graph_collect_terms( WP_Post $post ) {
383 375 $taxes = get_object_taxonomies( $post->post_type, 'objects' );
384 376 $out = array();
385 377 foreach ( $taxes as $tax ) {
386 378 if ( ! $tax->public && ! $tax->show_ui ) {
@@ -408,14 +400,12 @@
408 400 /**
409 401 * Collect attached media (anything with this post as its `post_parent`)
410 402 * plus any media referenced from a `wp:image` block. Returns up to 50.
411 403 *
412 - * @since 0.8.2
413 - *
414 404 * @param WP_Post $post
415 405 * @return array[]
416 406 */
417 -function desktop_mode_content_graph_collect_attached_media( WP_Post $post ) {
407 +function openstation_content_graph_collect_attached_media( WP_Post $post ) {
418 408 $attachments = get_attached_media( '', $post );
419 409 $out = array();
420 410 foreach ( $attachments as $att ) {
421 411 $out[] = array(
@@ -434,14 +424,12 @@
434 424
435 425 /**
436 426 * Collect post revisions (most recent first, capped at 30).
437 427 *
438 - * @since 0.8.2
439 - *
440 428 * @param WP_Post $post
441 429 * @return array[]
442 430 */
443 -function desktop_mode_content_graph_collect_revisions( WP_Post $post ) {
431 +function openstation_content_graph_collect_revisions( WP_Post $post ) {
444 432 $revs = wp_get_post_revisions(
445 433 $post->ID,
446 434 array(
447 435 'posts_per_page' => 30,
@@ -451,9 +439,9 @@
451 439 foreach ( $revs as $rev ) {
452 440 $out[] = array(
453 441 'id' => (int) $rev->ID,
454 442 'date' => mysql2date( 'c', $rev->post_date_gmt, false ),
455 - 'author' => desktop_mode_content_graph_format_user( (int) $rev->post_author ),
443 + 'author' => openstation_content_graph_format_user( (int) $rev->post_author ),
456 444 'edit_url' => (string) admin_url( 'revision.php?revision=' . (int) $rev->ID ),
457 445 );
458 446 }
459 447 return $out;