Completed
Push — add/admin-page-package ( b95118 )
by
unknown
26:28 queued 19:26
created

Jetpack_Admin::get_modules()   C

Complexity

Conditions 11
Paths 136

Size

Total Lines 113

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
nc 136
nop 0
dl 0
loc 113
rs 5.6133
c 0
b 0
f 0

How to fix   Long Method    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
3
4
// Build the Jetpack admin menu as a whole
5
use Automattic\Jetpack\AdminPage\Page as AdminPage;
6
7
class Jetpack_Admin {
8
9
	/**
10
	 * @var Jetpack_Admin
11
	 **/
12
	private static $instance = null;
13
14
	/**
15
	 * @var Jetpack
16
	 **/
17
	private $jetpack;
18
19
	static function init() {
20
		if( isset( $_GET['page'] ) && $_GET['page'] === 'jetpack' ) {
21
			add_filter( 'nocache_headers', array( 'Jetpack_Admin', 'add_no_store_header' ), 100 );
22
		}
23
24
		if ( is_null( self::$instance ) ) {
25
			self::$instance = new Jetpack_Admin;
26
		}
27
		return self::$instance;
28
	}
29
30
	static function add_no_store_header( $headers ) {
31
		$headers['Cache-Control'] .= ', no-store';
32
		return $headers;
33
	}
34
35
	private function __construct() {
36
		$this->jetpack = Jetpack::init();
37
38
		jetpack_require_lib( 'admin-pages/class.jetpack-react-page' );
39
		$this->jetpack_react = new Jetpack_React_Page;
0 ignored issues
show
Bug introduced by
The property jetpack_react does not seem to exist. Did you mean jetpack?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
40
41
		jetpack_require_lib( 'admin-pages/class.jetpack-settings-page' );
42
		$this->fallback_page = new Jetpack_Settings_Page;
0 ignored issues
show
Bug introduced by
The property fallback_page does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
43
44
		jetpack_require_lib( 'admin-pages/class-jetpack-about-page' );
45
		$this->jetpack_about = new Jetpack_About_Page;
0 ignored issues
show
Bug introduced by
The property jetpack_about does not seem to exist. Did you mean jetpack?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
46
47
		add_action( 'admin_menu',                    array( $this->jetpack_react, 'add_actions' ), 998 );
0 ignored issues
show
Bug introduced by
The property jetpack_react does not seem to exist. Did you mean jetpack?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
48
		add_action( 'jetpack_admin_menu',            array( $this->jetpack_react, 'jetpack_add_dashboard_sub_nav_item' ) );
0 ignored issues
show
Bug introduced by
The property jetpack_react does not seem to exist. Did you mean jetpack?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
49
		add_action( 'jetpack_admin_menu',            array( $this->jetpack_react, 'jetpack_add_settings_sub_nav_item' ) );
0 ignored issues
show
Bug introduced by
The property jetpack_react does not seem to exist. Did you mean jetpack?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
50
		add_action( 'jetpack_admin_menu',            array( $this, 'admin_menu_debugger' ) );
51
		add_action( 'jetpack_admin_menu',            array( $this->fallback_page, 'add_actions' ) );
52
		add_action( 'jetpack_admin_menu',            array( $this->jetpack_about, 'add_actions' ) );
0 ignored issues
show
Bug introduced by
The property jetpack_about does not seem to exist. Did you mean jetpack?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
53
54
		// Add redirect to current page for activation/deactivation of modules
55
		add_action( 'jetpack_pre_activate_module',   array( $this, 'fix_redirect' ), 10, 2 );
56
		add_action( 'jetpack_pre_deactivate_module', array( $this, 'fix_redirect' ) );
57
58
		// Add module bulk actions handler
59
		add_action( 'jetpack_unrecognized_action',   array( $this, 'handle_unrecognized_action' ) );
60
	}
61
62 View Code Duplication
	static function sort_requires_connection_last( $module1, $module2 ) {
63
		if ( $module1['requires_connection'] == $module2['requires_connection'] ) {
64
			return 0;
65
		} elseif ( $module1['requires_connection'] ) {
66
			return 1;
67
		} elseif ( $module2['requires_connection'] ) {
68
			return -1;
69
		}
70
71
		return 0;
72
	}
73
74
	// Produce JS understandable objects of modules containing information for
75
	// presentation like description, name, configuration url, etc.
76
	function get_modules() {
77
		include_once( JETPACK__PLUGIN_DIR . 'modules/module-info.php' );
78
		$available_modules = Jetpack::get_available_modules();
79
		$active_modules    = Jetpack::get_active_modules();
80
		$modules           = array();
81
		$jetpack_active = Jetpack::is_active() || Jetpack::is_development_mode();
82
		$overrides = Jetpack_Modules_Overrides::instance();
83
		foreach ( $available_modules as $module ) {
84
			if ( $module_array = Jetpack::get_module( $module ) ) {
85
				/**
86
				 * Filters each module's short description.
87
				 *
88
				 * @since 3.0.0
89
				 *
90
				 * @param string $module_array['description'] Module description.
91
				 * @param string $module Module slug.
92
				 */
93
				$short_desc = apply_filters( 'jetpack_short_module_description', $module_array['description'], $module );
94
				// Fix: correct multibyte strings truncate with checking for mbstring extension
95
				$short_desc_trunc = ( function_exists( 'mb_strlen' ) )
96
							? ( ( mb_strlen( $short_desc ) > 143 )
97
								? mb_substr( $short_desc, 0, 140 ) . '...'
98
								: $short_desc )
99
							: ( ( strlen( $short_desc ) > 143 )
100
								? substr( $short_desc, 0, 140 ) . '...'
101
								: $short_desc );
102
103
				$module_array['module']            = $module;
104
				$module_array['activated']         = ( $jetpack_active ? in_array( $module, $active_modules ) : false );
105
				$module_array['deactivate_nonce']  = wp_create_nonce( 'jetpack_deactivate-' . $module );
106
				$module_array['activate_nonce']    = wp_create_nonce( 'jetpack_activate-' . $module );
107
				$module_array['available']         = self::is_module_available( $module_array );
108
				$module_array['short_description'] = $short_desc_trunc;
109
				$module_array['configure_url']     = Jetpack::module_configuration_url( $module );
110
				$module_array['override']          = $overrides->get_module_override( $module );
111
112
				ob_start();
113
				/**
114
				 * Allow the display of a "Learn More" button.
115
				 * The dynamic part of the action, $module, is the module slug.
116
				 *
117
				 * @since 3.0.0
118
				 */
119
				do_action( 'jetpack_learn_more_button_' . $module );
120
				$module_array['learn_more_button'] = ob_get_clean();
121
122
				ob_start();
123
				/**
124
				 * Allow the display of information text when Jetpack is connected to WordPress.com.
125
				 * The dynamic part of the action, $module, is the module slug.
126
				 *
127
				 * @since 3.0.0
128
				 */
129
				do_action( 'jetpack_module_more_info_' . $module );
130
131
				/**
132
				* Filter the long description of a module.
133
	 			*
134
	 			* @since 3.5.0
135
	 			*
136
	 			* @param string ob_get_clean() The module long description.
137
				* @param string $module The module name.
138
	 			*/
139
				$module_array['long_description'] = apply_filters( 'jetpack_long_module_description', ob_get_clean(), $module );
140
141
				ob_start();
142
				/**
143
				 * Filter the search terms for a module
144
				 *
145
				 * Search terms are typically added to the module headers, under "Additional Search Queries".
146
				 *
147
				 * Use syntax:
148
				 * function jetpack_$module_search_terms( $terms ) {
149
				 *  $terms = _x( 'term 1, term 2', 'search terms', 'jetpack' );
150
				 *  return $terms;
151
				 * }
152
				 * add_filter( 'jetpack_search_terms_$module', 'jetpack_$module_search_terms' );
153
				 *
154
				 * @since 3.5.0
155
				 *
156
				 * @param string The search terms (comma separated).
157
				 */
158
				echo apply_filters( 'jetpack_search_terms_' . $module, $module_array['additional_search_queries'] );
159
				$module_array['search_terms'] = ob_get_clean();
160
161
				$module_array['configurable'] = false;
162
				if (
163
					current_user_can( 'manage_options' ) &&
164
					/**
165
					 * Allow the display of a configuration link in the Jetpack Settings screen.
166
					 *
167
					 * @since 3.0.0
168
					 *
169
					 * @param string $module Module name.
170
					 * @param bool false Should the Configure module link be displayed? Default to false.
171
					 */
172
					apply_filters( 'jetpack_module_configurable_' . $module, false )
173
				) {
174
					$module_array['configurable'] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $module_array['configure_url'] ), __( 'Configure', 'jetpack' ) );
175
				}
176
177
				$modules[ $module ] = $module_array;
178
			}
179
		}
