Completed
Push — fix/check-plan-deactivate-modu... ( 8de82e...36dfe9 )
by
unknown
08:27
created

e_modules()   C

Complexity

Conditions 11
Paths 14

Size

Total Lines 29
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 24
nc 14
nop 0
dl 0
loc 29
rs 5.2653
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
		// Adding a redirect tag wrapped in browser conditional comments
40
		add_action( 'admin_head', array( $this, 'add_legacy_browsers_head_script' ) );
41
42
		// Check if the site plan changed and deactivate modules accordingly.
43
		$this->check_plan_deactivate_modules( $hook );
44
	}
45
46
	/**
47
	 * Add Jetpack Dashboard sub-link and point it to AAG if the user can view stats, manage modules or if Protect is active.
48
	 * Otherwise and only if user is allowed to see the Jetpack Admin, the Dashboard sub-link is added but pointed to Apps tab.
49
	 *
50
	 * Works in Dev Mode or when user is connected.
51
	 *
52
	 * @since 4.3.0
53
	 */
54
	function jetpack_add_dashboard_sub_nav_item() {
55
		if ( Jetpack::is_development_mode() || Jetpack::is_active() ) {
56
			global $submenu;
57
			if ( current_user_can( 'jetpack_manage_modules' ) || Jetpack::is_module_active( 'protect' ) || current_user_can( 'view_stats' ) ) {
58
				$submenu['jetpack'][] = array( __( 'Dashboard', 'jetpack' ), 'jetpack_admin_page', Jetpack::admin_url( 'page=jetpack#/dashboard' ) );
59
			} elseif ( current_user_can( 'jetpack_admin_page' ) ) {
60
				$submenu['jetpack'][] = array( __( 'Dashboard', 'jetpack' ), 'jetpack_admin_page', Jetpack::admin_url( 'page=jetpack#/apps' ) );
61
			}
62
		}
63
	}
64
65
	/**
66
	 * If user is allowed to see the Jetpack Admin, add Settings sub-link.
67
	 *
68
	 * @since 4.3.0
69
	 */
70
	function jetpack_add_settings_sub_nav_item() {
71
		if ( ( Jetpack::is_development_mode() || Jetpack::is_active() ) && current_user_can( 'jetpack_admin_page' ) ) {
72
			global $submenu;
73
			$submenu['jetpack'][] = array( __( 'Settings', 'jetpack' ), 'jetpack_admin_page', Jetpack::admin_url( 'page=jetpack#/settings' ) );
74
		}
75
	}
76
77
	function add_fallback_head_meta() {
78
		echo '<meta http-equiv="refresh" content="0; url=?page=jetpack_modules">';
79
	}
80
81
	function add_noscript_head_meta() {
82
		echo '<noscript>';
83
		$this->add_fallback_head_meta();
84
		echo '</noscript>';
85
	}
86
87
	function add_legacy_browsers_head_script() {
88
		echo
89
			"<script type=\"text/javascript\">\n"
90
			. "/*@cc_on\n"
91
			. "if ( @_jscript_version <= 10) {\n"
92
			. "window.location.href = '?page=jetpack_modules';\n"
93
			. "}\n"
94
			. "@*/\n"
95
			. "</script>";
96
	}
97
98 View Code Duplication
	function jetpack_menu_order( $menu_order ) {
99
		$jp_menu_order = array();
100
101
		foreach ( $menu_order as $index => $item ) {
102
			if ( $item != 'jetpack' )
103
				$jp_menu_order[] = $item;
104
105
			if ( $index == 0 )
106
				$jp_menu_order[] = 'jetpack';
107
		}
108
109
		return $jp_menu_order;
110
	}
111
112
	// Render the configuration page for the module if it exists and an error
113
	// screen if the module is not configurable
114
	// @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...
115
	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...
116
		$module_name = preg_replace( '/[^\da-z\-]+/', '', $_GET['configure'] );
117
118
		include_once( JETPACK__PLUGIN_DIR . '_inc/header.php' );
119
		echo '<div class="wrap configure-module">';
120
121
		if ( Jetpack::is_module( $module_name ) && current_user_can( 'jetpack_configure_modules' ) ) {
122
			Jetpack::admin_screen_configure_module( $module_name );
123
		} else {
124
			echo '<h2>' . esc_html__( 'Error, bad module.', 'jetpack' ) . '</h2>';
125
		}
