Completed
Push — use-asset-tools-package-everyw... ( c90c8b...56f281 )
by
unknown
25:14 queued 17:28
created

class.jetpack-admin.php (1 issue)

Labels
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;
0 ignored issues
show
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;
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
		 * We never want to show VaultPress as activatable through Jetpack.
194
		 */
195
		if ( 'vaultpress' === $module['module'] ) {
196
			return false;
197
		}
198
199
		if ( Jetpack::is_development_mode() ) {
200
			return ! ( $module['requires_connection'] );
201
		} else {
202
			if ( ! Jetpack::is_active() ) {
203
				return false;
204
			}
205
206
			return Jetpack_Plan::supports( $module['module'] );
207
		}
208
	}
209
210
	function handle_unrecognized_action( $action ) {
211
		switch( $action ) {
212
			case 'bulk-activate' :
213
				if ( ! current_user_can( 'jetpack_activate_modules' ) ) {
214
					break;
215
				}
216
217
				$modules = (array) $_GET['modules'];
218
				$modules = array_map( 'sanitize_key', $modules );
219
				check_admin_referer( 'bulk-jetpack_page_jetpack_modules' );
220
				foreach( $modules as $module ) {
221
					Jetpack::log( 'activate', $module );
222
					Jetpack::activate_module( $module, false );
223
				}
224
				// The following two lines will rarely happen, as Jetpack::activate_module normally exits at the end.
225
				wp_safe_redirect( wp_get_referer() );
226
				exit;
227 View Code Duplication
			case 'bulk-deactivate' :
228
				if ( ! current_user_can( 'jetpack_deactivate_modules' ) ) {
229
					break;
230
				}
231
232
				$modules = (array) $_GET['modules'];
233
				$modules = array_map( 'sanitize_key', $modules );
234
				check_admin_referer( 'bulk-jetpack_page_jetpack_modules' );
235
				foreach ( $modules as $module ) {
236
					Jetpack::log( 'deactivate', $module );
237
					Jetpack::deactivate_module( $module );
238
					Jetpack::state( 'message', 'module_deactivated' );
239
				}
240
				Jetpack::state( 'module', $modules );
241
				wp_safe_redirect( wp_get_referer() );
242
				exit;
243
			default:
244
				return;
245
		}
246
	}
247
248
	function fix_redirect( $module, $redirect = true ) {
249
		if ( ! $redirect ) {
250
			return;
251
		}
252
		if ( wp_get_referer() ) {
253
			add_filter( 'wp_redirect', 'wp_get_referer' );
254
		}
255
	}
256
257
	function admin_menu_debugger() {
258
		jetpack_require_lib( 'debugger' );
259
		Jetpack_Debugger::disconnect_and_redirect();
260
		$debugger_hook = add_submenu_page(
261
			null,
262
			__( 'Debugging Center', 'jetpack' ),
263
			'',
264
			'manage_options',
265
			'jetpack-debugger',
266
			array( $this, 'wrap_debugger_page' )
267
		);
268
		add_action( "admin_head-$debugger_hook", array( 'Jetpack_Debugger', 'jetpack_debug_admin_head' ) );
269
	}
270
271
	function wrap_debugger_page( ) {
272
		nocache_headers();
273
		if ( ! current_user_can( 'manage_options' ) ) {
274
			die( '-1' );
275
		}
276
		Jetpack_Admin_Page::wrap_ui( array( $this, 'debugger_page' ) );
277
	}
278
279
	function debugger_page() {
280
		jetpack_require_lib( 'debugger' );
281
		Jetpack_Debugger::jetpack_debug_display_handler();
282
	}
283
}
284
Jetpack_Admin::init();
285