180
181
		uasort( $modules, array( $this->jetpack, 'sort_modules' ) );
182
183
		if ( ! Jetpack::is_active() ) {
184
			uasort( $modules, array( __CLASS__, 'sort_requires_connection_last' ) );
185
		}
186
187
		return $modules;
188
	}
189
190
	static function is_module_available( $module ) {
191
		if ( ! is_array( $module ) || empty( $module ) )
192
			return false;
193
194
		/**
195
		 * We never want to show VaultPress as activatable through Jetpack.
196
		 */
197
		if ( 'vaultpress' === $module['module'] ) {
198
			return false;
199
		}
200
201
		if ( Jetpack::is_development_mode() ) {
202
			return ! ( $module['requires_connection'] );
203
		} else {
204
			if ( ! Jetpack::is_active() ) {
205
				return false;
206
			}
207
208
			return Jetpack_Plan::supports( $module['module'] );
209
		}
210
	}
211
212
	function handle_unrecognized_action( $action ) {
213
		switch( $action ) {
214
			case 'bulk-activate' :
215
				if ( ! current_user_can( 'jetpack_activate_modules' ) ) {
216
					break;
217
				}
218
219
				$modules = (array) $_GET['modules'];
220
				$modules = array_map( 'sanitize_key', $modules );
221
				check_admin_referer( 'bulk-jetpack_page_jetpack_modules' );
222
				foreach( $modules as $module ) {
223
					Jetpack::log( 'activate', $module );
224
					Jetpack::activate_module( $module, false );
225
				}
226
				// The following two lines will rarely happen, as Jetpack::activate_module normally exits at the end.
227
				wp_safe_redirect( wp_get_referer() );
228
				exit;
229 View Code Duplication
			case 'bulk-deactivate' :
230
				if ( ! current_user_can( 'jetpack_deactivate_modules' ) ) {
231
					break;
232
				}
233
234
				$modules = (array) $_GET['modules'];
235
				$modules = array_map( 'sanitize_key', $modules );
236
				check_admin_referer( 'bulk-jetpack_page_jetpack_modules' );
237
				foreach ( $modules as $module ) {
238
					Jetpack::log( 'deactivate', $module );
239
					Jetpack::deactivate_module( $module );
240
					Jetpack::state( 'message', 'module_deactivated' );
241
				}
242
				Jetpack::state( 'module', $modules );
0 ignored issues
show
Documentation introduced by
$modules is of type array, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
243
				wp_safe_redirect( wp_get_referer() );
244
				exit;
245
			default:
246
				return;
247
		}
248
	}
