Completed
Push — fix/fallback-if-rest-api-disab... ( 3c6c28...2d3652 )
by
unknown
350:00 queued 342:52
created

check_plan_deactivate_modules()   C

Complexity

Conditions 16
Paths 16

Size

Total Lines 65
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 47
nc 16
nop 1
dl 0
loc 65
rs 5.9197
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
// Shared logic between Jetpack admin pages
4
abstract class Jetpack_Admin_Page {
5
	// Add page specific actions given the page hook
6
	abstract function add_page_actions( $hook );
7
8
	// Create a menu item for the page and returns the hook
9
	abstract function get_page_hook();
10
11
	// Enqueue and localize page specific scripts
12
	abstract function page_admin_scripts();
13
14
	// Render page specific HTML
15
	abstract function page_render();
16
17
	/**
18
	 * Should we block the page rendering because the site is in IDC?
19
	 * @var bool
20
	 */
21
	static $block_page_rendering_for_idc;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $block_page_rendering_for_idc.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
22
23
	/**
24
	 * Flag to know if we already checked the plan.
25
	 *
26
	 * @since 4.4.0
27
	 *
28
	 * @var bool
29
	 */
30
	static $plan_checked = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $plan_checked.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
31
32
	/**
33
	 * Function called after admin_styles to load any additional needed styles.
34
	 *
35
	 * @since 4.3.0
36
	 */
37
	function additional_styles() {}
38
39
	function __construct() {
40
		$this->jetpack = Jetpack::init();
0 ignored issues
show
Bug introduced by
The property jetpack 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
		self::$block_page_rendering_for_idc = (
42
			Jetpack::validate_sync_error_idc_option() && ! Jetpack_Options::get_option( 'safe_mode_confirmed' )
43
		);
44
45
		if ( ! self::$block_page_rendering_for_idc ) {
46
			add_action( 'admin_enqueue_scripts', array( $this, 'additional_styles' ) );
47
		}
48
	}
49
50
	function add_actions() {
51
52
		// If user is not an admin and site is in Dev Mode, don't do anything
53
		if ( ! current_user_can( 'manage_options' ) && Jetpack::is_development_mode() ) {
54
			return;
55
		}
56
57
		// Don't add in the modules page unless modules are available!
58
		if ( $this->dont_show_if_not_active && ! Jetpack::is_active() && ! Jetpack::is_development_mode() ) {
0 ignored issues
show
Bug introduced by
The property dont_show_if_not_active 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...
59
			return;
60
		}
61
62
		// Initialize menu item for the page in the admin
63
		$hook = $this->get_page_hook();
64
65
		// Attach hooks common to all Jetpack admin pages based on the created
66
		// hook
67
		add_action( "load-$hook",                array( $this, 'admin_help'      ) );
68
		add_action( "load-$hook",                array( $this, 'admin_page_load' ) );
69
		add_action( "admin_head-$hook",          array( $this, 'admin_head'      ) );
70
71
		add_action( "admin_print_styles-$hook",  array( $this, 'admin_styles'    ) );
72
		add_action( "admin_print_scripts-$hook", array( $this, 'admin_scripts'   ) );
73
74
		// Check if the site plan changed and deactivate modules accordingly.
75
		add_action( 'current_screen', array( $this, 'check_plan_deactivate_modules' ) );
76
77
		// Attach page specific actions in addition to the above
78
		$this->add_page_actions( $hook );
79
	}
80
81
	function admin_head() {
82 View Code Duplication
		if ( isset( $_GET['configure'] ) && Jetpack::is_module( $_GET['configure'] ) && current_user_can( 'manage_options' ) ) {
83
			/**
84
			 * Fires in the <head> of a particular Jetpack configuation page.
85
			 *
86
			 * The dynamic portion of the hook name, `$_GET['configure']`,
87
			 * refers to the slug of module, such as 'stats', 'sso', etc.
88
			 * A complete hook for the latter would be
89
			 * 'jetpack_module_configuation_head_sso'.
90
			 *
91
			 * @since 3.0.0
92
			 */
93
			do_action( 'jetpack_module_configuration_head_' . $_GET['configure'] );
94
		}
95
	}
96
97
	// Render the page with a common top and bottom part, and page specific content
98
	function render() {
99
		// We're in an IDC: we need a decision made before we show the UI again.
100
		if ( self::$block_page_rendering_for_idc ) {
101
			return;
102
		}
103
104
		$this->page_render();
105
	}
106
107
	function admin_help() {
108
		$this->jetpack->admin_help();
109
	}
110
111
	function admin_page_load() {
112
		// This is big.  For the moment, just call the existing one.
113
		$this->jetpack->admin_page_load();
114
	}
115
116
	function admin_page_top() {
117
		include_once( JETPACK__PLUGIN_DIR . '_inc/header.php' );
118
	}
119
120
	function admin_page_bottom() {
121
		include_once( JETPACK__PLUGIN_DIR . '_inc/footer.php' );
122
	}
123
124
	// Add page specific scripts and jetpack stats for all menu pages
125
	function admin_scripts() {
126
		$this->page_admin_scripts(); // Delegate to inheriting class
127
		add_action( 'admin_footer', array( $this->jetpack, 'do_stats' ) );
128
	}
129
130
	// Enqueue the Jetpack admin stylesheet
131
	function admin_styles() {
132
		$min = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
133
134
		wp_enqueue_style( 'jetpack-admin', plugins_url( "css/jetpack-admin{$min}.css", JETPACK__PLUGIN_FILE ), array( 'genericons' ), JETPACK__VERSION . '-20121016' );
135
		wp_style_add_data( 'jetpack-admin', 'rtl', 'replace' );
136
		wp_style_add_data( 'jetpack-admin', 'suffix', $min );
137
	}
138
139
	/**
140
	 * Checks if WordPress version is too old to have REST API.
141
	 *
142
	 * @since 4.3
143
	 *
144
	 * @return bool
145
	 */
146
	function is_wp_version_too_old() {
147
		global $wp_version;
148
		return ( ! function_exists( 'rest_api_init' ) || version_compare( $wp_version, '4.4-z', '<=' ) );
149
	}
150
151
	/**
152
	 * Checks if REST API is enabled.
153
	 *
154
	 * @since 4.4.2
155
	 *
156
	 * @return bool
157
	 */
158
	function is_rest_api_enabled() {
159
		return
160
			/** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */
161
			apply_filters( 'rest_enabled', true ) &&
162
			/** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */
163
			apply_filters( 'rest_jsonp_enabled', true ) &&
164
			/** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */
165
			apply_filters( 'rest_authentication_errors', true );
166
	}
167
168
	/**
169
	 * Checks the site plan and deactivates modules that were active but are no longer included in the plan.
170
	 *
171
	 * @since 4.4.0
172
	 *
173
	 * @param $page
174
	 *
175
	 * @return bool|array
176
	 */
177
	function check_plan_deactivate_modules( $page ) {
178
		if (
179
			Jetpack::is_development_mode()
180
			|| ! in_array(
181
				$page->base,
182
				array(
183
					'toplevel_page_jetpack',
184
					'admin_page_jetpack_modules',
185
					'jetpack_page_vaultpress',
186
					'jetpack_page_stats',
187
					'jetpack_page_akismet-key-config'
188
				)
189
			)
190
			|| true === self::$plan_checked
191
		) {
192
			return false;
193
		}
194
195
		self::$plan_checked = true;
196
		$previous = get_option( 'jetpack_active_plan', '' );
197
		$response = rest_do_request( new WP_REST_Request( 'GET', '/jetpack/v4/site' ) );
198
199
		if ( ! is_object( $response ) || $response->is_error() ) {
200
201
			// If we can't get information about the current plan we don't do anything
202
			self::$plan_checked = true;
203
			return;
204
		}
205
206
		$current = $response->get_data();
207
		$current = json_decode( $current['data'] );
208
209
		$to_deactivate = array();
210
		if ( isset( $current->plan->product_slug ) ) {
211
			if (
212
				empty( $previous )
213
				|| ! isset( $previous['product_slug'] )
214
				|| $previous['product_slug'] !== $current->plan->product_slug
215
			) {
216
				$active = Jetpack::get_active_modules();
217
				switch ( $current->plan->product_slug ) {
218
					case 'jetpack_free':
219
						$to_deactivate = array( 'seo-tools', 'videopress' );
220
						break;
221
					case 'jetpack_personal':
222
					case 'jetpack_personal_monthly':
223
						$to_deactivate = array( 'seo-tools', 'videopress' );
224
						break;
225
					case 'jetpack_premium':
226
					case 'jetpack_premium_monthly':
227
						$to_deactivate = array( 'seo-tools' );
228
						break;
229
				}
230
				$to_deactivate = array_intersect( $active, $to_deactivate );
231
				if ( ! empty( $to_deactivate ) ) {
232
					Jetpack::update_active_modules( array_filter( array_diff( $active, $to_deactivate ) ) );
233
				}
234
			}
235
		}
236
		return array(
237
			'previous'   => $previous,
238
			'current'    => $current,
239
			'deactivate' => $to_deactivate
240
		);
241
	}
242
}
243