Completed
Push — master-stable ( acd8d4...fb4264 )
by
unknown
324:02 queued 314:48
created

Jetpack_React_Page::add_page_actions()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 10
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 21
rs 8.7624
1
<?php
2
include_once( 'class.jetpack-admin-page.php' );
3
4
// Builds the landing page and its menu
5
class Jetpack_React_Page extends Jetpack_Admin_Page {
6
7
	protected $dont_show_if_not_active = false;
8
9
	protected $is_redirecting = false;
10
11
	function get_page_hook() {
12
		$title = _x( 'Jetpack', 'The menu item label', 'jetpack' );
13
14
		// Add the main admin Jetpack menu
15
		return add_menu_page( 'Jetpack', $title, 'jetpack_admin_page', 'jetpack', array( $this, 'render' ), 'div' );
16
	}
17
18
	function add_page_actions( $hook ) {
19
		/** This action is documented in class.jetpack.php */
20
		do_action( 'jetpack_admin_menu', $hook );
21
22
		// Place the Jetpack menu item on top and others in the order they appear
23
		add_filter( 'custom_menu_order',         '__return_true' );
24
		add_filter( 'menu_order',                array( $this, 'jetpack_menu_order' ) );
25
26
		if ( ! isset( $_GET['page'] ) || 'jetpack' !== $_GET['page'] || ! empty( $_GET['configure'] ) ) {
27
			return; // No need to handle the fallback redirection if we are not on the Jetpack page
28
		}
29
30
		// Adding a redirect meta tag for older WordPress versions
31
		if ( $this->is_wp_version_too_old() ) {
32
			$this->is_redirecting = true;
33
			add_action( 'admin_head', array( $this, 'add_fallback_head_meta' ) );
34
		}
35
36
		// Adding a redirect meta tag wrapped in noscript tags for all browsers in case they have JavaScript disabled
37
		add_action( 'admin_head', array( $this, 'add_noscript_head_meta' ) );
38
	}
39
40
	/**
41
	 * Add Jetpack Dashboard sub-link and point it to AAG if the user can view stats, manage modules or if Protect is active.
42
	 * Otherwise and only if user is allowed to see the Jetpack Admin, the Dashboard sub-link is added but pointed to Apps tab.
43
	 *
44
	 * Works in Dev Mode or when user is connected.
45
	 *
46
	 * @since 4.3
47
	 */
48
	function jetpack_add_dashboard_sub_nav_item() {
49
		if ( Jetpack::is_development_mode() || Jetpack::is_active() ) {
50
			global $submenu;
51
			if ( current_user_can( 'jetpack_manage_modules' ) || Jetpack::is_module_active( 'protect' ) || current_user_can( 'view_stats' ) ) {
52
				$submenu['jetpack'][] = array( __( 'Dashboard', 'jetpack' ), 'jetpack_admin_page', Jetpack::admin_url( 'page=jetpack#/dashboard' ) );
53
			} elseif ( current_user_can( 'jetpack_admin_page' ) ) {
54
				$submenu['jetpack'][] = array( __( 'Dashboard', 'jetpack' ), 'jetpack_admin_page', Jetpack::admin_url( 'page=jetpack#/apps' ) );
55
			}
56
		}
57
	}
58
59
	/**
60
	 * If user is allowed to see the Jetpack Admin, add Settings sub-link.
61
	 *
62
	 * @since 4.3
63
	 */
64
	function jetpack_add_settings_sub_nav_item() {
65
		if ( ( Jetpack::is_development_mode() || Jetpack::is_active() ) && current_user_can( 'jetpack_admin_page' ) ) {
66
			global $submenu;
67
			$submenu['jetpack'][] = array( __( 'Settings', 'jetpack' ), 'jetpack_admin_page', Jetpack::admin_url( 'page=jetpack#/settings' ) );
68
		}
69
	}
70
71
	function add_fallback_head_meta() {
72
		echo '<meta http-equiv="refresh" content="0; url=?page=jetpack_modules">';
73
	}
74
75
	function add_noscript_head_meta() {
76
		echo '<noscript>';
77
		$this->add_fallback_head_meta();
78
		echo '</noscript>';
79
	}
80
81 View Code Duplication
	function jetpack_menu_order( $menu_order ) {
82
		$jp_menu_order = array();
83
84
		foreach ( $menu_order as $index => $item ) {
85
			if ( $item != 'jetpack' )
86
				$jp_menu_order[] = $item;
87
88
			if ( $index == 0 )
89
				$jp_menu_order[] = 'jetpack';
90
		}
91
92
		return $jp_menu_order;
93
	}
94
95
	// Render the configuration page for the module if it exists and an error
96
	// screen if the module is not configurable
97
	// @todo remove when real settings are in place
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
98 View Code Duplication
	function render_nojs_configurable( $module_name ) {
0 ignored issues
show
Unused Code introduced by
The parameter $module_name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
99
		$module_name = preg_replace( '/[^\da-z\-]+/', '', $_GET['configure'] );
100
101
		include_once( JETPACK__PLUGIN_DIR . '_inc/header.php' );
102
		echo '<div class="wrap configure-module">';
103
104
		if ( Jetpack::is_module( $module_name ) && current_user_can( 'jetpack_configure_modules' ) ) {
105
			Jetpack::admin_screen_configure_module( $module_name );
106
		} else {
107
			echo '<h2>' . esc_html__( 'Error, bad module.', 'jetpack' ) . '</h2>';
108
		}
109
110
		echo '</div><!-- /wrap -->';
111
	}
112
113
	function page_render() {
114
		// Handle redirects to configuration pages
115
		if ( ! empty( $_GET['configure'] ) ) {
116
			return $this->render_nojs_configurable( $_GET['configure'] );
117
		}
118
119
		/** This action is already documented in views/admin/admin-page.php */
120
		do_action( 'jetpack_notices' );
121
122
		echo file_get_contents( JETPACK__PLUGIN_DIR . '/_inc/build/static.html' );
123
	}
124
125
	function get_i18n_data() {
126
		$locale_data = @file_get_contents( JETPACK__PLUGIN_DIR . '/languages/json/jetpack-' . get_locale() . '.json' );
127
		if ( $locale_data ) {
128
			return $locale_data;
129
		} else {
130
			return '{}';
131
		}
132
	}
133
134
	/**
135
	 * Gets array of any Jetpack notices that have been dismissed.
136
	 *
137
	 * @since 4.0.1
138
	 * @return mixed|void
139
	 */
140
	function get_dismissed_jetpack_notices() {
141
		$jetpack_dismissed_notices = get_option( 'jetpack_dismissed_notices', array() );
142
		/**
143
		 * Array of notices that have been dismissed.
144
		 *
145
		 * @since 4.0.1
146
		 *
147
		 * @param array $jetpack_dismissed_notices If empty, will not show any Jetpack notices.
148
		 */
149
		$dismissed_notices = apply_filters( 'jetpack_dismissed_notices', $jetpack_dismissed_notices );
150
		return $dismissed_notices;
151
	}
152
153
	function page_admin_scripts() {
154
		if ( $this->is_redirecting ) {
155
			return; // No need for scripts on a fallback page
156
		}
157
158
		$rtl = is_rtl() ? '.rtl' : '';
159
160
		// Enqueue jp.js and localize it
161
		wp_enqueue_script( 'react-plugin', plugins_url( '_inc/build/admin.js', JETPACK__PLUGIN_FILE ), array(), JETPACK__VERSION, true );
162
		wp_enqueue_style( 'dops-css', plugins_url( "_inc/build/admin.dops-style$rtl.css", JETPACK__PLUGIN_FILE ), array(), JETPACK__VERSION );
163
		wp_enqueue_style( 'components-css', plugins_url( "_inc/build/style.min$rtl.css", JETPACK__PLUGIN_FILE ), array(), JETPACK__VERSION );
164
165
		$localeSlug = explode( '_', get_locale() );
166
		$localeSlug = $localeSlug[0];
167
168
		// Collecting roles that can view site stats
169
		$stats_roles = array();
170
		$enabled_roles = function_exists( 'stats_get_option' ) ? stats_get_option( 'roles' ) : array( 'administrator' );
171
		foreach( get_editable_roles() as $slug => $role ) {
172
			$stats_roles[ $slug ] = array(
173
				'name' => translate_user_role( $role['name'] ),
174
				'canView' => in_array( $slug, $enabled_roles, true ),
175
			);
176
		}
177
178
		// Add objects to be passed to the initial state of the app
179
		wp_localize_script( 'react-plugin', 'Initial_State', array(
180
			'WP_API_root' => esc_url_raw( rest_url() ),
181
			'WP_API_nonce' => wp_create_nonce( 'wp_rest' ),
182
			'pluginBaseUrl' => plugins_url( '', JETPACK__PLUGIN_FILE ),
183
			'connectionStatus' => array(
184
				'isActive'  => Jetpack::is_active(),
185
				'isStaging' => Jetpack::is_staging_site(),
186
				'devMode'   => array(
187
					'isActive' => Jetpack::is_development_mode(),
188
					'constant' => defined( 'JETPACK_DEV_DEBUG' ) && JETPACK_DEV_DEBUG,
189
					'url'      => site_url() && false === strpos( site_url(), '.' ),
190
					'filter'   => apply_filters( 'jetpack_development_mode', false ),
191
				),
192
				'isPublic'	=> '1' == get_option( 'blog_public' ),
193
			),
194
			'dismissedNotices' => $this->get_dismissed_jetpack_notices(),
195
			'isDevVersion' => Jetpack::is_development_version(),
196
			'currentVersion' => JETPACK__VERSION,
197
			'happinessGravIds' => jetpack_get_happiness_gravatar_ids(),
198
			'getModules' => Jetpack_Core_Json_Api_Endpoints::get_modules(),
199
			'showJumpstart' => jetpack_show_jumpstart(),
200
			'rawUrl' => Jetpack::build_raw_urls( get_home_url() ),
201
			'adminUrl' => esc_url( admin_url() ),
202
			'stats' => array(
203
				// data is populated asynchronously on page load
204
				'data'  => array(
205
					'general' => false,
206
					'day'     => false,
207
					'week'    => false,
208
					'month'   => false,
209
				),
210
				'roles' => $stats_roles,
211
			),
212
			'settingNames' => array(
213
				'jetpack_holiday_snow_enabled' => function_exists( 'jetpack_holiday_snow_option_name' ) ? jetpack_holiday_snow_option_name() : false,
214
			),
215
			'userData' => array(
216
				'othersLinked' => jetpack_get_other_linked_users(),
217
				'currentUser'  => jetpack_current_user_data(),
218
			),
219
			'locale' => $this->get_i18n_data(),
220
			'localeSlug' => $localeSlug,
221
			'jetpackStateNotices' => array(
222
				'messageCode' => Jetpack::state( 'message' ),
223
				'errorCode' => Jetpack::state( 'error' ),
224
				'errorDescription' => Jetpack::state( 'error_description' ),
225
			),
226
		) );
227
	}
228
}
229
230
/*
231
 * List of happiness Gravatar IDs
232
 *
233
 * @todo move to functions.global.php when available
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
234
 * @since 4.1.0
235
 * @return array
236
 */
