1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Automattic\Jetpack\Sync\Modules; |
4
|
|
|
|
5
|
|
|
use Automattic\Jetpack\Constants as Jetpack_Constants; |
6
|
|
|
use Automattic\Jetpack\Sync\Defaults; |
7
|
|
|
|
8
|
|
|
class Users extends Module { |
9
|
|
|
const MAX_INITIAL_SYNC_USERS = 100; |
10
|
|
|
|
11
|
|
|
protected $flags = array(); |
12
|
|
|
|
13
|
|
|
function name() { |
14
|
|
|
return 'users'; |
15
|
|
|
} |
16
|
|
|
|
17
|
|
|
// this is here to support the backfill API |
18
|
|
|
public function get_object_by_id( $object_type, $id ) { |
19
|
|
|
if ( $object_type === 'user' && $user = get_user_by( 'id', intval( $id ) ) ) { |
20
|
|
|
return $this->sanitize_user_and_expand( $user ); |
21
|
|
|
} |
22
|
|
|
|
23
|
|
|
return false; |
24
|
|
|
} |
25
|
|
|
|
26
|
|
|
public function init_listeners( $callable ) { |
27
|
|
|
|
28
|
|
|
// users |
29
|
|
|
add_action( 'user_register', array( $this, 'user_register_handler' ) ); |
30
|
|
|
add_action( 'profile_update', array( $this, 'save_user_handler' ), 10, 2 ); |
31
|
|
|
|
32
|
|
|
add_action( 'add_user_to_blog', array( $this, 'add_user_to_blog_handler' ) ); |
33
|
|
|
add_action( 'jetpack_sync_add_user', $callable, 10, 2 ); |
34
|
|
|
|
35
|
|
|
add_action( 'jetpack_sync_register_user', $callable, 10, 2 ); |
36
|
|
|
add_action( 'jetpack_sync_save_user', $callable, 10, 2 ); |
37
|
|
|
|
38
|
|
|
add_action( 'jetpack_sync_user_locale', $callable, 10, 2 ); |
39
|
|
|
add_action( 'jetpack_sync_user_locale_delete', $callable, 10, 1 ); |
40
|
|
|
|
41
|
|
|
add_action( 'deleted_user', array( $this, 'deleted_user_handler' ), 10, 2 ); |
42
|
|
|
add_action( 'jetpack_deleted_user', $callable, 10, 3 ); |
43
|
|
|
add_action( 'remove_user_from_blog', array( $this, 'remove_user_from_blog_handler' ), 10, 2 ); |
44
|
|
|
add_action( 'jetpack_removed_user_from_blog', $callable, 10, 2 ); |
45
|
|
|
|
46
|
|
|
// user roles |
47
|
|
|
add_action( 'add_user_role', array( $this, 'save_user_role_handler' ), 10, 2 ); |
48
|
|
|
add_action( 'set_user_role', array( $this, 'save_user_role_handler' ), 10, 3 ); |
49
|
|
|
add_action( 'remove_user_role', array( $this, 'save_user_role_handler' ), 10, 2 ); |
50
|
|
|
|
51
|
|
|
// user capabilities |
52
|
|
|
add_action( 'added_user_meta', array( $this, 'maybe_save_user_meta' ), 10, 4 ); |
53
|
|
|
add_action( 'updated_user_meta', array( $this, 'maybe_save_user_meta' ), 10, 4 ); |
54
|
|
|
add_action( 'deleted_user_meta', array( $this, 'maybe_save_user_meta' ), 10, 4 ); |
55
|
|
|
|
56
|
|
|
// user authentication |
57
|
|
|
add_filter( 'authenticate', array( $this, 'authenticate_handler' ), 1000, 3 ); |
58
|
|
|
add_action( 'wp_login', array( $this, 'wp_login_handler' ), 10, 2 ); |
59
|
|
|
|
60
|
|
|
add_action( 'jetpack_wp_login', $callable, 10, 3 ); |
61
|
|
|
|
62
|
|
|
add_action( 'wp_logout', $callable, 10, 0 ); |
63
|
|
|
add_action( 'wp_masterbar_logout', $callable, 10, 0 ); |
64
|
|
|
|
65
|
|
|
// Add on init |
66
|
|
|
add_filter( 'jetpack_sync_before_enqueue_jetpack_sync_add_user', array( $this, 'expand_action' ) ); |
67
|
|
|
add_filter( 'jetpack_sync_before_enqueue_jetpack_sync_register_user', array( $this, 'expand_action' ) ); |
68
|
|
|
add_filter( 'jetpack_sync_before_enqueue_jetpack_sync_save_user', array( $this, 'expand_action' ) ); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
public function init_full_sync_listeners( $callable ) { |
72
|
|
|
add_action( 'jetpack_full_sync_users', $callable ); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
public function init_before_send() { |
76
|
|
|
|
77
|
|
|
add_filter( 'jetpack_sync_before_send_jetpack_wp_login', array( $this, 'expand_login_username' ), 10, 1 ); |
78
|
|
|
add_filter( 'jetpack_sync_before_send_wp_logout', array( $this, 'expand_logout_username' ), 10, 2 ); |
79
|
|
|
|
80
|
|
|
// full sync |
81
|
|
|
add_filter( 'jetpack_sync_before_send_jetpack_full_sync_users', array( $this, 'expand_users' ) ); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
private function get_user( $user ) { |
85
|
|
|
if ( is_numeric( $user ) ) { |
86
|
|
|
$user = get_user_by( 'id', $user ); |
87
|
|
|
} |
88
|
|
|
if ( $user instanceof \WP_User ) { |
|
|
|
|
89
|
|
|
return $user; |
90
|
|
|
} |
91
|
|
|
return null; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
public function sanitize_user( $user ) { |
95
|
|
|
$user = $this->get_user( $user ); |
96
|
|
|
// this create a new user object and stops the passing of the object by reference. |
97
|
|
|
$user = unserialize( serialize( $user ) ); |
98
|
|
|
|
99
|
|
|
if ( is_object( $user ) && is_object( $user->data ) ) { |
100
|
|
|
unset( $user->data->user_pass ); |
101
|
|
|
} |
102
|
|
|
return $user; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
public function expand_user( $user ) { |
106
|
|
|
if ( ! is_object( $user ) ) { |
107
|
|
|
return null; |
108
|
|
|
} |
109
|
|
|
$user->allowed_mime_types = get_allowed_mime_types( $user ); |
110
|
|
|
$user->allcaps = $this->get_real_user_capabilities( $user ); |
111
|
|
|
|
112
|
|
|
// Only set the user locale if it is different from the site local |
113
|
|
|
if ( get_locale() !== get_user_locale( $user->ID ) ) { |
114
|
|
|
$user->locale = get_user_locale( $user->ID ); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
return $user; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
public function get_real_user_capabilities( $user ) { |
121
|
|
|
$user_capabilities = array(); |
122
|
|
|
if ( is_wp_error( $user ) ) { |
123
|
|
|
return $user_capabilities; |
124
|
|
|
} |
125
|
|
|
foreach ( Defaults::get_capabilities_whitelist() as $capability ) { |
126
|
|
|
if ( $user_has_capabilities = user_can( $user, $capability ) ) { |
|
|
|
|
127
|
|
|
$user_capabilities[ $capability ] = true; |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
return $user_capabilities; |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
public function sanitize_user_and_expand( $user ) { |
134
|
|
|
$user = $this->get_user( $user ); |
135
|
|
|
$user = $this->expand_user( $user ); |
136
|
|
|
return $this->sanitize_user( $user ); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
public function expand_action( $args ) { |
140
|
|
|
// the first argument is always the user |
141
|
|
|
list( $user ) = $args; |
142
|
|
|
if ( $user ) { |
143
|
|
|
$args[0] = $this->sanitize_user_and_expand( $user ); |
144
|
|
|
return $args; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
return false; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
public function expand_login_username( $args ) { |
151
|
|
|
list( $login, $user, $flags ) = $args; |
152
|
|
|
$user = $this->sanitize_user( $user ); |
153
|
|
|
|
154
|
|
|
return array( $login, $user, $flags ); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
public function expand_logout_username( $args, $user_id ) { |
158
|
|
|
$user = get_userdata( $user_id ); |
159
|
|
|
$user = $this->sanitize_user( $user ); |
160
|
|
|
|
161
|
|
|
$login = ''; |
162
|
|
|
if ( is_object( $user ) && is_object( $user->data ) ) { |
163
|
|
|
$login = $user->data->user_login; |
164
|
|
|
} |
165
|
|
|
// if we don't have a user here lets not send anything. |
166
|
|
|
if ( empty( $login ) ) { |
167
|
|
|
return false; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
return array( $login, $user ); |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* Additional processing is needed for wp_login so we introduce this wrapper |
175
|
|
|
* handler. |
176
|
|
|
* |
177
|
|
|
* @param String $user_login the user login. |
178
|
|
|
* @param WP_User $user the user object. |
179
|
|
|
*/ |
180
|
|
|
function wp_login_handler( $user_login, $user ) { |
181
|
|
|
/** |
182
|
|
|
* Fires when a user is logged into a site. |
183
|
|
|
* |
184
|
|
|
* @since 7.2.0 |
185
|
|
|
* |
186
|
|
|
* @param Numeric $user_id The user ID. |
187
|
|
|
* @param WP_User $user The User Object of the user that currently logged in |
188
|
|
|
* @param Array $params Any Flags that have been added during login |
189
|
|
|
*/ |
190
|
|
|
do_action( 'jetpack_wp_login', $user->ID, $user, $this->get_flags( $user->ID ) ); |
191
|
|
|
$this->clear_flags( $user->ID ); |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* A hook for the authenticate event that checks the password strength. |
196
|
|
|
* |
197
|
|
|
* @param WP_Error|WP_User $user the user object, or an error. |
198
|
|
|
* @param String $username the username. |
199
|
|
|
* @param Sting $password the password used to authenticate. |
200
|
|
|
* @return WP_Error|WP_User the same object that was passed into the function. |
201
|
|
|
*/ |
202
|
|
|
public function authenticate_handler( $user, $username, $password ) { |
203
|
|
|
// In case of cookie authentication we don't do anything here. |
204
|
|
|
if ( empty( $password ) ) { |
205
|
|
|
return $user; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
// We are only interested in successful authentication events. |
209
|
|
|
if ( is_wp_error( $user ) || ! ( $user instanceof \WP_User ) ) { |
|
|
|
|
210
|
|
|
return $user; |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
jetpack_require_lib( 'class.jetpack-password-checker' ); |
214
|
|
|
$password_checker = new \Jetpack_Password_Checker( $user->ID ); |
215
|
|
|
|
216
|
|
|
$test_results = $password_checker->test( $password, true ); |
217
|
|
|
|
218
|
|
|
// If the password passes tests, we don't do anything. |
219
|
|
|
if ( empty( $test_results['test_results']['failed'] ) ) { |
220
|
|
|
return $user; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
$this->add_flags( |
224
|
|
|
$user->ID, |
225
|
|
|
array( |
226
|
|
|
'warning' => 'The password failed at least one strength test.', |
227
|
|
|
'failures' => $test_results['test_results']['failed'], |
228
|
|
|
) |
229
|
|
|
); |
230
|
|
|
|
231
|
|
|
return $user; |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
public function deleted_user_handler( $deleted_user_id, $reassigned_user_id = '' ) { |
235
|
|
|
$is_multisite = is_multisite(); |
236
|
|
|
/** |
237
|
|
|
* Fires when a user is deleted on a site |
238
|
|
|
* |
239
|
|
|
* @since 5.4.0 |
240
|
|
|
* |
241
|
|
|
* @param int $deleted_user_id - ID of the deleted user |
242
|
|
|
* @param int $reassigned_user_id - ID of the user the deleted user's posts is reassigned to (if any) |
243
|
|
|
* @param bool $is_multisite - Whether this site is a multisite installation |
244
|
|
|
*/ |
245
|
|
|
do_action( 'jetpack_deleted_user', $deleted_user_id, $reassigned_user_id, $is_multisite ); |
246
|
|
|
} |
247
|
|
|
|
248
|
|
View Code Duplication |
function user_register_handler( $user_id, $old_user_data = null ) { |
249
|
|
|
// ensure we only sync users who are members of the current blog |
250
|
|
|
if ( ! is_user_member_of_blog( $user_id, get_current_blog_id() ) ) { |
251
|
|
|
return; |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
if ( Jetpack_Constants::is_true( 'JETPACK_INVITE_ACCEPTED' ) ) { |
255
|
|
|
$this->add_flags( $user_id, array( 'invitation_accepted' => true ) ); |
256
|
|
|
} |
257
|
|
|
/** |
258
|
|
|
* Fires when a new user is registered on a site |
259
|
|
|
* |
260
|
|
|
* @since 4.9.0 |
261
|
|
|
* |
262
|
|
|
* @param object The WP_User object |
263
|
|
|
*/ |
264
|
|
|
do_action( 'jetpack_sync_register_user', $user_id, $this->get_flags( $user_id ) ); |
265
|
|
|
$this->clear_flags( $user_id ); |
266
|
|
|
|
267
|
|
|
} |
268
|
|
|
|
269
|
|
View Code Duplication |
function add_user_to_blog_handler( $user_id, $old_user_data = null ) { |
270
|
|
|
// ensure we only sync users who are members of the current blog |
271
|
|
|
if ( ! is_user_member_of_blog( $user_id, get_current_blog_id() ) ) { |
272
|
|
|
return; |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
if ( Jetpack_Constants::is_true( 'JETPACK_INVITE_ACCEPTED' ) ) { |
276
|
|
|
$this->add_flags( $user_id, array( 'invitation_accepted' => true ) ); |
277
|
|
|
} |
278
|
|
|
/** |
279
|
|
|
* Fires when a user is added on a site |
280
|
|
|
* |
281
|
|
|
* @since 4.9.0 |
282
|
|
|
* |
283
|
|
|
* @param object The WP_User object |
284
|
|
|
*/ |
285
|
|
|
do_action( 'jetpack_sync_add_user', $user_id, $this->get_flags( $user_id ) ); |
286
|
|
|
$this->clear_flags( $user_id ); |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
function save_user_handler( $user_id, $old_user_data = null ) { |
290
|
|
|
// ensure we only sync users who are members of the current blog |
291
|
|
|
if ( ! is_user_member_of_blog( $user_id, get_current_blog_id() ) ) { |
292
|
|
|
return; |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
$user = get_user_by( 'id', $user_id ); |
296
|
|
|
|
297
|
|
|
// Older versions of WP don't pass the old_user_data in ->data |
298
|
|
|
if ( isset( $old_user_data->data ) ) { |
299
|
|
|
$old_user = $old_user_data->data; |
300
|
|
|
} else { |
301
|
|
|
$old_user = $old_user_data; |
302
|
|
|
} |
303
|
|
|
|
304
|
|
|
if ( $old_user !== null && $user->user_pass !== $old_user->user_pass ) { |
305
|
|
|
$this->flags[ $user_id ]['password_changed'] = true; |
306
|
|
|
} |
307
|
|
|
if ( $old_user !== null && $user->data->user_email !== $old_user->user_email ) { |
308
|
|
|
// The '_new_email' user meta is deleted right after the call to wp_update_user |
309
|
|
|
// that got us to this point so if it's still set then this was a user confirming |
310
|
|
|
// their new email address |
311
|
|
|
if ( 1 === intval( get_user_meta( $user->ID, '_new_email', true ) ) ) { |
312
|
|
|
$this->flags[ $user_id ]['email_changed'] = true; |
313
|
|
|
} |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
/** |
317
|
|
|
* Fires when the client needs to sync an updated user |
318
|
|
|
* |
319
|
|
|
* @since 4.2.0 |
320
|
|
|
* |
321
|
|
|
* @param object The WP_User object |
322
|
|
|
* @param array state - New since 5.8.0 |
323
|
|
|
*/ |
324
|
|
|
do_action( 'jetpack_sync_save_user', $user_id, $this->get_flags( $user_id ) ); |
325
|
|
|
$this->clear_flags( $user_id ); |
326
|
|
|
} |
327
|
|
|
|
328
|
|
|
function save_user_role_handler( $user_id, $role, $old_roles = null ) { |
329
|
|
|
$this->add_flags( |
330
|
|
|
$user_id, |
331
|
|
|
array( |
332
|
|
|
'role_changed' => true, |
333
|
|
|
'previous_role' => $old_roles, |
334
|
|
|
) |
335
|
|
|
); |
336
|
|
|
|
337
|
|
|
// The jetpack_sync_register_user payload is identical to jetpack_sync_save_user, don't send both |
338
|
|
|
if ( $this->is_create_user() || $this->is_add_user_to_blog() ) { |
339
|
|
|
return; |
340
|
|
|
} |
341
|
|
|
/** |
342
|
|
|
* This action is documented already in this file |
343
|
|
|
*/ |
344
|
|
|
do_action( 'jetpack_sync_save_user', $user_id, $this->get_flags( $user_id ) ); |
345
|
|
|
$this->clear_flags( $user_id ); |
346
|
|
|
} |
347
|
|
|
|
348
|
|
|
function get_flags( $user_id ) { |
349
|
|
|
if ( isset( $this->flags[ $user_id ] ) ) { |
350
|
|
|
return $this->flags[ $user_id ]; |
351
|
|
|
} |
352
|
|
|
return array(); |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
function clear_flags( $user_id ) { |
356
|
|
|
if ( isset( $this->flags[ $user_id ] ) ) { |
357
|
|
|
unset( $this->flags[ $user_id ] ); |
358
|
|
|
} |
359
|
|
|
} |
360
|
|
|
|
361
|
|
|
function add_flags( $user_id, $flags ) { |
362
|
|
|
$this->flags[ $user_id ] = wp_parse_args( $flags, $this->get_flags( $user_id ) ); |
363
|
|
|
} |
364
|
|
|
|
365
|
|
|
function maybe_save_user_meta( $meta_id, $user_id, $meta_key, $value ) { |
366
|
|
|
if ( $meta_key === 'locale' ) { |
367
|
|
|
$this->add_flags( $user_id, array( 'locale_changed' => true ) ); |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
$user = get_user_by( 'id', $user_id ); |
371
|
|
|
if ( isset( $user->cap_key ) && $meta_key === $user->cap_key ) { |
372
|
|
|
$this->add_flags( $user_id, array( 'capabilities_changed' => true ) ); |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
if ( $this->is_create_user() || $this->is_add_user_to_blog() || $this->is_delete_user() ) { |
376
|
|
|
return; |
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
if ( isset( $this->flags[ $user_id ] ) ) { |
380
|
|
|
/** |
381
|
|
|
* This action is documented already in this file |
382
|
|
|
*/ |
383
|
|
|
do_action( 'jetpack_sync_save_user', $user_id, $this->get_flags( $user_id ) ); |
384
|
|
|
} |
385
|
|
|
} |
386
|
|
|
|
387
|
|
|
public function enqueue_full_sync_actions( $config, $max_items_to_enqueue, $state ) { |
388
|
|
|
global $wpdb; |
389
|
|
|
|
390
|
|
|
return $this->enqueue_all_ids_as_action( 'jetpack_full_sync_users', $wpdb->usermeta, 'user_id', $this->get_where_sql( $config ), $max_items_to_enqueue, $state ); |
391
|
|
|
} |
392
|
|
|
|
393
|
|
View Code Duplication |
public function estimate_full_sync_actions( $config ) { |
394
|
|
|
global $wpdb; |
395
|
|
|
|
396
|
|
|
$query = "SELECT count(*) FROM $wpdb->usermeta"; |
397
|
|
|
|
398
|
|
|
if ( $where_sql = $this->get_where_sql( $config ) ) { |
399
|
|
|
$query .= ' WHERE ' . $where_sql; |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
$count = $wpdb->get_var( $query ); |
403
|
|
|
|
404
|
|
|
return (int) ceil( $count / self::ARRAY_CHUNK_SIZE ); |
405
|
|
|
} |
406
|
|
|
|
407
|
|
View Code Duplication |
private function get_where_sql( $config ) { |
408
|
|
|
global $wpdb; |
409
|
|
|
|
410
|
|
|
$query = "meta_key = '{$wpdb->prefix}capabilities'"; |
411
|
|
|
|
412
|
|
|
// config is a list of user IDs to sync |
413
|
|
|
if ( is_array( $config ) ) { |
414
|
|
|
$query .= ' AND user_id IN (' . implode( ',', array_map( 'intval', $config ) ) . ')'; |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
return $query; |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
function get_full_sync_actions() { |
421
|
|
|
return array( 'jetpack_full_sync_users' ); |
422
|
|
|
} |
423
|
|
|
|
424
|
|
|
function get_initial_sync_user_config() { |
425
|
|
|
global $wpdb; |
426
|
|
|
|
427
|
|
|
$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 ) ); |
428
|
|
|
|
429
|
|
|
if ( count( $user_ids ) <= self::MAX_INITIAL_SYNC_USERS ) { |
430
|
|
|
return $user_ids; |
431
|
|
|
} else { |
432
|
|
|
return false; |
433
|
|
|
} |
434
|
|
|
} |
435
|
|
|
|
436
|
|
|
public function expand_users( $args ) { |
437
|
|
|
list( $user_ids, $previous_end ) = $args; |
438
|
|
|
|
439
|
|
|
return array( |
440
|
|
|
'users' => array_map( |
441
|
|
|
array( $this, 'sanitize_user_and_expand' ), |
442
|
|
|
get_users( |
443
|
|
|
array( |
444
|
|
|
'include' => $user_ids, |
445
|
|
|
'orderby' => 'ID', |
446
|
|
|
'order' => 'DESC', |
447
|
|
|
) |
448
|
|
|
) |
449
|
|
|
), |
450
|
|
|
'previous_end' => $previous_end, |
451
|
|
|
); |
452
|
|
|
} |
453
|
|
|
|
454
|
|
|
public function remove_user_from_blog_handler( $user_id, $blog_id ) { |
455
|
|
|
// User is removed on add, see https://github.com/WordPress/WordPress/blob/0401cee8b36df3def8e807dd766adc02b359dfaf/wp-includes/ms-functions.php#L2114 |
456
|
|
|
if ( $this->is_add_new_user_to_blog() ) { |
457
|
|
|
return; |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
$reassigned_user_id = $this->get_reassigned_network_user_id(); |
461
|
|
|
|
462
|
|
|
// Note that we are in the context of the blog the user is removed from, see https://github.com/WordPress/WordPress/blob/473e1ba73bc5c18c72d7f288447503713d518790/wp-includes/ms-functions.php#L233 |
463
|
|
|
/** |
464
|
|
|
* Fires when a user is removed from a blog on a multisite installation |
465
|
|
|
* |
466
|
|
|
* @since 5.4.0 |
467
|
|
|
* |
468
|
|
|
* @param int $user_id - ID of the removed user |
469
|
|
|
* @param int $reassigned_user_id - ID of the user the removed user's posts is reassigned to (if any) |
470
|
|
|
*/ |
471
|
|
|
do_action( 'jetpack_removed_user_from_blog', $user_id, $reassigned_user_id ); |
472
|
|
|
} |
473
|
|
|
|
474
|
|
|
protected function is_add_new_user_to_blog() { |
475
|
|
|
return \Jetpack::is_function_in_backtrace( 'add_new_user_to_blog' ); |
476
|
|
|
} |
477
|
|
|
|
478
|
|
|
protected function is_add_user_to_blog() { |
479
|
|
|
return \Jetpack::is_function_in_backtrace( 'add_user_to_blog' ); |
480
|
|
|
} |
481
|
|
|
|
482
|
|
|
protected function is_delete_user() { |
483
|
|
|
return \Jetpack::is_function_in_backtrace( array( 'wp_delete_user', 'remove_user_from_blog' ) ); |
484
|
|
|
} |
485
|
|
|
|
486
|
|
|
protected function is_create_user() { |
487
|
|
|
$functions = array( |
488
|
|
|
'add_new_user_to_blog', // Used to suppress jetpack_sync_save_user in save_user_cap_handler when user registered on multi site |
489
|
|
|
'wp_create_user', // Used to suppress jetpack_sync_save_user in save_user_role_handler when user registered on multi site |
490
|
|
|
'wp_insert_user', // Used to suppress jetpack_sync_save_user in save_user_cap_handler and save_user_role_handler when user registered on single site |
491
|
|
|
); |
492
|
|
|
|
493
|
|
|
return \Jetpack::is_function_in_backtrace( $functions ); |
494
|
|
|
} |
495
|
|
|
|
496
|
|
|
protected function get_reassigned_network_user_id() { |
497
|
|
|
$backtrace = debug_backtrace( false ); // phpcs:ignore PHPCompatibility.PHP.NewFunctionParameters.debug_backtrace_optionsFound |
498
|
|
|
foreach ( $backtrace as $call ) { |
499
|
|
|
if ( |
500
|
|
|
'remove_user_from_blog' === $call['function'] && |
501
|
|
|
3 === count( $call['args'] ) |
502
|
|
|
) { |
503
|
|
|
return $call['args'][2]; |
504
|
|
|
} |
505
|
|
|
} |
506
|
|
|
|
507
|
|
|
return false; |
508
|
|
|
} |
509
|
|
|
} |
510
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.