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