237
function jetpack_get_happiness_gravatar_ids() {
238
	return array(
239
		'623f42e878dbd146ddb30ebfafa1375b',
240
		'561be467af56cefa58e02782b7ac7510',
241
		'd8ad409290a6ae7b60f128a0b9a0c1c5',
242
		'790618302648bd80fa8a55497dfd8ac8',
243
		'6e238edcb0664c975ccb9e8e80abb307',
244
		'4e6c84eeab0a1338838a9a1e84629c1a',
245
		'9d4b77080c699629e846d3637b3a661c',
246
		'4626de7797aada973c1fb22dfe0e5109',
247
		'190cf13c9cd358521085af13615382d5',
248
		'f7006d10e9f7dd7bea89a001a2a2fd59',
249
		'16acbc88e7aa65104ed289d736cb9698',
250
		'4d5ad4219c6f676ea1e7d40d2e8860e8',
251
		'e301f7d01b09e7578fdfc1b1ec1bc08d',
252
		'42f4c73f5337486e199f6e3b3910f168',
253
		'e7b26de48e76498cff880abca1eed8da',
254
		'764fb02aaae2ff64c0625c763d82b74e',
255
		'4988305772319fb9bc8fce0a7acb3aa1',
256
		'5d8695c4b81592f1255721d2644627ca',
257
		'0e2249a7de3404bc6d5207a45e911187',
258
	);
259
}
260
261
/*
262
 * Only show Jump Start on first activation.
263
 * Any option 'jumpstart' other than 'new connection' will hide it.
264
 *
265
 * The option can be of 4 things, and will be stored as such:
266
 * new_connection      : Brand new connection - Show
267
 * jumpstart_activated : Jump Start has been activated - dismiss
268
 * jetpack_action_taken: Manual activation of a module already happened - dismiss
269
 * jumpstart_dismissed : Manual dismissal of Jump Start - dismiss
270
 *
271
 * @todo move to functions.global.php when available
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
272
 * @since 3.6
273
 * @return bool | show or hide
274
 */
