Completed
Push — update/user-tos-package ( 4fee76...3b2612 )
by
unknown
23:24 queued 16:11
created

Jetpack_Admin::init()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 0
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
4
// Build the Jetpack admin menu as a whole
5
class Jetpack_Admin {
6
7
	/**
8
	 * @var Jetpack_Admin
9
	 **/
10
	private static $instance = null;
11
12
	/**
13
	 * @var Jetpack
14
	 **/
15
	private $jetpack;
16
17
	static function init() {
18
		if ( isset( $_GET['page'] ) && $_GET['page'] === 'jetpack' ) {
19
			add_filter( 'nocache_headers', array( 'Jetpack_Admin', 'add_no_store_header' ), 100 );
20
		}
21
22
		if ( is_null( self::$instance ) ) {
23
			self::$instance = new Jetpack_Admin();
24
		}
25
		return self::$instance;
26
	}
27
28
	static function add_no_store_header( $headers ) {
29
		$headers['Cache-Control'] .= ', no-store';
30
		return $headers;
31
	}
32
33
	private function __construct() {
34
		$this->jetpack = Jetpack::init();
35
36
		jetpack_require_lib( 'admin-pages/class.jetpack-react-page' );
37
		$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...
38
39
		jetpack_require_lib( 'admin-pages/class.jetpack-settings-page' );
40
		$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...
41
42
		jetpack_require_lib( 'admin-pages/class-jetpack-about-page' );
43
		$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...
44
45
		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...
46
		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...
47
		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...
48
		add_action( 'jetpack_admin_menu', array( $this, 'admin_menu_debugger' ) );
49
		add_action( 'jetpack_admin_menu', array( $this->fallback_page, 'add_actions' ) );
50
		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...
51
52
		// Add redirect to current page for activation/deactivation of modules
53
		add_action( 'jetpack_pre_activate_module', array( $this, 'fix_redirect' ), 10, 2 );
54
		add_action( 'jetpack_pre_deactivate_module', array( $this, 'fix_redirect' ) );
55
56
		// Add module bulk actions handler
57
		add_action( 'jetpack_unrecognized_action', array( $this, 'handle_unrecognized_action' ) );
58
	}
59
60 View Code Duplication
	static function sort_requires_connection_last( $module1, $module2 ) {
61
		if ( $module1['requires_connection'] == $module2['requires_connection'] ) {
62
			return 0;
63
		} elseif ( $module1['requires_connection'] ) {
64
			return 1;
65
		} elseif ( $module2['requires_connection'] ) {
66
			return -1;
67
		}
68
69
		return 0;
70
	}
71
72
	// Produce JS understandable objects of modules containing information for
73
	// presentation like description, name, configuration url, etc.
74
	function get_modules() {
75
		include_once JETPACK__PLUGIN_DIR . 'modules/module-info.php';
76
		$available_modules = Jetpack::get_available_modules();
77
		$active_modules    = Jetpack::get_active_modules();
78
		$modules           = array();
79
		$jetpack_active    = Jetpack::is_active() || Jetpack::is_development_mode();
80
		$overrides         = Jetpack_Modules_Overrides::instance();
81
		foreach ( $available_modules as $module ) {
82
			if ( $module_array = Jetpack::get_module( $module ) ) {
83
				/**
84
				 * Filters each module's short description.
85
				 *
86
				 * @since 3.0.0
87
				 *
88
				 * @param string $module_array['description'] Module description.
89
				 * @param string $module Module slug.
90
				 */
91
				$short_desc = apply_filters( 'jetpack_short_module_description', $module_array['description'], $module );
92
				// Fix: correct multibyte strings truncate with checking for mbstring extension
93
				$short_desc_trunc = ( function_exists( 'mb_strlen' ) )
94
							? ( ( mb_strlen( $short_desc ) > 143 )
95
								? mb_substr( $short_desc, 0, 140 ) . '...'
96
								: $short_desc )
97
							: ( ( strlen( $short_desc ) > 143 )
98
								? substr( $short_desc, 0, 140 ) . '...'
99
								: $short_desc );
100
101
				$module_array['module']            = $module;
102
				$module_array['activated']         = ( $jetpack_active ? in_array( $module, $active_modules ) : false );
103
				$module_array['deactivate_nonce']  = wp_create_nonce( 'jetpack_deactivate-' . $module );
104
				$module_array['activate_nonce']    = wp_create_nonce( 'jetpack_activate-' . $module );
105
				$module_array['available']         = self::is_module_available( $module_array );
106
				$module_array['short_description'] = $short_desc_trunc;
107
				$module_array['configure_url']     = Jetpack::module_configuration_url( $module );
108
				$module_array['override']          = $overrides->get_module_override( $module );
109
110
				ob_start();
111
				/**
112
				 * Allow the display of a "Learn More" button.
113
				 * The dynamic part of the action, $module, is the module slug.
114
				 *
115
				 * @since 3.0.0
116
				 */
117
				do_action( 'jetpack_learn_more_button_' . $module );
118
				$module_array['learn_more_button'] = ob_get_clean();
119
120
				ob_start();
121
				/**
122
				 * Allow the display of information text when Jetpack is connected to WordPress.com.
123
				 * The dynamic part of the action, $module, is the module slug.
124
				 *
125
				 * @since 3.0.0
126
				 */
127
				do_action( 'jetpack_module_more_info_' . $module );
128
129
				/**
130
				* Filter the long description of a module.
131
				*
132
				* @since 3.5.0
133
				*
134
				* @param string ob_get_clean() The module long description.
135
				* @param string $module The module name.
136
				*/
137
				$module_array['long_description'] = apply_filters( 'jetpack_long_module_description', ob_get_clean(), $module );
138
139
				ob_start();
140
				/**
141
				 * Filter the search terms for a module
142
				 *
143
				 * Search terms are typically added to the module headers, under "Additional Search Queries".
144
				 *
145
				 * Use syntax:
146
				 * function jetpack_$module_search_terms( $terms ) {
147
				 *  $terms = _x( 'term 1, term 2', 'search terms', 'jetpack' );
148
				 *  return $terms;
149
				 * }
150
				 * add_filter( 'jetpack_search_terms_$module', 'jetpack_$module_search_terms' );
151
				 *
152
				 * @since 3.5.0
153
				 *
154
				 * @param string The search terms (comma separated).
155
				 */
156
				echo apply_filters( 'jetpack_search_terms_' . $module, $module_array['additional_search_queries'] );
157
				$module_array['search_terms'] = ob_get_clean();
158
159
				$module_array['configurable'] = false;
160
				if (
161
					current_user_can( 'manage_options' ) &&
162
					/**
163
					 * Allow the display of a configuration link in the Jetpack Settings screen.
164
					 *
165
					 * @since 3.0.0
166
					 *
167
					 * @param string $module Module name.
168
					 * @param bool false Should the Configure module link be displayed? Default to false.
169
					 */
170
					apply_filters( 'jetpack_module_configurable_' . $module, false )
171
				) {
172
					$module_array['configurable'] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $module_array['configure_url'] ), __( 'Configure', 'jetpack' ) );
173
				}
174
175
				$modules[ $module ] = $module_array;
176
			}
177
		}
