Completed
Push — try/alternative-fullsync-enque... ( 2f2a9e )
by
unknown
167:50 queued 156:14
created

Jetpack_Sync_Module_Users   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 245
Duplicated Lines 10.2 %

Coupling/Cohesion

Components 2
Dependencies 1

Importance

Changes 10
Bugs 5 Features 1
Metric Value
c 10
b 5
f 1
dl 25
loc 245
rs 8.2857
wmc 39
lcom 2
cbo 1

20 Methods

Rating   Name   Duplication   Size   Complexity  
A name() 0 3 1
A init_before_send() 0 8 1
B save_user_handler() 0 31 5
B init_listeners() 0 25 1
A init_full_sync_listeners() 0 3 1
A sanitize_user_and_expand() 0 5 1
A sanitize_user() 0 7 1
A add_to_user() 0 5 1
A expand_user() 0 9 2
A expand_login_username() 0 6 1
A expand_logout_username() 0 7 1
A save_user_role_handler() 0 12 1
B save_user_cap_handler() 0 24 5
A enqueue_full_sync_actions() 0 15 2
A estimate_full_sync_actions() 13 13 2
A get_where_sql() 12 12 2
A get_full_sync_actions() 0 3 1
A get_initial_sync_user_config() 0 11 2
A expand_users() 0 12 4
A get_next_user_ids() 0 11 4

How to fix   Duplicated Code   

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:

1
<?php
2
3
class Jetpack_Sync_Module_Users extends Jetpack_Sync_Module {
4
	const MAX_INITIAL_SYNC_USERS = 100;
5
	
6
	function name() {
7
		return 'users';
8
	}
9
10
	public function init_listeners( $callable ) {
11
		// users
12
		add_action( 'user_register', array( $this, 'save_user_handler' ) );
13
		add_action( 'profile_update', array( $this, 'save_user_handler' ), 10, 2 );
14
		add_action( 'add_user_to_blog', array( $this, 'save_user_handler' ) );
15
		add_action( 'jetpack_sync_save_user', $callable, 10, 2 );
16
17
		add_action( 'deleted_user', $callable, 10, 2 );
18
		add_action( 'remove_user_from_blog', $callable, 10, 2 );
19
20
		// user roles
21
		add_action( 'add_user_role', array( $this, 'save_user_role_handler' ), 10, 2 );
22
		add_action( 'set_user_role', array( $this, 'save_user_role_handler' ), 10, 3 );
23
		add_action( 'remove_user_role', array( $this, 'save_user_role_handler' ), 10, 2 );
24
25
		// user capabilities
26
		add_action( 'added_user_meta', array( $this, 'save_user_cap_handler' ), 10, 4 );
27
		add_action( 'updated_user_meta', array( $this, 'save_user_cap_handler' ), 10, 4 );
28
		add_action( 'deleted_user_meta', array( $this, 'save_user_cap_handler' ), 10, 4 );
29
30
		// user authentication
31
		add_action( 'wp_login', $callable, 10, 2 );
32
		add_action( 'wp_login_failed', $callable, 10, 2 );
33
		add_action( 'wp_logout', $callable, 10, 0 );
34
	}
35
36
	public function init_full_sync_listeners( $callable ) {
37
		add_action( 'jetpack_full_sync_users', $callable );
38
	}
39
40
	public function init_before_send() {
41
		add_filter( 'jetpack_sync_before_send_jetpack_sync_save_user', array( $this, 'expand_user' ) );
42
		add_filter( 'jetpack_sync_before_send_wp_login', array( $this, 'expand_login_username' ), 10, 1 );
43
		add_filter( 'jetpack_sync_before_send_wp_logout', array( $this, 'expand_logout_username' ), 10, 2 );
44
45
		// full sync
46
		add_filter( 'jetpack_sync_before_send_jetpack_full_sync_users', array( $this, 'expand_users' ) );
47
	}
48
49
	public function sanitize_user_and_expand( $user ) {
50
		$user = $this->sanitize_user( $user );
51
52
		return $this->add_to_user( $user );
53
	}
54
55
	public function sanitize_user( $user ) {
56
		// this create a new user object and stops the passing of the object by reference.
57
		$user = unserialize( serialize( $user ) );
58
		unset( $user->data->user_pass );
59
60
		return $user;
61
	}
62
63
	public function add_to_user( $user ) {
64
		$user->allowed_mime_types = get_allowed_mime_types( $user );
65
66
		return $user;
67
	}
68
69
	public function expand_user( $args ) {
70
		list( $user ) = $args;
71
72
		if ( $user ) {
73
			return array( $this->add_to_user( $user ) );	
74
		}
75
76
		return false;
77
	}
78
79
	public function expand_login_username( $args ) {
80
		list( $login, $user ) = $args;
81
		$user = $this->sanitize_user( $user );
82
83
		return array( $login, $user );
84
	}
85
86
	public function expand_logout_username( $args, $user_id ) {
87
		$user  = get_userdata( $user_id );
88
		$user  = $this->sanitize_user( $user );
89
		$login = $user->data->user_login;
90
91
		return array( $login, $user );
92
	}
93
94
	function save_user_handler( $user_id, $old_user_data = null ) {
95
96
		// ensure we only sync users who are members of the current blog
97
		if ( ! is_user_member_of_blog( $user_id, get_current_blog_id() ) ) {
98
			return;
99
		}
100
101
		$user = $this->sanitize_user( get_user_by( 'id', $user_id ) );
102
103
		// Older versions of WP don't pass the old_user_data in ->data
104
		if ( isset( $old_user_data->data ) ) {
105
			$old_user = $old_user_data->data;
106
		} else {
107
			$old_user = $old_user_data;
108
		}
109
110
		if ( $old_user !== null ) {
111
			unset( $old_user->user_pass );
112
			if ( serialize( $old_user ) === serialize( $user->data ) ) {
113
				return;
114
			}
115
		}
116
		/**
117
		 * Fires when the client needs to sync an updated user
118
		 *
119
		 * @since 4.2.0
120
		 *
121
		 * @param object The WP_User object
122
		 */
123
		do_action( 'jetpack_sync_save_user', $user );
124
	}
125
126
	function save_user_role_handler( $user_id, $role, $old_roles = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $role is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $old_roles is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
127
		$user = $this->sanitize_user( get_user_by( 'id', $user_id ) );
128
129
		/**
130
		 * Fires when the client needs to sync an updated user
131
		 *
132
		 * @since 4.2.0
133
		 *
134
		 * @param object The WP_User object
135
		 */
136
		do_action( 'jetpack_sync_save_user', $user );
137
	}
138
139
	function save_user_cap_handler( $meta_id, $user_id, $meta_key, $capabilities ) {
0 ignored issues
show
Unused Code introduced by
The parameter $capabilities is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
140
141
		// if a user is currently being removed as a member of this blog, we don't fire the event
142
		if ( current_filter() === 'deleted_user_meta'
143
		     &&
144
		     preg_match( '/capabilities|user_level/', $meta_key )
145
		     &&
146
		     ! is_user_member_of_blog( $user_id, get_current_blog_id() )
147
		) {
148
			return;
149
		}
150
151
		$user =  get_user_by( 'id', $user_id );
152
		if ( $meta_key === $user->cap_key ) {
153
			/**
154
			 * Fires when the client needs to sync an updated user
155
			 *
156
			 * @since 4.2.0
157
			 *
158
			 * @param object The Sanitized WP_User object
159
			 */
160
			do_action( 'jetpack_sync_save_user', $this->sanitize_user( $user ) );
161
		}
162
	}
163
164
	public function enqueue_full_sync_actions( $config ) {
165
		global $wpdb;
166
		if ( is_array( $config ) ) {
167
			return $this->enqueue_all_ids_as_action( 'jetpack_full_sync_users', $wpdb->usermeta, 'user_id', $this->get_where_sql( $config ) );
168
		}
169
		/**
170
		 * Tells the client to sync all users to the server
171
		 *
172
		 * @since 4.2.3
173
		 *
174
		 */
175
		do_action( 'jetpack_full_sync_users', 0 );
176
177
		return $this->estimate_full_sync_actions( $config );
178
	}
179
180 View Code Duplication
	public function estimate_full_sync_actions( $config ) {
181
		global $wpdb;
182
183
		$query = "SELECT count(*) FROM $wpdb->usermeta";
184
		
185
		if ( $where_sql = $this->get_where_sql( $config ) ) {
186
			$query .= ' WHERE ' . $where_sql;
187
		}
188
189
		$count = $wpdb->get_var( $query );
190
191
		return (int) ceil( $count / self::ARRAY_CHUNK_SIZE );
192
	}
193
194 View Code Duplication
	private function get_where_sql( $config ) {
195
		global $wpdb;
196
197
		$query = "meta_key = '{$wpdb->prefix}capabilities'";
198
		
199
		// config is a list of user IDs to sync
200
		if ( is_array( $config ) ) {
201
			$query .= ' AND user_id IN (' . implode( ',', array_map( 'intval', $config ) ) . ')';
202
		}
203
204
		return $query;
205
	}
206
207
	function get_full_sync_actions() {
208
		return array( 'jetpack_full_sync_users' );
209
	}
210
211
	function get_initial_sync_user_config() {
212
		global $wpdb;
213
214
		$user_ids = $wpdb->get_col( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '{$wpdb->prefix}user_level' AND meta_value > 0 LIMIT " . ( self::MAX_INITIAL_SYNC_USERS + 1 ) );
215
216
		if ( count( $user_ids ) <= self::MAX_INITIAL_SYNC_USERS ) {
217
			return $user_ids;
218
		} else {
219
			return false;
220
		}
221
	}
222
223
	public function expand_users( $args ) {
224
		if ( is_array( $args[0] ) ) {
225
			$user_ids = $args[0];
226
		}
227
		if ( is_int( $args[0] ) ) {
228
			return $this->get_next_user_ids( $args[0] );
229
		}
230
		if ( empty( $user_ids ) ) {
231
			return false;
232
		}
233
		return array_map( array( $this, 'sanitize_user_and_expand' ), get_users( array( 'include' => $user_ids ) ) );
234
	}
235
236
	public function get_next_user_ids( $from ) {
237
		global $wpdb;
238
		while ( true ) {
239
			$ids =  $wpdb->get_col( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '{$wpdb->prefix}user_level' AND user_id > $from ORDER BY user_id ASC LIMIT " . self::ARRAY_CHUNK_SIZE );
240
			if ( is_wp_error( $ids ) || empty( $ids ) ) {
241
				return false;
242
			}
243
			$from = end( $ids );
244
			yield $ids;
245
		}
246
	}
247
}
248