Completed
Push — kraftbj-patch-1 ( 599bd6...9b0476 )
by
unknown
145:59 queued 137:31
created

Jetpack_Sync_Module_Updates   F

Complexity

Total Complexity 64

Size/Duplication

Total Lines 319
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 319
rs 3.28
c 0
b 0
f 0
wmc 64
lcom 2
cbo 2

19 Methods

Rating   Name   Duplication   Size   Complexity  
A set_defaults() 0 3 1
A name() 0 3 1
A init_listeners() 0 44 2
A init_full_sync_listeners() 0 3 1
A init_before_send() 0 4 1
A update_core_network_event() 0 14 1
B update_core() 0 43 5
D get_update_checksum() 0 62 29
B validate_update_change() 0 36 7
A sync_last_event() 0 16 2
A enqueue_full_sync_actions() 0 13 1
A estimate_full_sync_actions() 0 3 1
A get_full_sync_actions() 0 3 1
A get_all_updates() 0 7 1
A filter_update_keys() 0 9 2
A filter_upgrader_process_complete() 0 5 1
A expand_updates() 0 7 2
A expand_themes() 0 14 4
A reset_data() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like Jetpack_Sync_Module_Updates 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_Sync_Module_Updates, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
class Jetpack_Sync_Module_Updates extends Jetpack_Sync_Module {
4
5
	const UPDATES_CHECKSUM_OPTION_NAME = 'jetpack_updates_sync_checksum';
6
7
	private $old_wp_version = null;
8
	private $updates        = array();
9
10
	public function set_defaults() {
11
		$this->updates = array();
12
	}
13
14
	function name() {
15
		return 'updates';
16
	}
17
18
	public function init_listeners( $callable ) {
19
		global $wp_version;
20
		$this->old_wp_version = $wp_version;
21
		add_action( 'set_site_transient_update_plugins', array( $this, 'validate_update_change' ), 10, 3 );
22
		add_action( 'set_site_transient_update_themes', array( $this, 'validate_update_change' ), 10, 3 );
23
		add_action( 'set_site_transient_update_core', array( $this, 'validate_update_change' ), 10, 3 );
24
25
		add_action( 'jetpack_update_plugins_change', $callable );
26
		add_action( 'jetpack_update_themes_change', $callable );
27
		add_action( 'jetpack_update_core_change', $callable );
28
29
		add_filter(
30
			'jetpack_sync_before_enqueue_jetpack_update_plugins_change',
31
			array(
32
				$this,
33
				'filter_update_keys',
34
			),
35
			10,
36
			2
37
		);
38
		add_filter(
39
			'jetpack_sync_before_enqueue_upgrader_process_complete',
40
			array(
41
				$this,
42
				'filter_upgrader_process_complete',
43
			),
44
			10,
45
			2
46
		);
47
48
		add_action( 'automatic_updates_complete', $callable );
49
50
		if ( is_multisite() ) {
51
			add_filter( 'pre_update_site_option_wpmu_upgrade_site', array( $this, 'update_core_network_event' ), 10, 2 );
52
			add_action( 'jetpack_sync_core_update_network', $callable, 10, 3 );
53
		}
54
55
		// Send data when update completes
56
		add_action( '_core_updated_successfully', array( $this, 'update_core' ) );
57
		add_action( 'jetpack_sync_core_reinstalled_successfully', $callable );
58
		add_action( 'jetpack_sync_core_autoupdated_successfully', $callable, 10, 2 );
59
		add_action( 'jetpack_sync_core_updated_successfully', $callable, 10, 2 );
60
61
	}
62
63
	public function init_full_sync_listeners( $callable ) {
64
		add_action( 'jetpack_full_sync_updates', $callable );
65
	}
66
67
	public function init_before_send() {
68
		add_filter( 'jetpack_sync_before_send_jetpack_full_sync_updates', array( $this, 'expand_updates' ) );
69
		add_filter( 'jetpack_sync_before_send_jetpack_update_themes_change', array( $this, 'expand_themes' ) );
70
	}
71
72
	public function update_core_network_event( $wp_db_version, $old_wp_db_version ) {
73
		global $wp_version;
74
		/**
75
		 * Sync event for when core wp network updates to a new db version
76
		 *
77
		 * @since 5.0.0
78
		 *
79
		 * @param int $wp_db_version the latest wp_db_version
80
		 * @param int $old_wp_db_version previous wp_db_version
81
		 * @param string $wp_version the latest wp_version
82
		 */
83
		do_action( 'jetpack_sync_core_update_network', $wp_db_version, $old_wp_db_version, $wp_version );
84
		return $wp_db_version;
85
	}
86
87
	public function update_core( $new_wp_version ) {
88
		global $pagenow;
89
90
		if ( isset( $_GET['action'] ) && 'do-core-reinstall' === $_GET['action'] ) {
91
			/**
92
			 * Sync event that fires when core reinstall was successful
93
			 *
94
			 * @since 5.0.0
95
			 *
96
			 * @param string $new_wp_version the updated WordPress version
97
			 */
98
			do_action( 'jetpack_sync_core_reinstalled_successfully', $new_wp_version );
99
			return;
100
		}
101
102
		// Core was autoudpated
103
		if (
104
			'update-core.php' !== $pagenow &&
105
			! Jetpack_Constants::is_true( 'REST_API_REQUEST' ) // wp.com rest api calls should never be marked as a core autoupdate
106
		) {
107
			/**
108
			 * Sync event that fires when core autoupdate was successful
109
			 *
110
			 * @since 5.0.0
111
			 *
112
			 * @param string $new_wp_version the updated WordPress version
113
			 * @param string $old_wp_version the previous WordPress version
114
			 */
115
			do_action( 'jetpack_sync_core_autoupdated_successfully', $new_wp_version, $this->old_wp_version );
116
			return;
117
		}
118
		/**
119
		 * Sync event that fires when core update was successful
120
		 *
121
		 * @since 5.0.0
122
		 *
123
		 * @param string $new_wp_version the updated WordPress version
124
		 * @param string $old_wp_version the previous WordPress version
125
		 */
126
		do_action( 'jetpack_sync_core_updated_successfully', $new_wp_version, $this->old_wp_version );
127
		return;
128
129
	}
130
131
	public function get_update_checksum( $update, $transient ) {
132
		$updates    = array();
133
		$no_updated = array();
134
		switch ( $transient ) {
135
			case 'update_plugins':
136
				if ( ! empty( $update->response ) && is_array( $update->response ) ) {
137
					foreach ( $update->response as $plugin_slug => $response ) {
138
						if ( ! empty( $plugin_slug ) && isset( $response->new_version ) ) {
139
							$updates[] = array( $plugin_slug => $response->new_version );
140
						}
141
					}
142
				}
143
				if ( ! empty( $update->no_update ) ) {
144
					$no_updated = array_keys( $update->no_update );
145
				}
146
147
				if ( ! isset( $no_updated['jetpack/jetpack.php'] ) && isset( $updates['jetpack/jetpack.php'] ) ) {
148
					return false;
149
				}
150
151
				break;
152
			case 'update_themes':
153
				if ( ! empty( $update->response ) && is_array( $update->response ) ) {
154
					foreach ( $update->response as $theme_slug => $response ) {
155
						if ( ! empty( $theme_slug ) && isset( $response['new_version'] ) ) {
156
							$updates[] = array( $theme_slug => $response['new_version'] );
157
						}
158
					}
159
				}
160
161
				if ( ! empty( $update->checked ) ) {
162
					$no_updated = $update->checked;
163
				}
164
165
				break;
166
			case 'update_core':
167
				if ( ! empty( $update->updates ) && is_array( $update->updates ) ) {
168
					foreach ( $update->updates as $response ) {
169
						if ( ! empty( $response->response ) && $response->response === 'latest' ) {
170
							continue;
171
						}
172
						if ( ! empty( $response->response ) && isset( $response->packages->full ) ) {
173
							$updates[] = array( $response->response => $response->packages->full );
174
						}
175
					}
176
				}
177
178
				if ( ! empty( $update->version_checked ) ) {
179
					$no_updated = $update->version_checked;
180
				}
181
182
				if ( empty( $updates ) ) {
183
					return false;
184
				}
185
				break;
186
187
		}
188
		if ( empty( $updates ) && empty( $no_updated ) ) {
189
			return false;
190
		}
191
		return $this->get_check_sum( array( $no_updated, $updates ) );
192
	}
193
194
	public function validate_update_change( $value, $expiration, $transient ) {
195
		$new_checksum = $this->get_update_checksum( $value, $transient );
196
197
		if ( false === $new_checksum ) {
198
			return;
199
		}
200
201
		$checksums = get_option( self::UPDATES_CHECKSUM_OPTION_NAME, array() );
202
203
		if ( isset( $checksums[ $transient ] ) && $checksums[ $transient ] === $new_checksum ) {
204
			return;
205
		}
206
207
		$checksums[ $transient ] = $new_checksum;
208
209
		update_option( self::UPDATES_CHECKSUM_OPTION_NAME, $checksums );
210
		if ( 'update_core' === $transient ) {
211
			/**
212
			 * jetpack_update_core_change
213
			 *
214
			 * @since 5.1.0
215
			 *
216
			 * @param array containing info that tells us what needs updating
217
			 */
218
			do_action( 'jetpack_update_core_change', $value );
219
			return;
220
		}
221
		if ( empty( $this->updates ) ) {
222
			// lets add the shutdown method once and only when the updates move from empty to filled with something
223
			add_action( 'shutdown', array( $this, 'sync_last_event' ), 9 );
224
		}
225
		if ( ! isset( $this->updates[ $transient ] ) ) {
226
			$this->updates[ $transient ] = array();
227
		}
228
		$this->updates[ $transient ][] = $value;
229
	}
230
231
	public function sync_last_event() {
232
		foreach ( $this->updates as $transient => $values ) {
233
			$value = end( $values ); // only send over the last value
234
			/**
235
			 * jetpack_{$transient}_change
236
			 * jetpack_update_plugins_change
237
			 * jetpack_update_themes_change
238
			 *
239
			 * @since 5.1.0
240
			 *
241
			 * @param array containing info that tells us what needs updating
242
			 */
243
			do_action( "jetpack_{$transient}_change", $value );
244
		}
245
246
	}
247
248
	public function enqueue_full_sync_actions( $config, $max_items_to_enqueue, $state ) {
249
		/**
250
		 * Tells the client to sync all updates to the server
251
		 *
252
		 * @since 4.2.0
253
		 *
254
		 * @param boolean Whether to expand updates (should always be true)
255
		 */
256
		do_action( 'jetpack_full_sync_updates', true );
257
258
		// The number of actions enqueued, and next module state (true == done)
259
		return array( 1, true );
260
	}
261
262
	public function estimate_full_sync_actions( $config ) {
263
		return 1;
264
	}
265
266
	function get_full_sync_actions() {
267
		return array( 'jetpack_full_sync_updates' );
268
	}
269
270
	public function get_all_updates() {
271
		return array(
272
			'core'    => get_site_transient( 'update_core' ),
273
			'plugins' => get_site_transient( 'update_plugins' ),
274
			'themes'  => get_site_transient( 'update_themes' ),
275
		);
276
	}
277
278
	// removes unnecessary keys from synced updates data
279
	function filter_update_keys( $args ) {
280
		$updates = $args[0];
281
282
		if ( isset( $updates->no_update ) ) {
283
			unset( $updates->no_update );
284
		}
285
286
		return $args;
287
	}
288
289
	function filter_upgrader_process_complete( $args ) {
290
		array_shift( $args );
291
292
		return $args;
293
	}
294
295
	public function expand_updates( $args ) {
296
		if ( $args[0] ) {
297
			return $this->get_all_updates();
298
		}
299
300
		return $args;
301
	}
302
303
	public function expand_themes( $args ) {
304
		if ( ! isset( $args[0], $args[0]->response ) ) {
305
			return $args;
306
		}
307
		if ( ! is_array( $args[0]->response ) ) {
308
			trigger_error( 'Warning: Not an Array as expected but -> ' . wp_json_encode( $args[0]->response ) . ' instead', E_USER_WARNING );
309
			return $args;
310
		}
311
		foreach ( $args[0]->response as $stylesheet => &$theme_data ) {
312
			$theme              = wp_get_theme( $stylesheet );
313
			$theme_data['name'] = $theme->name;
314
		}
315
		return $args;
316
	}
317
318
	public function reset_data() {
319
		delete_option( self::UPDATES_CHECKSUM_OPTION_NAME );
320
	}
321
}
322