178
179
		uasort( $modules, array( $this->jetpack, 'sort_modules' ) );
180
181
		if ( ! Jetpack::is_active() ) {
182
			uasort( $modules, array( __CLASS__, 'sort_requires_connection_last' ) );
183
		}
184
185
		return $modules;
186
	}
187
188
	static function is_module_available( $module ) {
189
		if ( ! is_array( $module ) || empty( $module ) ) {
190
			return false;
191
		}
192
193
		/**
194
		 * We never want to show VaultPress as activatable through Jetpack.
195
		 */
196
		if ( 'vaultpress' === $module['module'] ) {
197
			return false;
198
		}
199
200
		if ( Jetpack::is_development_mode() ) {
201
			return ! ( $module['requires_connection'] );
202
		} else {
203
			if ( ! Jetpack::is_active() ) {
204
				return false;
205
			}
206
207
			return Jetpack_Plan::supports( $module['module'] );
208
		}
209
	}
210
211
	function handle_unrecognized_action( $action ) {
212
		switch ( $action ) {
213
			case 'bulk-activate':
214
				if ( ! current_user_can( 'jetpack_activate_modules' ) ) {
215
					break;
216
				}
217
218
				$modules = (array) $_GET['modules'];
219
				$modules = array_map( 'sanitize_key', $modules );
220
				check_admin_referer( 'bulk-jetpack_page_jetpack_modules' );
221
				foreach ( $modules as $module ) {
222
					Jetpack::log( 'activate', $module );
223
					Jetpack::activate_module( $module, false );
224
				}
225
				// The following two lines will rarely happen, as Jetpack::activate_module normally exits at the end.
226
				wp_safe_redirect( wp_get_referer() );
227
				exit;
228 View Code Duplication
			case 'bulk-deactivate':
229
				if ( ! current_user_can( 'jetpack_deactivate_modules' ) ) {
230
					break;
231
				}
232
233
				$modules = (array) $_GET['modules'];
234
				$modules = array_map( 'sanitize_key', $modules );
235
				check_admin_referer( 'bulk-jetpack_page_jetpack_modules' );
236
				foreach ( $modules as $module ) {
237
					Jetpack::log( 'deactivate', $module );
238
					Jetpack::deactivate_module( $module );
239
					Jetpack::state( 'message', 'module_deactivated' );
240
				}
241
				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...
242
				wp_safe_redirect( wp_get_referer() );
243
				exit;
244
			default:
245
				return;
246
		}
247
	}
248
249
	function fix_redirect( $module, $redirect = true ) {
250
		if ( ! $redirect ) {
251
			return;
252
		}
253
		if ( wp_get_referer() ) {
254
			add_filter( 'wp_redirect', 'wp_get_referer' );
255
		}
256
	}
257
258
	function admin_menu_debugger() {
259
		jetpack_require_lib( 'debugger' );
260
		Jetpack_Debugger::disconnect_and_redirect();
261
		$debugger_hook = add_submenu_page(
262
			null,
263
			__( 'Debugging Center', 'jetpack' ),
264
			'',
265
			'manage_options',
266
			'jetpack-debugger',
267
			array( $this, 'wrap_debugger_page' )
268
		);
269
		add_action( "admin_head-$debugger_hook", array( 'Jetpack_Debugger', 'jetpack_debug_admin_head' ) );
270
	}
271
272
	function wrap_debugger_page() {
273
		nocache_headers();
274
		if ( ! current_user_can( 'manage_options' ) ) {
275
			die( '-1' );
276
		}
277
		Jetpack_Admin_Page::wrap_ui( array( $this, 'debugger_page' ) );
278
	}
279
280
	function debugger_page() {
281
		jetpack_require_lib( 'debugger' );
282
		Jetpack_Debugger::jetpack_debug_display_handler();
283
	}
284
}
285
Jetpack_Admin::init();
286