275
function jetpack_show_jumpstart() {
276
	if ( ! Jetpack::is_active() ) {
277
		return false;
278
	}
279
	$jumpstart_option = Jetpack_Options::get_option( 'jumpstart' );
280
281
	$hide_options = array(
282
		'jumpstart_activated',
283
		'jetpack_action_taken',
284
		'jumpstart_dismissed'
285
	);
286
287
	if ( ! $jumpstart_option || in_array( $jumpstart_option, $hide_options ) ) {
288
		return false;
289
	}
290
291
	return true;
292
}
293
294
/*
295
 * Checks to see if there are any other users available to become primary
296
 * Users must both:
297
 * - Be linked to wpcom
298
 * - Be an admin
299
 *
300
 * @return mixed False if no other users are linked, Int if there are.
301
 */
302 View Code Duplication
function jetpack_get_other_linked_users() {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
303
	// If only one admin
304
	$all_users = count_users();
305
	if ( 2 > $all_users['avail_roles']['administrator'] ) {
306
		return false;
307
	}
308
309
	$users = get_users();
310
	$available = array();
311
	// If no one else is linked to dotcom
312
	foreach ( $users as $user ) {
313
		if ( isset( $user->caps['administrator'] ) && Jetpack::is_user_connected( $user->ID ) ) {
314
			$available[] = $user->ID;
315
		}
316
	}
317
318
	if ( 2 > count( $available ) ) {
319
		return false;
320
	}
321
322
	return count( $available );
323
}
324
325
/*
326
 * Gather data about the master user.
327
 *
328
 * @since 4.1.0
329
 *
330
 * @return array
331
 */
