PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.2
Jetpack – WP Security, Backup, Speed, & Growth v16.2
16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 All 502 releases
jetpack / _inc / lib / core-api / wpcom-endpoints / class-wpcom-rest-api-v2-endpoint-admin-bar.php

class-wpcom-rest-api-v2-endpoint-admin-bar.php in Jetpack – WP Security, Backup, Speed, & Growth 16.2, at _inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-admin-bar.php

177 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * REST API endpoint for admin bar.
4 *
5 * @package automattic/jetpack
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit( 0 );
10 }
11
12 /**
13 * Class WPCOM_REST_API_V2_Endpoint_Admin_Bar
14 */
15 class WPCOM_REST_API_V2_Endpoint_Admin_Bar extends WP_REST_Controller {
16
17 /**
18 * Namespace prefix.
19 *
20 * @var string
21 */
22 public $namespace = 'wpcom/v2';
23
24 /**
25 * Endpoint base route.
26 *
27 * @var string
28 */
29 public $rest_base = 'admin-bar';
30
31 /**
32 * Top-level admin bar node IDs that are considered safe to show.
33 *
34 * @var string[]
35 */
36 const ALLOWED_TOP_LEVEL_NODES = array( 'wp-logo', 'site-name', 'updates', 'command-palette', 'comments', 'new-content', 'my-account', 'agents-manager', 'agents-manager-ai-chat' );
37
38 /**
39 * WPCOM_REST_API_V2_Endpoint_Admin_Bar constructor.
40 */
41 public function __construct() {
42 add_action( 'rest_api_init', array( $this, 'register_routes' ) );
43 }
44
45 /**
46 * Register routes.
47 */
48 public function register_routes() {
49 register_rest_route(
50 $this->namespace,
51 $this->rest_base . '/',
52 array(
53 array(
54 'methods' => WP_REST_Server::READABLE,
55 'callback' => array( $this, 'get_item' ),
56 'permission_callback' => array( $this, 'get_item_permissions_check' ),
57 ),
58 )
59 );
60 }
61
62 /**
63 * Checks if a given request has access to the admin bar.
64 *
65 * @param WP_REST_Request $request Full details about the request.
66 * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise.
67 */
68 public function get_item_permissions_check( $request ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter, VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
69 if ( ! current_user_can( 'manage_options' ) ) {
70 return new WP_Error(
71 'rest_forbidden',
72 __( 'Sorry, you are not allowed to view the admin bar on this site.', 'jetpack' ),
73 array( 'status' => rest_authorization_required_code() )
74 );
75 }
76
77 return true;
78 }
79
80 /**
81 * Retrieves the admin bar registered for the current site, filtered to
82 * the allowed top-level nodes and their descendants.
83 *
84 * @param WP_REST_Request $request Full details about the request.
85 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
86 */
87 public function get_item( $request ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter, VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
88 if ( ! class_exists( 'WP_Screen' ) ) {
89 require_once ABSPATH . 'wp-admin/includes/class-wp-screen.php';
90 }
91
92 if ( ! function_exists( 'set_current_screen' ) ) {
93 require_once ABSPATH . 'wp-admin/includes/screen.php';
94 }
95
96 $switched_locale = false;
97 if ( 'user' === $request->get_param( '_locale' ) ) {
98 $user_locale = get_user_locale();
99 if ( $user_locale ) {
100 $switched_locale = switch_to_locale( $user_locale );
101 }
102 }
103
104 // Simulate a wp-admin context.
105 set_current_screen( 'dashboard' );
106
107 // Core only adds the command palette node when its assets are enqueued,
108 // which normally happens on admin_enqueue_scripts.
109 if ( function_exists( 'wp_enqueue_command_palette_assets' ) ) {
110 wp_enqueue_command_palette_assets();
111 }
112
113 $nodes = $this->get_nodes();
114 $filtered_nodes = $this->filter_nodes( $nodes, self::ALLOWED_TOP_LEVEL_NODES );
115
116 $response = rest_ensure_response( array( 'nodes' => array_values( $filtered_nodes ) ) );
117
118 if ( $switched_locale ) {
119 restore_previous_locale();
120 }
121
122 return $response;
123 }
124
125 /**
126 * Builds the admin bar for the current request and returns its nodes.
127 *
128 * @return array Admin bar nodes.
129 */
130 private function get_nodes() {
131 global $wp_admin_bar;
132
133 add_filter( 'show_admin_bar', '__return_true', 999 );
134 if ( ! _wp_admin_bar_init() || ! $wp_admin_bar instanceof WP_Admin_Bar ) {
135 return array();
136 }
137
138 ob_start();
139 do_action_ref_array( 'admin_bar_menu', array( &$wp_admin_bar ) );
140 ob_end_clean();
141
142 return $wp_admin_bar->get_nodes() ?? array();
143 }
144
145 /**
146 * Filters admin bar nodes to only include allowed top-level items and
147 * their descendants.
148 *
149 * @param array $nodes All admin bar nodes keyed by ID.
150 * @param array $allowed_ids Top-level node IDs to keep.
151 * @return array Filtered nodes.
152 */
153 private function filter_nodes( array $nodes, array $allowed_ids ) {
154 $allowed = array();
155
156 foreach ( $nodes as $id => $node ) {
157 if ( in_array( $id, $allowed_ids, true ) ) {
158 $allowed[ $id ] = $node;
159 continue;
160 }
161
162 $current = $node;
163 while ( ! empty( $current->parent ) && isset( $nodes[ $current->parent ] ) ) {
164 if ( in_array( $current->parent, $allowed_ids, true ) ) {
165 $allowed[ $id ] = $node;
166 break;
167 }
168 $current = $nodes[ $current->parent ];
169 }
170 }
171
172 return $allowed;
173 }
174 }
175
176 wpcom_rest_api_v2_load_plugin( 'WPCOM_REST_API_V2_Endpoint_Admin_Bar' );
177