PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 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 All 508 releases
← All changes | _inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-admin-bar.php +176 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,176 @@
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', 'help-center' );
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' );