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