Completed
Push — update/user-tos-package ( 9c7777...4fee76 )
by
unknown
06:31
created

class.jetpack-admin.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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();
38
39
		jetpack_require_lib( 'admin-pages/class.jetpack-settings-page' );
40
		$this->fallback_page = new Jetpack_Settings_Page();
41
42
		jetpack_require_lib( 'admin-pages/class-jetpack-about-page' );
43
		$this->jetpack_about = new Jetpack_About_Page();
44
45
		add_action( 'admin_menu', array( $this->jetpack_react, 'add_actions' ), 998 );
46
		add_action( 'jetpack_admin_menu', array( $this->jetpack_react, 'jetpack_add_dashboard_sub_nav_item' ) );
47
		add_action( 'jetpack_admin_menu', array( $this->jetpack_react, 'jetpack_add_settings_sub_nav_item' ) );
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' ) );
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
$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