PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 14.5.1
Jetpack – WP Security, Backup, Speed, & Growth v14.5.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
340 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 * At that point, admins can access the Jetpack Dashboard instead.
85 *
86 * @since 13.8
87 */
88 public function remove_jetpack_menu() {
89 if (
90 ( new Status() )->is_offline_mode()
91 || Jetpack::is_connection_ready()
92 ) {
93 remove_submenu_page( 'jetpack', 'jetpack' );
94 }
95 }
96
97 /**
98 * Add Jetpack Dashboard sub-link and point it to AAG if the user can view stats, manage modules or if Protect is active.
99 *
100 * Works in Dev Mode or when user is connected.
101 *
102 * @since 4.3.0
103 */
104 public function jetpack_add_dashboard_sub_nav_item() {
105 if ( ( new Status() )->is_offline_mode() || Jetpack::is_connection_ready() ) {
106 Admin_Menu::add_menu(
107 __( 'Dashboard', 'jetpack' ),
108 __( 'Dashboard', 'jetpack' ),
109 'jetpack_admin_page',
110 Jetpack::admin_url( array( 'page' => 'jetpack#/dashboard' ) ),
111 null, // @phan-suppress-current-line PhanTypeMismatchArgumentProbablyReal -- See https://core.trac.wordpress.org/ticket/52539.
112 14
113 );
114 }
115 }
116
117 /**
118 * Determine whether a user can access the Jetpack Settings page.
119 *
120 * Rules are:
121 * - user is allowed to see the Jetpack Admin
122 * - site is connected or in offline mode
123 * - non-admins only need access to the settings when there are modules they can manage.
124 *
125 * @return bool $can_access_settings Can the user access settings.
126 */
127 private function can_access_settings() {
128 $connection = new Connection_Manager( 'jetpack' );
129 $status = new Status();
130
131 // User must have the necessary permissions to see the Jetpack settings pages.
132 if ( ! current_user_can( 'edit_posts' ) ) {
133 return false;
134 }
135
136 // In offline mode, allow access to admins.
137 if ( $status->is_offline_mode() && current_user_can( 'manage_options' ) ) {
138 return true;
139 }
140
141 // If not in offline mode but site is not connected, bail.
142 if ( ! Jetpack::is_connection_ready() ) {
143 return false;
144 }
145
146 /*
147 * Additional checks for non-admins.
148 */
149 if ( ! current_user_can( 'manage_options' ) ) {
150 // If the site isn't connected at all, bail.
151 if ( ! $connection->has_connected_owner() ) {
152 return false;
153 }
154
155 /*
156 * If they haven't connected their own account yet,
157 * they have no use for the settings page.
158 * They will not be able to manage any settings.
159 */
160 if ( ! $connection->is_user_connected() ) {
161 return false;
162 }
163
164 /*
165 * Non-admins only have access to settings
166 * for the following modules:
167 * - Publicize
168 * - Post By Email
169 * If those modules are not available, bail.
170 */
171 if (
172 ! Jetpack::is_module_active( 'post-by-email' )
173 && (
174 Publicize_Script_Data::has_feature_flag( 'admin-page' ) ||
175 ! Jetpack::is_module_active( 'publicize' ) ||
176 ! current_user_can( 'publish_posts' )
177 )
178 ) {
179 return false;
180 }
181 }
182
183 // fallback.
184 return true;
185 }
186
187 /**
188 * Jetpack Settings sub-link.
189 *
190 * @since 4.3.0
191 * @since 9.7.0 If Connection does not have an owner, restrict it to admins
192 */
193 public function jetpack_add_settings_sub_nav_item() {
194 if ( $this->can_access_settings() ) {
195 Admin_Menu::add_menu(
196 __( 'Settings', 'jetpack' ),
197 __( 'Settings', 'jetpack' ),
198 'jetpack_admin_page',
199 Jetpack::admin_url( array( 'page' => 'jetpack#/settings' ) ),
200 null, // @phan-suppress-current-line PhanTypeMismatchArgumentProbablyReal -- See https://core.trac.wordpress.org/ticket/52539.
201 13
202 );
203 }
204 }
205
206 /**
207 * Fallback redirect meta tag if the REST API is disabled.
208 *
209 * @return void
210 */
211 public function add_fallback_head_meta() {
212 echo '<meta http-equiv="refresh" content="0; url=?page=jetpack_modules">';
213 }
214
215 /**
216 * Fallback meta tag wrapped in noscript tags for all browsers in case they have JavaScript disabled.
217 *
218 * @return void
219 */
220 public function add_noscript_head_meta() {
221 echo '<noscript>';
222 $this->add_fallback_head_meta();
223 echo '</noscript>';
224 }
225
226 /**
227 * Add action to render page specific HTML.
228 *
229 * @return void
230 */
231 public function page_render() {
232 /** This action is already documented in class.jetpack-admin-page.php */
233 do_action( 'jetpack_notices' );
234
235 // Fetch static.html.
236 $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.
237
238 if ( false === $static_html ) {
239
240 // If we still have nothing, display an error.
241 echo '<p>';
242 esc_html_e( 'Error fetching static.html. Try running: ', 'jetpack' );
243 echo '<code>pnpm run distclean && pnpm jetpack build plugins/jetpack</code>';
244 echo '</p>';
245 } else {
246 // We got the static.html so let's display it.
247 echo $static_html; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
248 }
249 }
250 /**
251 * Allow robust deep links to React.
252 *
253 * The Jetpack dashboard requires fragments/hash values to make
254 * a deep link to it but passing fragments as part of a return URL
255 * will most often be discarded throughout the process.
256 * This logic aims to bridge this gap and reduce the chance of React
257 * specific links being broken while passing them along.
258 */
259 public function react_redirects() {
260 global $pagenow;
261
262 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
263 if ( 'admin.php' !== $pagenow || ! isset( $_GET['jp-react-redirect'] ) ) {
264 return;
265 }
266
267 $allowed_paths = array(
268 'product-purchased' => admin_url( '/admin.php?page=jetpack#/recommendations/product-purchased' ),
269 );
270
271 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
272 $target = sanitize_text_field( wp_unslash( $_GET['jp-react-redirect'] ) );
273 if ( isset( $allowed_paths[ $target ] ) ) {
274 wp_safe_redirect( $allowed_paths[ $target ] );
275 exit( 0 );
276 }
277 }
278
279 /**
280 * Load styles for static page.
281 */
282 public function additional_styles() {
283 Jetpack_Admin_Page::load_wrapper_styles();
284 }
285
286 /**
287 * Load admin page scripts.
288 */
289 public function page_admin_scripts() {
290 if ( $this->is_redirecting ) {
291 return; // No need for scripts on a fallback page.
292 }
293
294 $status = new Status();
295 $is_offline_mode = $status->is_offline_mode();
296 $site_suffix = $status->get_site_suffix();
297 $script_deps_path = JETPACK__PLUGIN_DIR . '_inc/build/admin.asset.php';
298 $script_dependencies = array( 'jquery', 'wp-polyfill' );
299 $version = JETPACK__VERSION;
300 if ( file_exists( $script_deps_path ) ) {
301 $asset_manifest = include $script_deps_path;
302 $script_dependencies = $asset_manifest['dependencies'];
303 $version = $asset_manifest['version'];
304 }
305
306 $blog_id_prop = '';
307 if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) {
308 $blog_id = Connection_Manager::get_site_id( true );
309 if ( $blog_id ) {
310 $blog_id_prop = ', currentBlogID: "' . (int) $blog_id . '"';
311 }
312 }
313
314 wp_enqueue_script(
315 'react-plugin',
316 plugins_url( '_inc/build/admin.js', JETPACK__PLUGIN_FILE ),
317 $script_dependencies,
318 $version,
319 true
320 );
321
322 if ( ! $is_offline_mode && Jetpack::is_connection_ready() ) {
323 // Required for Analytics.
324 wp_enqueue_script( 'jp-tracks', '//stats.wp.com/w.js', array(), gmdate( 'YW' ), true );
325 }
326
327 wp_set_script_translations( 'react-plugin', 'jetpack' );
328
329 // Add objects to be passed to the initial state of the app.
330 // Use wp_add_inline_script instead of wp_localize_script, see https://core.trac.wordpress.org/ticket/25280.
331 wp_add_inline_script( 'react-plugin', 'var Initial_State=JSON.parse(decodeURIComponent("' . rawurlencode( wp_json_encode( Jetpack_Redux_State_Helper::get_initial_state() ) ) . '"));', 'before' );
332
333 // This will set the default URL of the jp_redirects lib.
334 wp_add_inline_script( 'react-plugin', 'var jetpack_redirects = { currentSiteRawUrl: "' . $site_suffix . '"' . $blog_id_prop . ' };', 'before' );
335
336 // Adds Connection package initial state.
337 Connection_Initial_State::render_script( 'react-plugin' );
338 }
339 }
340