126
127
		echo '</div><!-- /wrap -->';
128
	}
129
130
	function page_render() {
131
		// Handle redirects to configuration pages
132
		if ( ! empty( $_GET['configure'] ) ) {
133
			return $this->render_nojs_configurable( $_GET['configure'] );
134
		}
135
136
		/** This action is already documented in views/admin/admin-page.php */
137
		do_action( 'jetpack_notices' );
138
139
		// Try fetching by patch
140
		$static_html = @file_get_contents( JETPACK__PLUGIN_DIR . '_inc/build/static.html' );
141
142
		if ( false === $static_html ) {
143
144
			// If we still have nothing, display an error
145
			esc_html_e( 'Error fetching static.html.', 'jetpack' );
146
		} else {
147
148
			// We got the static.html so let's display it
149
			echo $static_html;
150
		}
151
	}
152
153
	function get_i18n_data() {
154
155
		$i18n_json = JETPACK__PLUGIN_DIR . 'languages/json/jetpack-' . get_locale() . '.json';
156
157
		if ( is_file( $i18n_json ) && is_readable( $i18n_json ) ) {
158
			$locale_data = @file_get_contents( $i18n_json );
159
			if ( $locale_data ) {
160
				return $locale_data;
161
			}
162
		}
163
164
		// Return empty if we have nothing to return so it doesn't fail when parsed in JS
165
		return '{}';
166
	}
167
168
	/**
169
	 * Gets array of any Jetpack notices that have been dismissed.
170
	 *
171
	 * @since 4.0.1
172
	 * @return mixed|void
173
	 */
174
	function get_dismissed_jetpack_notices() {
175
		$jetpack_dismissed_notices = get_option( 'jetpack_dismissed_notices', array() );
176
		/**
177
		 * Array of notices that have been dismissed.
178
		 *
179
		 * @since 4.0.1
180
		 *
181
		 * @param array $jetpack_dismissed_notices If empty, will not show any Jetpack notices.
182
		 */
183
		$dismissed_notices = apply_filters( 'jetpack_dismissed_notices', $jetpack_dismissed_notices );
184
		return $dismissed_notices;
185
	}
186
187
	function additional_styles() {
188
		$rtl = is_rtl() ? '.rtl' : '';
189
190
		wp_enqueue_style( 'dops-css', plugins_url( "_inc/build/admin.dops-style$rtl.css", JETPACK__PLUGIN_FILE ), array(), JETPACK__VERSION );
191
		wp_enqueue_style( 'components-css', plugins_url( "_inc/build/style.min$rtl.css", JETPACK__PLUGIN_FILE ), array(), JETPACK__VERSION );
192
	}
