Completed
Push — core/custom-css-4.7 ( 7f4836...adaf63 )
by
unknown
09:28
created

Jetpack_JSON_API_Plugins_Modify_Endpoint   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 189
Duplicated Lines 16.4 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 31
loc 189
rs 8.3157
wmc 43
lcom 2
cbo 4

7 Methods

Rating   Name   Duplication   Size   Complexity  
A callback() 0 16 4
B default_action() 0 21 7
A autoupdate_on() 0 5 1
A autoupdate_off() 0 5 1
C activate() 20 39 14
C deactivate() 8 24 8
C update() 3 64 8

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Jetpack_JSON_API_Plugins_Modify_Endpoint often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Jetpack_JSON_API_Plugins_Modify_Endpoint, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
class Jetpack_JSON_API_Plugins_Modify_Endpoint extends Jetpack_JSON_API_Plugins_Endpoint {
4
	// POST  /sites/%s/plugins/%s
5
	// POST  /sites/%s/plugins
6
7
	protected $needed_capabilities = 'activate_plugins';
8
	protected $action              = 'default_action';
9
	protected $expected_actions    = array( 'update', 'install', 'delete' );
10
11
	public function callback( $path = '', $blog_id = 0, $object = null ) {
12
		Jetpack_JSON_API_Endpoint::validate_input( $object );
13
		switch ( $this->action ) {
14
			case 'update' :
15
				$this->needed_capabilities = 'update_plugins';
16
				break;
17
			case 'install' :
18
				$this->needed_capabilities = 'install_plugins';
19
				break;
20
		}
21
		if ( isset( $args['autoupdate'] ) ) {
0 ignored issues
show
Bug introduced by
The variable $args seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
22
			$this->needed_capabilities = 'update_plugins';
23
		}
24
25
		return parent::callback( $path, $blog_id, $object );
26
	}
27
28
	public function default_action() {
29
		$args = $this->input();
30
31
		if ( isset( $args['autoupdate'] ) && is_bool( $args['autoupdate'] ) ) {
32
			if ( $args['autoupdate'] ) {
33
				$this->autoupdate_on();
34
			} else {
35
				$this->autoupdate_off();
36
			}
37
		}
38
39
		if ( isset( $args['active'] ) && is_bool( $args['active'] ) ) {
40
			if ( $args['active'] ) {
41
				return $this->activate();
42
			} else {
43
				return $this->deactivate();
44
			}
45
		}
46
47
		return true;
48
	}
49
50
	protected function autoupdate_on() {
51
		$autoupdate_plugins = Jetpack_Options::get_option( 'autoupdate_plugins', array() );
52
		$autoupdate_plugins = array_unique( array_merge( $autoupdate_plugins, $this->plugins ) );
53
		Jetpack_Options::update_option( 'autoupdate_plugins', $autoupdate_plugins );
54
	}
55
56
	protected function autoupdate_off() {
57
		$autoupdate_plugins = Jetpack_Options::get_option( 'autoupdate_plugins', array() );
58
		$autoupdate_plugins = array_diff( $autoupdate_plugins, $this->plugins );
59
		Jetpack_Options::update_option( 'autoupdate_plugins', $autoupdate_plugins );
60
	}
61
62
	protected function activate() {
63
		foreach ( $this->plugins as $plugin ) {
64 View Code Duplication
			if ( ( ! $this->network_wide && Jetpack::is_plugin_active( $plugin ) ) || is_plugin_active_for_network( $plugin ) ) {
65
				$this->log[ $plugin ]['error'] = __( 'The Plugin is already active.', 'jetpack' );
66
				$has_errors = true;
67
				continue;
68
			}
69
70 View Code Duplication
			if ( ! $this->network_wide && is_network_only_plugin( $plugin ) && is_multisite() ) {
71
				$this->log[ $plugin ]['error'] = __( 'Plugin can only be Network Activated', 'jetpack' );
72
				$has_errors = true;
73
				continue;
74
			}
75
76
			$result = activate_plugin( $plugin, '', $this->network_wide );
77
78 View Code Duplication
			if ( is_wp_error( $result ) ) {
79
				$this->log[ $plugin ]['error'] = $result->get_error_messages();
80
				$has_errors = true;
81
				continue;
82
			}
83
84
			$success = Jetpack::is_plugin_active( $plugin );
85
			if ( $success && $this->network_wide ) {
86
				$success &= is_plugin_active_for_network( $plugin );
87
			}
88
89 View Code Duplication
			if ( ! $success ) {
90
				$this->log[ $plugin ]['error'] = $result->get_error_messages;
91
				$has_errors = true;
92
				continue;
93
			}
94
			$this->log[ $plugin ][] = __( 'Plugin activated.', 'jetpack' );
95
		}
96
		if ( ! $this->bulk && isset( $has_errors ) ) {
97
			$plugin = $this->plugins[0];
98
			return new WP_Error( 'activation_error', $this->log[ $plugin ]['error'] );
99
		}
100
	}
101
102
	protected function deactivate() {
103
		foreach ( $this->plugins as $plugin ) {
104 View Code Duplication
			if ( ! Jetpack::is_plugin_active( $plugin ) ) {
105
				$error = $this->log[ $plugin ]['error'] = __( 'The Plugin is already deactivated.', 'jetpack' );
106
				continue;
107
			}
108
109
			deactivate_plugins( $plugin, false, $this->network_wide );
110
111
			$success = ! Jetpack::is_plugin_active( $plugin );
112
			if ( $success && $this->network_wide ) {
113
				$success &= ! is_plugin_active_for_network( $plugin );
114
			}
115
116 View Code Duplication
			if ( ! $success ) {
117
				$error = $this->log[ $plugin ]['error'] = __( 'There was an error deactivating your plugin', 'jetpack' );
118
				continue;
119
			}
120
			$this->log[ $plugin ][] = __( 'Plugin deactivated.', 'jetpack' );
121
		}
122
		if ( ! $this->bulk && isset( $error ) ) {
123
			return new WP_Error( 'deactivation_error', $error );
124
		}
125
	}
126
127
	protected function update() {
128
129
		wp_clean_plugins_cache();
130
		ob_start();
131
		wp_update_plugins(); // Check for Plugin updates
132
		ob_end_clean();
133
134
		$update_plugins = get_site_transient( 'update_plugins' );
135
136
		if ( isset( $update_plugins->response ) ) {
137
			$plugin_updates_needed = array_keys( $update_plugins->response );
138
		} else {
139
			$plugin_updates_needed = array();
140
		}
141
142
		$update_attempted = false;
143
144
		include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
145
146
		// unhook this functions that output things before we send our response header.
147
		remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
148
		remove_action( 'upgrader_process_complete', 'wp_version_check' );
149
		remove_action( 'upgrader_process_complete', 'wp_update_themes' );
150
151
		$result = false;
152
153
		foreach ( $this->plugins as $plugin ) {
154
155
			if ( ! in_array( $plugin, $plugin_updates_needed ) ) {
156
				$this->log[ $plugin ][] = __( 'No update needed', 'jetpack' );
157
				continue;
158
			}
159
160
			/**
161
			 * Pre-upgrade action
162
			 * 
163
			 * @since 3.9.3
164
			 * 
165
			 * @param array $plugin Plugin data
166
			 * @param array $plugin Array of plugin objects
167
			 * @param bool $updated_attempted false for the first update, true subsequently
168
			 */
169
			do_action('jetpack_pre_plugin_upgrade', $plugin, $this->plugins, $update_attempted);
170
171
			$update_attempted = true;
172
173
			// Object created inside the for loop to clean the messages for each plugin
174
			$skin = new Automatic_Upgrader_Skin();
175
			// The Automatic_Upgrader_Skin skin shouldn't output anything.
176
			$upgrader = new Plugin_Upgrader( $skin );
177
			$upgrader->init();
178
			// This avoids the plugin to be deactivated.
179
			defined( 'DOING_CRON' ) or define( 'DOING_CRON', true );
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
180
			$result = $upgrader->upgrade( $plugin );
181
182
			$this->log[ $plugin ][] = $upgrader->skin->get_upgrade_messages();
183
		}
184
185 View Code Duplication
		if ( ! $this->bulk && ! $result && $update_attempted ) {
186
			return new WP_Error( 'update_fail', __( 'There was an error updating your plugin', 'jetpack' ), 400 );
187
		}
188
189
		return $this->default_action();
190
	}
191
}
192