249
250
	function fix_redirect( $module, $redirect = true ) {
251
		if ( ! $redirect ) {
252
			return;
253
		}
254
		if ( wp_get_referer() ) {
255
			add_filter( 'wp_redirect', 'wp_get_referer' );
256
		}
257
	}
258
259
	function admin_menu_debugger() {
260
		jetpack_require_lib( 'debugger' );
261
		Jetpack_Debugger::disconnect_and_redirect();
262
		$debugger_hook = add_submenu_page(
263
			null,
264
			__( 'Debugging Center', 'jetpack' ),
265
			'',
266
			'manage_options',
267
			'jetpack-debugger',
268
			array( $this, 'wrap_debugger_page' )
269
		);
270
		add_action( "admin_head-$debugger_hook", array( 'Jetpack_Debugger', 'jetpack_debug_admin_head' ) );
271
		$this->admin_page = new AdminPage( $debugger_hook );
0 ignored issues
show
Bug introduced by
The property admin_page does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
272
	}
273
274
	function wrap_debugger_page( ) {
275
		nocache_headers();
276
		if ( ! current_user_can( 'manage_options' ) ) {
277
			die( '-1' );
278
		}
279
		echo $this->admin_page->render( array( $this, 'debugger_page' ) );
280
	}
281
282
	function debugger_page() {
283
		jetpack_require_lib( 'debugger' );
284
		Jetpack_Debugger::jetpack_debug_display_handler();
285
	}
286
}
287
Jetpack_Admin::init();
288