193
194
	function page_admin_scripts() {
195
		if ( $this->is_redirecting ) {
196
			return; // No need for scripts on a fallback page
197
		}
198
199
		$is_dev_mode = Jetpack::is_development_mode();
200
201
		// Enqueue jp.js and localize it
202
		wp_enqueue_script( 'react-plugin', plugins_url( '_inc/build/admin.js', JETPACK__PLUGIN_FILE ), array(), JETPACK__VERSION, true );
203
204
		if ( ! $is_dev_mode ) {
205
			// Required for Analytics
206
			wp_enqueue_script( 'jp-tracks', '//stats.wp.com/w.js', array(), gmdate( 'YW' ), true );
207
		}
208
209
		$localeSlug = explode( '_', get_locale() );
210
		$localeSlug = $localeSlug[0];
211
212
		// Collecting roles that can view site stats
213
		$stats_roles = array();
214
		$enabled_roles = function_exists( 'stats_get_option' ) ? stats_get_option( 'roles' ) : array( 'administrator' );
215
		foreach( get_editable_roles() as $slug => $role ) {
216
			$stats_roles[ $slug ] = array(
217
				'name' => translate_user_role( $role['name'] ),
218
				'canView' => is_array( $enabled_roles ) ? in_array( $slug, $enabled_roles, true ) : false,
219
			);
220
		}
221
222
		$response = rest_do_request( new WP_REST_Request( 'GET', '/jetpack/v4/module/all' ) );
223
		$modules = $response->get_data();
224
225
		// Preparing translated fields for JSON encoding by transforming all HTML entities to
226
		// respective characters.
227
		foreach( $modules as $slug => $data ) {
228
			$modules[ $slug ]['name'] = html_entity_decode( $data['name'] );
229
			$modules[ $slug ]['description'] = html_entity_decode( $data['description'] );
230
			$modules[ $slug ]['short_description'] = html_entity_decode( $data['short_description'] );
231
			$modules[ $slug ]['long_description'] = html_entity_decode( $data['long_description'] );
232
		}
233
234
		// Add objects to be passed to the initial state of the app
235
		wp_localize_script( 'react-plugin', 'Initial_State', array(
236
			'WP_API_root' => esc_url_raw( rest_url() ),
237
			'WP_API_nonce' => wp_create_nonce( 'wp_rest' ),
238
			'pluginBaseUrl' => plugins_url( '', JETPACK__PLUGIN_FILE ),
239
			'connectionStatus' => array(
240
				'isActive'  => Jetpack::is_active(),
241
				'isStaging' => Jetpack::is_staging_site(),
242
				'devMode'   => array(
243
					'isActive' => $is_dev_mode,
244
					'constant' => defined( 'JETPACK_DEV_DEBUG' ) && JETPACK_DEV_DEBUG,
245
					'url'      => site_url() && false === strpos( site_url(), '.' ),
246
					'filter'   => apply_filters( 'jetpack_development_mode', false ),
247
				),
248
				'isPublic'	=> '1' == get_option( 'blog_public' ),
249
				'isInIdentityCrisis' => Jetpack::validate_sync_error_idc_option(),
250
			),
251
			'dismissedNotices' => $this->get_dismissed_jetpack_notices(),
252
			'isDevVersion' => Jetpack::is_development_version(),
253
			'currentVersion' => JETPACK__VERSION,
254
			'happinessGravIds' => jetpack_get_happiness_gravatar_ids(),
255
			'getModules' => $modules,
256
			'showJumpstart' => jetpack_show_jumpstart(),
257
			'rawUrl' => Jetpack::build_raw_urls( get_home_url() ),
258
			'adminUrl' => esc_url( admin_url() ),
259
			'stats' => array(
260
				// data is populated asynchronously on page load
261
				'data'  => array(
262
					'general' => false,
263
					'day'     => false,
264
					'week'    => false,
265
					'month'   => false,
266
				),
267
				'roles' => $stats_roles,
268
			),
269
			'settingNames' => array(
270
				'jetpack_holiday_snow_enabled' => function_exists( 'jetpack_holiday_snow_option_name' ) ? jetpack_holiday_snow_option_name() : false,
271
			),
272
			'userData' => array(
273
//				'othersLinked' => Jetpack::get_other_linked_admins(),
274
				'currentUser'  => jetpack_current_user_data(),
275
			),
276
			'locale' => $this->get_i18n_data(),
277
			'localeSlug' => $localeSlug,
278
			'jetpackStateNotices' => array(
279
				'messageCode' => Jetpack::state( 'message' ),
280
				'errorCode' => Jetpack::state( 'error' ),
281
				'errorDescription' => Jetpack::state( 'error_description' ),
282
			),
283
			'tracksUserData' => Jetpack_Tracks_Client::get_connected_user_tracks_identity(),
284
			'currentIp' => function_exists( 'jetpack_protect_get_ip' ) ? jetpack_protect_get_ip() : false
285
		) );
286
	}
287
}
288
289
/*
290
 * List of happiness Gravatar IDs
291
 *
292
 * @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...
293
 * @since 4.1.0
294
 * @return array
295
 */
296
function jetpack_get_happiness_gravatar_ids() {
297
	return array(
298
		'623f42e878dbd146ddb30ebfafa1375b',
299
		'561be467af56cefa58e02782b7ac7510',
300
		'd8ad409290a6ae7b60f128a0b9a0c1c5',
301
		'790618302648bd80fa8a55497dfd8ac8',
302
		'6e238edcb0664c975ccb9e8e80abb307',
303
		'4e6c84eeab0a1338838a9a1e84629c1a',
304
		'9d4b77080c699629e846d3637b3a661c',
305
		'4626de7797aada973c1fb22dfe0e5109',
306
		'190cf13c9cd358521085af13615382d5',
307
		'f7006d10e9f7dd7bea89a001a2a2fd59',
308
		'16acbc88e7aa65104ed289d736cb9698',
309
		'4d5ad4219c6f676ea1e7d40d2e8860e8',
310
		'e301f7d01b09e7578fdfc1b1ec1bc08d',
311
		'42f4c73f5337486e199f6e3b3910f168',
312
		'e7b26de48e76498cff880abca1eed8da',
313
		'764fb02aaae2ff64c0625c763d82b74e',
314
		'4988305772319fb9bc8fce0a7acb3aa1',
315
		'5d8695c4b81592f1255721d2644627ca',
316
		'0e2249a7de3404bc6d5207a45e911187',
317
	);
318
}
319
320
/*
321
 * Only show Jump Start on first activation.
322
 * Any option 'jumpstart' other than 'new connection' will hide it.
323
 *
324
 * The option can be of 4 things, and will be stored as such:
325
 * new_connection      : Brand new connection - Show
326
 * jumpstart_activated : Jump Start has been activated - dismiss
327
 * jetpack_action_taken: Manual activation of a module already happened - dismiss
328
 * jumpstart_dismissed : Manual dismissal of Jump Start - dismiss
329
 *
330
 * @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...
331
 * @since 3.6
332
 * @return bool | show or hide
333
 */