332 View Code Duplication
function jetpack_master_user_data() {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
333
	$masterID = Jetpack_Options::get_option( 'master_user' );
334
	if ( ! get_user_by( 'id', $masterID ) ) {
335
		return false;
336
	}
337
338
	$jetpack_user = get_userdata( $masterID );
339
	$wpcom_user   = Jetpack::get_connected_user_data( $jetpack_user->ID );
340
	$gravatar     = get_avatar( $jetpack_user->ID, 40 );
341
342
	$master_user_data = array(
343
		'jetpackUser' => $jetpack_user,
344
		'wpcomUser'   => $wpcom_user,
345
		'gravatar'    => $gravatar,
346
	);
347
348
	return $master_user_data;
349
}
350
351
/*
352
 * Gather data about the current user.
353
 *
354
 * @since 4.1.0
355
 *
356
 * @return array
357
 */
358
function jetpack_current_user_data() {
359
	global $current_user;
360
	$is_master_user = $current_user->ID == Jetpack_Options::get_option( 'master_user' );
361
	$dotcom_data    = Jetpack::get_connected_user_data();
362
363
	$current_user_data = array(
364
		'isConnected' => Jetpack::is_user_connected( $current_user->ID ),
365
		'isMaster'    => $is_master_user,
366
		'username'    => $current_user->user_login,
367
		'wpcomUser'   => $dotcom_data,
368
		'gravatar'    => get_avatar( $current_user->ID, 40 ),
369
		'permissions' => array(
370
			'admin_page'         => current_user_can( 'jetpack_admin_page' ),
371
			'connect'            => current_user_can( 'jetpack_connect' ),
372
			'disconnect'         => current_user_can( 'jetpack_disconnect' ),
373
			'manage_modules'     => current_user_can( 'jetpack_manage_modules' ),
374
			'network_admin'      => current_user_can( 'jetpack_network_admin_page' ),
375
			'network_sites_page' => current_user_can( 'jetpack_network_sites_page' ),
376
			'edit_posts'         => current_user_can( 'edit_posts' ),
377
			'manage_options'     => current_user_can( 'manage_options' ),
378
			'view_stats'		 => current_user_can( 'view_stats' ),
379
		),
380
	);
381
382
	return $current_user_data;
383
}
384