PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 14.8.1
Jetpack – WP Security, Backup, Speed, & Growth v14.8.1
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 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / _inc / lib / admin-pages / class.jetpack-react-page.php
jetpack / _inc / lib / admin-pages Last commit date
class-jetpack-about-page.php 1 year ago class-jetpack-redux-state-helper.php 1 year ago class.jetpack-admin-page.php 1 year ago class.jetpack-landing-page.php 2 years ago class.jetpack-react-page.php 1 year ago class.jetpack-settings-page.php 3 years ago
class.jetpack-react-page.php
345 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3 use Automattic\Jetpack\Admin_UI\Admin_Menu;
4 use Automattic\Jetpack\Assets\Logo;
5 use Automattic\Jetpack\Connection\Initial_State as Connection_Initial_State;
6 use Automattic\Jetpack\Connection\Manager as Connection_Manager;
7 use Automattic\Jetpack\Publicize\Publicize_Script_Data;
8 use Automattic\Jetpack\Status;
9
10 require_once __DIR__ . '/class.jetpack-admin-page.php';
11 require_once __DIR__ . '/class-jetpack-redux-state-helper.php';
12
13 /**
14 * Builds the landing page and its menu.
15 */
16 class Jetpack_React_Page extends Jetpack_Admin_Page {
17 /**
18 * Show the landing page only when Jetpack is connected.
19 *
20 * @var bool
21 */
22 protected $dont_show_if_not_active = false;
23
24 /**
25 * Used for fallback when REST API is disabled.
26 *
27 * @var bool
28 */
29 protected $is_redirecting = false;
30
31 /**
32 * Add the main admin Jetpack menu.
33 *
34 * @return string|false Return value from WordPress's `add_menu_page()`.
35 */
36 public function get_page_hook() {
37 $icon = ( new Logo() )->get_base64_logo();
38 return add_menu_page( 'Jetpack', 'Jetpack', 'jetpack_admin_page', 'jetpack', array( $this, 'render' ), $icon, 3 );
39 }
40
41 /**
42 * Add page action.
43 *
44 * @param string $hook Hook of current page.
45 * @return void
46 */
47 public function add_page_actions( $hook ) {
48 /** This action is documented in class.jetpack-admin.php */
49 do_action( 'jetpack_admin_menu', $hook );
50
51 if ( ! isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
52 return;
53 }
54 $page = sanitize_text_field( wp_unslash( $_GET['page'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
55 if ( 'jetpack' !== $page ) {
56 if ( strpos( $page, 'jetpack/' ) === 0 ) {
57 $section = substr( $page, 8 );
58 wp_safe_redirect( admin_url( 'admin.php?page=jetpack#/' . $section ) );
59 exit( 0 );
60 }
61 return; // No need to handle the fallback redirection if we are not on the Jetpack page.
62 }
63
64 // Adding a redirect meta tag if the REST API is disabled.
65 if ( ! $this->is_rest_api_enabled() ) {
66 $this->is_redirecting = true;
67 add_action( 'admin_head', array( $this, 'add_fallback_head_meta' ) );
68 }
69
70 // Adding a redirect meta tag wrapped in noscript tags for all browsers in case they have JavaScript disabled.
71 add_action( 'admin_head', array( $this, 'add_noscript_head_meta' ) );
72
73 // If this is the first time the user is viewing the admin, don't show JITMs.
74 // This filter is added just in time because this function is called on admin_menu
75 // and JITMs are initialized on admin_init.
76 if ( Jetpack::is_connection_ready() && ! Jetpack_Options::get_option( 'first_admin_view', false ) ) {
77 Jetpack_Options::update_option( 'first_admin_view', true );
78 add_filter( 'jetpack_just_in_time_msgs', '__return_false' );
79 }
80 }
81
82 /**
83 * Remove the main Jetpack submenu if a site is in offline mode or connected
84 * or if My Jetpack is available.
85 * At that point, admins can access the Jetpack Dashboard instead.
86 *
87 * @since 13.8
88 */
89 public function remove_jetpack_menu() {
90 $is_offline_mode = ( new Status() )->is_offline_mode();
91 $has_my_jetpack = (
92 class_exists( 'Automattic\Jetpack\My_Jetpack\Initializer' ) &&
93 method_exists( 'Automattic\Jetpack\My_Jetpack\Initializer', 'should_initialize' ) &&
94 \Automattic\Jetpack\My_Jetpack\Initializer::should_initialize()
95 );
96
97 if ( $is_offline_mode || $has_my_jetpack || Jetpack::is_connection_ready() ) {
98 remove_submenu_page( 'jetpack', 'jetpack' );
99 }
100 }
101
102 /**
103 * Add Jetpack Dashboard sub-link and point it to AAG if the user can view stats, manage modules or if Protect is active.
104 *
105 * Works in Dev Mode or when user is connected.
106 *
107 * @since 4.3.0
108 */
109 public function jetpack_add_dashboard_sub_nav_item() {
110 if ( ( new Status() )->is_offline_mode() || Jetpack::is_connection_ready() ) {
111 Admin_Menu::add_menu(
112 __( 'Dashboard', 'jetpack' ),
113 __( 'Dashboard', 'jetpack' ),
114 'jetpack_admin_page',
115 Jetpack::admin_url( array( 'page' => 'jetpack#/dashboard' ) ),
116 null,
117 14
118 );
119 }
120 }
121
122 /**
123 * Determine whether a user can access the Jetpack Settings page.
124 *
125 * Rules are:
126 * - user is allowed to see the Jetpack Admin
127 * - site is connected or in offline mode
128 * - non-admins only need access to the settings when there are modules they can manage.
129 *
130 * @return bool $can_access_settings Can the user access settings.
131 */
132 private function can_access_settings() {
133 $connection = new Connection_Manager( 'jetpack' );
134 $status = new Status();
135
136 // User must have the necessary permissions to see the Jetpack settings pages.
137 if ( ! current_user_can( 'edit_posts' ) ) {
138 return false;
139 }
140
141 // In offline mode, allow access to admins.
142 if ( $status->is_offline_mode() && current_user_can( 'manage_options' ) ) {
143 return true;
144 }
145
146 // If not in offline mode but site is not connected, bail.
147 if ( ! Jetpack::is_connection_ready() ) {
148 return false;
149 }
150
151 /*
152 * Additional checks for non-admins.
153 */
154 if ( ! current_user_can( 'manage_options' ) ) {
155 // If the site isn't connected at all, bail.
156 if ( ! $connection->has_connected_owner() ) {
157 return false;
158 }
159
160 /*
161 * If they haven't connected their own account yet,
162 * they have no use for the settings page.
163 * They will not be able to manage any settings.
164 */
165 if ( ! $connection->is_user_connected() ) {
166 return false;
167 }
168
169 /*
170 * Non-admins only have access to settings
171 * for the following modules:
172 * - Publicize
173 * - Post By Email
174 * If those modules are not available, bail.
175 */
176 if (
177 ! Jetpack::is_module_active( 'post-by-email' )
178 && (
179 Publicize_Script_Data::has_feature_flag( 'admin-page' ) ||
180 ! Jetpack::is_module_active( 'publicize' ) ||
181 ! current_user_can( 'publish_posts' )
182 )
183 ) {
184 return false;
185 }
186 }
187
188 // fallback.
189 return true;
190 }
191
192 /**
193 * Jetpack Settings sub-link.
194 *
195 * @since 4.3.0
196 * @since 9.7.0 If Connection does not have an owner, restrict it to admins
197 */
198 public function jetpack_add_settings_sub_nav_item() {
199 if ( $this->can_access_settings() ) {
200 Admin_Menu::add_menu(
201 __( 'Settings', 'jetpack' ),
202 __( 'Settings', 'jetpack' ),
203 'jetpack_admin_page',
204 Jetpack::admin_url( array( 'page' => 'jetpack#/settings' ) ),
205 null,
206 13
207 );
208 }
209 }
210
211 /**
212 * Fallback redirect meta tag if the REST API is disabled.
213 *
214 * @return void
215 */
216 public function add_fallback_head_meta() {
217 echo '<meta http-equiv="refresh" content="0; url=?page=jetpack_modules">';
218 }
219
220 /**
221 * Fallback meta tag wrapped in noscript tags for all browsers in case they have JavaScript disabled.
222 *
223 * @return void
224 */
225 public function add_noscript_head_meta() {
226 echo '<noscript>';
227 $this->add_fallback_head_meta();
228 echo '</noscript>';
229 }
230
231 /**
232 * Add action to render page specific HTML.
233 *
234 * @return void
235 */
236 public function page_render() {
237 /** This action is already documented in class.jetpack-admin-page.php */
238 do_action( 'jetpack_notices' );
239
240 // Fetch static.html.
241 $static_html = @file_get_contents( JETPACK__PLUGIN_DIR . '_inc/build/static.html' ); //phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents, Not fetching a remote file.
242
243 if ( false === $static_html ) {
244
245 // If we still have nothing, display an error.
246 echo '<p>';
247 esc_html_e( 'Error fetching static.html. Try running: ', 'jetpack' );
248 echo '<code>pnpm run distclean && pnpm jetpack build plugins/jetpack</code>';
249 echo '</p>';
250 } else {
251 // We got the static.html so let's display it.
252 echo $static_html; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
253 }
254 }
255 /**
256 * Allow robust deep links to React.
257 *
258 * The Jetpack dashboard requires fragments/hash values to make
259 * a deep link to it but passing fragments as part of a return URL
260 * will most often be discarded throughout the process.
261 * This logic aims to bridge this gap and reduce the chance of React
262 * specific links being broken while passing them along.
263 */
264 public function react_redirects() {
265 global $pagenow;
266
267 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
268 if ( 'admin.php' !== $pagenow || ! isset( $_GET['jp-react-redirect'] ) ) {
269 return;
270 }
271
272 $allowed_paths = array(
273 'product-purchased' => admin_url( '/admin.php?page=jetpack#/recommendations/product-purchased' ),
274 );
275
276 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
277 $target = sanitize_text_field( wp_unslash( $_GET['jp-react-redirect'] ) );
278 if ( isset( $allowed_paths[ $target ] ) ) {
279 wp_safe_redirect( $allowed_paths[ $target ] );
280 exit( 0 );
281 }
282 }
283
284 /**
285 * Load styles for static page.
286 */
287 public function additional_styles() {
288 Jetpack_Admin_Page::load_wrapper_styles();
289 }
290
291 /**
292 * Load admin page scripts.
293 */
294 public function page_admin_scripts() {
295 if ( $this->is_redirecting ) {
296 return; // No need for scripts on a fallback page.
297 }
298
299 $status = new Status();
300 $is_offline_mode = $status->is_offline_mode();
301 $site_suffix = $status->get_site_suffix();
302 $script_deps_path = JETPACK__PLUGIN_DIR . '_inc/build/admin.asset.php';
303 $script_dependencies = array( 'jquery', 'wp-polyfill' );
304 $version = JETPACK__VERSION;
305 if ( file_exists( $script_deps_path ) ) {
306 $asset_manifest = include $script_deps_path;
307 $script_dependencies = $asset_manifest['dependencies'];
308 $version = $asset_manifest['version'];
309 }
310
311 $blog_id_prop = '';
312 if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) {
313 $blog_id = Connection_Manager::get_site_id( true );
314 if ( $blog_id ) {
315 $blog_id_prop = ', currentBlogID: "' . (int) $blog_id . '"';
316 }
317 }
318
319 wp_enqueue_script(
320 'react-plugin',
321 plugins_url( '_inc/build/admin.js', JETPACK__PLUGIN_FILE ),
322 $script_dependencies,
323 $version,
324 true
325 );
326
327 if ( ! $is_offline_mode && Jetpack::is_connection_ready() ) {
328 // Required for Analytics.
329 wp_enqueue_script( 'jp-tracks', '//stats.wp.com/w.js', array(), gmdate( 'YW' ), true );
330 }
331
332 wp_set_script_translations( 'react-plugin', 'jetpack' );
333
334 // Add objects to be passed to the initial state of the app.
335 // Use wp_add_inline_script instead of wp_localize_script, see https://core.trac.wordpress.org/ticket/25280.
336 wp_add_inline_script( 'react-plugin', 'var Initial_State=JSON.parse(decodeURIComponent("' . rawurlencode( wp_json_encode( Jetpack_Redux_State_Helper::get_initial_state() ) ) . '"));', 'before' );
337
338 // This will set the default URL of the jp_redirects lib.
339 wp_add_inline_script( 'react-plugin', 'var jetpack_redirects = { currentSiteRawUrl: "' . $site_suffix . '"' . $blog_id_prop . ' };', 'before' );
340
341 // Adds Connection package initial state.
342 Connection_Initial_State::render_script( 'react-plugin' );
343 }
344 }
345