334
function jetpack_show_jumpstart() {
335
	if ( ! Jetpack::is_active() ) {
336
		return false;
337
	}
338
	$jumpstart_option = Jetpack_Options::get_option( 'jumpstart' );
339
340
	$hide_options = array(
341
		'jumpstart_activated',
342
		'jetpack_action_taken',
343
		'jumpstart_dismissed'
344
	);
345
346
	if ( ! $jumpstart_option || in_array( $jumpstart_option, $hide_options ) ) {
347
		return false;
348
	}
349
350
	return true;
351
}
352
353
/*
354
 * Gather data about the master user.
355
 *
356
 * @since 4.1.0
357
 *
358
 * @return array
359
 */
360 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...
361
	$masterID = Jetpack_Options::get_option( 'master_user' );
362
	if ( ! get_user_by( 'id', $masterID ) ) {
363
		return false;
364
	}
365
366
	$jetpack_user = get_userdata( $masterID );
367
	$wpcom_user   = Jetpack::get_connected_user_data( $jetpack_user->ID );
368
	$gravatar     = get_avatar( $jetpack_user->ID, 40 );
369
370
	$master_user_data = array(
371
		'jetpackUser' => $jetpack_user,
372
		'wpcomUser'   => $wpcom_user,
373
		'gravatar'    => $gravatar,
374
	);
375
376
	return $master_user_data;
377
}
378
379
/**
380
 * Gather data about the current user.
381
 *
382
 * @since 4.1.0
383
 *
384
 * @return array
385
 */
386
function jetpack_current_user_data() {
387
	global $current_user;
388
	$is_master_user = $current_user->ID == Jetpack_Options::get_option( 'master_user' );
389
	$dotcom_data    = Jetpack::get_connected_user_data();
390
	// Add connected user gravatar to the returned dotcom_data
391
	$avatar_data = Jetpack::get_avatar_url( $dotcom_data[ 'email' ] );
392
	$dotcom_data[ 'avatar'] = $avatar_data[ 0 ];
393
394
	$current_user_data = array(
395
		'isConnected' => Jetpack::is_user_connected( $current_user->ID ),
396
		'isMaster'    => $is_master_user,
397
		'username'    => $current_user->user_login,
398
		'wpcomUser'   => $dotcom_data,
399
		'gravatar'    => get_avatar( $current_user->ID, 40 ),
400
		'permissions' => array(
401
			'admin_page'         => current_user_can( 'jetpack_admin_page' ),
402
			'connect'            => current_user_can( 'jetpack_connect' ),
403
			'disconnect'         => current_user_can( 'jetpack_disconnect' ),
404
			'manage_modules'     => current_user_can( 'jetpack_manage_modules' ),
405
			'network_admin'      => current_user_can( 'jetpack_network_admin_page' ),
406
			'network_sites_page' => current_user_can( 'jetpack_network_sites_page' ),
407
			'edit_posts'         => current_user_can( 'edit_posts' ),
408
			'manage_options'     => current_user_can( 'manage_options' ),
409
			'view_stats'		 => current_user_can( 'view_stats' ),
410
			'manage_plugins'	 => current_user_can( 'install_plugins' )
411
									&& current_user_can( 'activate_plugins' )
412
									&& current_user_can( 'update_plugins' )
413
									&& current_user_can( 'delete_plugins' ),
414
		),
415
	);
416
417
	return $current_user_data;
418
}
419