|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* User account management - approval/block. |
|
4
|
|
|
* |
|
5
|
|
|
* @package user-approval |
|
6
|
|
|
*/ |
|
7
|
|
|
|
|
8
|
|
|
namespace User_Approval\Management; |
|
9
|
|
|
|
|
10
|
|
|
use function User_Approval\filter_input; |
|
11
|
|
|
use function User_Approval\get_default_user_role; |
|
12
|
|
|
use function User_Approval\get_pre_approved_user_roles; |
|
13
|
|
|
use function User_Approval\get_user_status; |
|
14
|
|
|
|
|
15
|
|
|
use const User_Approval\STATUS_APPROVED; |
|
|
|
|
|
|
16
|
|
|
use const User_Approval\STATUS_APPROVED_NONCE; |
|
|
|
|
|
|
17
|
|
|
use const User_Approval\STATUS_BLOCKED; |
|
|
|
|
|
|
18
|
|
|
use const User_Approval\STATUS_BLOCKED_NONCE; |
|
|
|
|
|
|
19
|
|
|
use const User_Approval\STATUS_META_KEY; |
|
|
|
|
|
|
20
|
|
|
use const User_Approval\STATUS_PENDING; |
|
|
|
|
|
|
21
|
|
|
use const User_Approval\STATUS_PRE_APPROVED; |
|
|
|
|
|
|
22
|
|
|
|
|
23
|
|
|
use WP_User; |
|
24
|
1 |
|
|
|
25
|
|
|
/** |
|
26
|
1 |
|
* Hook up all the filters and actions. |
|
27
|
1 |
|
*/ |
|
28
|
|
|
function bootstrap() { |
|
29
|
1 |
|
add_action( 'manage_users_columns', __NAMESPACE__ . '\\user_verification_column', 1 ); |
|
30
|
|
|
|
|
31
|
1 |
|
add_filter( 'manage_users_custom_column', __NAMESPACE__ . '\\add_user_verification_status', 10, 3 ); |
|
32
|
|
|
add_filter( 'user_row_actions', __NAMESPACE__ . '\\add_user_verification_action', 10, 2 ); |
|
33
|
1 |
|
|
|
34
|
1 |
|
add_action( 'admin_action_aj_user_status', __NAMESPACE__ . '\\aj_user_status_update' ); |
|
35
|
|
|
|
|
36
|
1 |
|
add_filter( 'wp_new_user_notification_email', __NAMESPACE__ . '\\update_approved_new_user_email', 50, 3 ); |
|
37
|
|
|
|
|
38
|
|
|
add_filter( 'manage_users_extra_tablenav', __NAMESPACE__ . '\\add_user_status_filters', 10 ); |
|
39
|
|
|
add_filter( 'users_list_table_query_args', __NAMESPACE__ . '\\filter_user_list_by_status', 100 ); |
|
40
|
|
|
|
|
41
|
|
|
} |
|
42
|
|
|
|
|
43
|
|
|
/** |
|
44
|
|
|
* Add new column for users list page for user status. |
|
45
|
|
|
* |
|
46
|
|
|
* @param array $columns Columns list of user data. |
|
47
|
1 |
|
* |
|
48
|
|
|
* @return array |
|
49
|
1 |
|
*/ |
|
50
|
|
|
function user_verification_column( $columns ) { |
|
51
|
|
|
|
|
52
|
|
|
$columns[ STATUS_META_KEY ] = esc_html__( 'Status', 'user-approval' ); |
|
53
|
|
|
|
|
54
|
|
|
return $columns; |
|
55
|
|
|
} |
|
56
|
|
|
|
|
57
|
|
|
/** |
|
58
|
|
|
* Add a user status to status column of respective user row. |
|
59
|
|
|
* |
|
60
|
|
|
* @param string $val Default value of column. |
|
61
|
|
|
* @param string $column_name Column id/name. |
|
62
|
|
|
* @param int $user_id User id of respective user row. |
|
63
|
2 |
|
* |
|
64
|
|
|
* @return array|string |
|
65
|
|
|
*/ |
|
66
|
|
|
function add_user_verification_status( $val, $column_name, $user_id ) { |
|
67
|
2 |
|
|
|
68
|
2 |
|
if ( STATUS_META_KEY !== $column_name ) { |
|
69
|
2 |
|
return $val; |
|
70
|
|
|
} |
|
71
|
2 |
|
|
|
72
|
|
|
$user_status = get_user_meta( $user_id, STATUS_META_KEY, true ) ?: STATUS_PENDING; |
|
73
|
|
|
$user = get_userdata( $user_id ); |
|
74
|
|
|
$user_status = ( ! empty( $user ) && in_array( get_default_user_role(), $user->roles, true ) ) ? $user_status : STATUS_PRE_APPROVED; |
|
75
|
|
|
|
|
76
|
|
|
return get_user_status( $user_status ); |
|
77
|
|
|
} |
|
78
|
|
|
|
|
79
|
|
|
/** |
|
80
|
|
|
* Add action links to respective user row to approve/block the user. |
|
81
|
|
|
* |
|
82
|
|
|
* @param array $actions All action link lists. |
|
83
|
|
|
* @param WP_User $user WP_User object for respective user row. |
|
84
|
1 |
|
* |
|
85
|
1 |
|
* @return array |
|
86
|
|
|
*/ |
|
87
|
|
|
function add_user_verification_action( $actions, $user ) { |
|
88
|
1 |
|
|
|
89
|
|
|
if ( ! in_array( get_default_user_role(), $user->roles, true ) ) { |
|
90
|
|
|
return $actions; |
|
91
|
1 |
|
} |
|
92
|
1 |
|
|
|
93
|
1 |
|
$user_current_status = get_user_meta( $user->ID, STATUS_META_KEY, true ); |
|
94
|
|
|
|
|
95
|
|
|
$query_args = [ |
|
96
|
|
|
'user' => $user->ID, |
|
97
|
1 |
|
'action' => STATUS_META_KEY, |
|
98
|
1 |
|
'status' => STATUS_APPROVED, |
|
99
|
1 |
|
]; |
|
100
|
|
|
|
|
101
|
1 |
|
// Approve action link. |
|
102
|
|
|
$approve_link = add_query_arg( $query_args ); |
|
103
|
|
|
$approve_link = remove_query_arg( [ 'new_role' ], $approve_link ); |
|
104
|
1 |
|
$approve_link = wp_nonce_url( $approve_link, STATUS_APPROVED_NONCE ); |
|
105
|
1 |
|
|
|
106
|
1 |
|
$query_args['status'] = STATUS_BLOCKED; |
|
107
|
|
|
|
|
108
|
1 |
|
// Block action link. |
|
109
|
1 |
|
$block_link = add_query_arg( $query_args ); |
|
110
|
1 |
|
$block_link = remove_query_arg( [ 'new_role' ], $block_link ); |
|
111
|
1 |
|
$block_link = wp_nonce_url( $block_link, STATUS_BLOCKED_NONCE ); |
|
112
|
|
|
|
|
113
|
|
|
$approve_action = sprintf( |
|
114
|
1 |
|
'<a href="%s">%s</a>', |
|
115
|
1 |
|
esc_url( $approve_link ), |
|
116
|
1 |
|
get_user_status( STATUS_APPROVED ) |
|
|
|
|
|
|
117
|
1 |
|
); |
|
118
|
|
|
|
|
119
|
|
|
$block_action = sprintf( |
|
120
|
1 |
|
'<a href="%s">%s</a>', |
|
121
|
1 |
|
esc_url( $block_link ), |
|
122
|
1 |
|
get_user_status( STATUS_BLOCKED ) |
|
123
|
|
|
); |
|
124
|
|
|
|
|
125
|
1 |
|
$actions = array_merge( $actions, [ |
|
126
|
1 |
|
'approved' => $approve_action, |
|
127
|
|
|
'blocked' => $block_action, |
|
128
|
|
|
] ); |
|
129
|
1 |
|
|
|
130
|
|
|
if ( isset( $actions[ $user_current_status ] ) ) { |
|
131
|
|
|
unset( $actions[ $user_current_status ] ); |
|
132
|
|
|
} |
|
133
|
|
|
|
|
134
|
|
|
return $actions; |
|
135
|
|
|
} |
|
136
|
1 |
|
|
|
137
|
1 |
|
/** |
|
138
|
|
|
* Update user status on post request. |
|
139
|
1 |
|
*/ |
|
140
|
1 |
|
function aj_user_status_update() { |
|
141
|
|
|
$user_id = filter_input( INPUT_GET, 'user', FILTER_VALIDATE_INT ); |
|
142
|
|
|
$status = filter_input( INPUT_GET, 'status', FILTER_SANITIZE_STRING ); |
|
143
|
1 |
|
|
|
144
|
1 |
|
$user = get_userdata( $user_id ); |
|
|
|
|
|
|
145
|
1 |
|
$user_status = get_user_meta( $user_id, STATUS_META_KEY, true ); |
|
|
|
|
|
|
146
|
1 |
|
|
|
147
|
|
|
if ( |
|
148
|
|
|
! $user instanceof WP_User |
|
149
|
|
|
|| ! in_array( get_default_user_role(), $user->roles, true ) |
|
150
|
|
|
|| ( $status === $user_status ) // Avoid any refresh page. |
|
151
|
1 |
|
|| ! current_user_can( 'list_users' ) |
|
152
|
|
|
) { |
|
153
|
1 |
|
return; |
|
154
|
1 |
|
} |
|
155
|
1 |
|
|
|
156
|
1 |
|
$current_user_id = get_current_user_id(); |
|
157
|
1 |
|
|
|
158
|
1 |
|
if ( STATUS_APPROVED === $status && check_admin_referer( STATUS_APPROVED_NONCE ) ) { |
|
159
|
1 |
|
update_user_meta( $user_id, STATUS_META_KEY, STATUS_APPROVED ); |
|
160
|
1 |
|
wp_send_new_user_notifications( $user_id, 'user' ); |
|
161
|
|
|
update_user_meta( $user_id, 'aj_user_verified_by', $current_user_id ); |
|
162
|
1 |
|
} elseif ( STATUS_BLOCKED === $status && check_admin_referer( STATUS_BLOCKED_NONCE ) ) { |
|
163
|
|
|
update_user_meta( $user_id, STATUS_META_KEY, STATUS_BLOCKED ); |
|
164
|
|
|
send_user_blocked_email( $user ); |
|
165
|
|
|
update_user_meta( $user_id, 'aj_user_verified_by', $current_user_id ); |
|
166
|
|
|
} |
|
167
|
|
|
} |
|
168
|
|
|
|
|
169
|
|
|
/** |
|
170
|
|
|
* Send a notification/email to approved user. |
|
171
|
|
|
* |
|
172
|
|
|
* @param array $email_data { |
|
173
|
|
|
* Used to build wp_mail(). |
|
174
|
|
|
* |
|
175
|
|
|
* @type string $to The intended recipient - New user email address. |
|
176
|
|
|
* @type string $subject The subject of the email. |
|
177
|
|
|
* @type string $message The body of the email. |
|
178
|
|
|
* @type string $headers The headers of the email. |
|
179
|
|
|
* } |
|
180
|
|
|
* @param WP_User $user User object for new user. |
|
181
|
|
|
* @param string $blogname The site title. |
|
182
|
1 |
|
* |
|
183
|
|
|
* @return array Updated email data for wp_mail. |
|
184
|
|
|
*/ |
|
185
|
|
|
function update_approved_new_user_email( $email_data, $user, $blogname ) { |
|
186
|
1 |
|
|
|
187
|
|
|
if ( empty( $user ) || ! in_array( get_default_user_role(), $user->roles, true ) ) { |
|
188
|
1 |
|
return $email_data; |
|
189
|
1 |
|
} |
|
190
|
|
|
|
|
191
|
1 |
|
$message = sprintf( |
|
192
|
1 |
|
/* translators: %s: User login. */ |
|
193
|
|
|
esc_html__( 'You have been approved to access %s', 'user-approval' ), |
|
194
|
|
|
$blogname |
|
195
|
1 |
|
); |
|
196
|
1 |
|
$message .= "\r\n\r\n"; |
|
197
|
|
|
$message .= $email_data['message']; |
|
198
|
1 |
|
|
|
199
|
|
|
/* translators: Login details notification email subject. %s: Site title. */ |
|
200
|
|
|
$email_data['subject'] = esc_html__( '[%s] Login Details [Account Approved]', 'user-approval' ); |
|
201
|
|
|
$email_data['message'] = $message; |
|
202
|
|
|
|
|
203
|
|
|
return apply_filters( 'user_approval_approved_user_email_data', $email_data ); |
|
204
|
|
|
} |
|
205
|
|
|
|
|
206
|
|
|
/** |
|
207
|
1 |
|
* Send a notification/email to blocked user. |
|
208
|
|
|
* |
|
209
|
1 |
|
* @param WP_User $user WP_User object. |
|
210
|
|
|
*/ |
|
211
|
1 |
|
function send_user_blocked_email( $user ) { |
|
212
|
1 |
|
$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); |
|
|
|
|
|
|
213
|
|
|
|
|
214
|
|
|
$message = sprintf( |
|
215
|
1 |
|
/* translators: %s: Site title. */ |
|
216
|
|
|
esc_html__( 'You have been denied access to %s.', 'user-approval' ), |
|
217
|
1 |
|
$blogname |
|
218
|
1 |
|
); |
|
219
|
|
|
|
|
220
|
|
|
$subject = sprintf( |
|
221
|
|
|
/* translators: %s: Site title. */ |
|
222
|
1 |
|
esc_html__( '[%s] Account Blocked.', 'user-approval' ), |
|
223
|
1 |
|
$blogname |
|
224
|
1 |
|
); |
|
225
|
1 |
|
|
|
226
|
|
|
$email_data = [ |
|
227
|
|
|
'to' => $user->user_email, |
|
228
|
1 |
|
'subject' => $subject, |
|
229
|
|
|
'message' => $message, |
|
230
|
|
|
'headers' => '', |
|
231
|
1 |
|
]; |
|
232
|
1 |
|
|
|
233
|
1 |
|
/** |
|
234
|
1 |
|
* Filters the contents of account blocked notification email sent to the blogger. |
|
235
|
1 |
|
* |
|
236
|
|
|
* @param array $email_data { |
|
237
|
1 |
|
* Used to build wp_mail(). |
|
238
|
|
|
* |
|
239
|
|
|
* @type string $to The intended recipient - site admin email address. |
|
240
|
|
|
* @type string $subject The subject of the email. |
|
241
|
|
|
* @type string $message The body of the email. |
|
242
|
|
|
* @type string $headers The headers of the email. |
|
243
|
|
|
* } |
|
244
|
|
|
* @param WP_User $user User object for new user. |
|
245
|
|
|
* @param string $blogname The site title. |
|
246
|
1 |
|
*/ |
|
247
|
1 |
|
$email_data = apply_filters( 'user_approval_blocked_user_email_data', $email_data, $user, $blogname ); |
|
248
|
|
|
|
|
249
|
|
|
// phpcs:ignore WordPressVIPMinimum.VIP.RestrictedFunctions.wp_mail_wp_mail, WordPressVIPMinimum.Functions.RestrictedFunctions.wp_mail_wp_mail |
|
250
|
1 |
|
wp_mail( |
|
251
|
1 |
|
$email_data['to'], |
|
252
|
|
|
wp_specialchars_decode( $email_data['subject'] ), |
|
253
|
|
|
$email_data['message'], |
|
254
|
1 |
|
$email_data['headers'] |
|
255
|
|
|
); |
|
256
|
|
|
} |
|
257
|
|
|
|
|
258
|
1 |
|
/** |
|
259
|
1 |
|
* Add a filter to list users based on user status. |
|
260
|
1 |
|
* |
|
261
|
1 |
|
* @param string $which The location of the extra table nav markup: 'top' or 'bottom'. |
|
262
|
1 |
|
*/ |
|
263
|
|
|
function add_user_status_filters( $which ) { |
|
264
|
1 |
|
|
|
265
|
|
|
if ( 'top' !== $which ) { |
|
266
|
1 |
|
return; |
|
267
|
1 |
|
} |
|
268
|
1 |
|
|
|
269
|
1 |
|
$status = filter_input( INPUT_GET, 'user_status', FILTER_SANITIZE_STRING ); |
|
270
|
1 |
|
$all_user_status = get_user_status( 'all' ); |
|
271
|
|
|
|
|
272
|
|
|
?> |
|
273
|
|
|
<div class="alignleft actions"> |
|
274
|
1 |
|
<label for="filter-by-date" class="screen-reader-text">Filter by user status</label> |
|
275
|
|
|
<select name="user_status" id="filter-by-user-status"> |
|
276
|
|
|
<?php |
|
277
|
|
|
printf( |
|
278
|
1 |
|
'<option %s value="%s">%s</option>', |
|
279
|
|
|
( 'all' === $status ) ? esc_html( 'selected="selected"' ) : '', |
|
280
|
|
|
esc_attr( 'all' ), |
|
281
|
|
|
esc_html__( 'All', 'user-approval' ) |
|
282
|
|
|
); |
|
283
|
|
|
foreach ( $all_user_status as $value => $label ) { |
|
284
|
|
|
|
|
285
|
|
|
printf( |
|
286
|
|
|
'<option %s value="%s">%s</option>', |
|
287
|
|
|
( $value === $status ) ? esc_html( 'selected="selected"' ) : '', |
|
288
|
|
|
esc_attr( $value ), |
|
289
|
|
|
esc_html( $label ) |
|
290
|
1 |
|
); |
|
291
|
|
|
} |
|
292
|
1 |
|
?> |
|
293
|
|
|
</select> |
|
294
|
|
|
<button type="submit" name="filter_action" class="button"><?php esc_html_e( 'Filter', 'user-approval' ) ?></button> |
|
295
|
1 |
|
</div> |
|
296
|
1 |
|
<?php |
|
297
|
1 |
|
} |
|
298
|
1 |
|
|
|
299
|
1 |
|
/** |
|
300
|
|
|
* Filter user list in WP Admin filter by user status. |
|
301
|
1 |
|
* |
|
302
|
|
|
* @param array $args Arguments passed to WP_User_Query to retrieve items for the current |
|
303
|
|
|
* users list table. |
|
304
|
1 |
|
* |
|
305
|
1 |
|
* @return array |
|
306
|
1 |
|
*/ |
|
307
|
1 |
|
function filter_user_list_by_status( $args ) { |
|
308
|
1 |
|
|
|
309
|
1 |
|
$current_screen = get_current_screen(); |
|
|
|
|
|
|
310
|
1 |
|
|
|
311
|
|
|
$status = filter_input( INPUT_GET, 'user_status', FILTER_SANITIZE_STRING ); |
|
312
|
1 |
|
|
|
313
|
|
|
if ( |
|
314
|
1 |
|
! is_admin() |
|
315
|
1 |
|
|| empty( $current_screen ) |
|
316
|
|
|
|| 'users' !== $current_screen->id |
|
317
|
|
|
|| empty( $status ) |
|
318
|
|
|
|| is_array( get_user_status( $status ) ) |
|
319
|
1 |
|
) { |
|
320
|
|
|
return $args; |
|
321
|
|
|
} |
|
322
|
|
|
|
|
323
|
|
|
if ( in_array( $status, [ STATUS_APPROVED, STATUS_BLOCKED ], true ) ) { |
|
324
|
|
|
$args['meta_key'] = STATUS_META_KEY; // phpcs:ignore WordPress.VIP.SlowDBQuery.slow_db_query_meta_key |
|
325
|
|
|
$args['meta_value'] = $status; // phpcs:ignore WordPress.VIP.SlowDBQuery.slow_db_query_meta_value, WordPress.DB.SlowDBQuery.slow_db_query_meta_value |
|
326
|
|
|
} elseif ( STATUS_PENDING === $status ) { |
|
327
|
|
|
$args['role'] = get_default_user_role(); |
|
328
|
|
|
$args['meta_key'] = STATUS_META_KEY; // phpcs:ignore WordPress.VIP.SlowDBQuery.slow_db_query_meta_key |
|
329
|
|
|
$args['meta_compare'] = 'NOT EXISTS'; |
|
330
|
|
|
} else { |
|
331
|
|
|
$user_roles_data = get_pre_approved_user_roles(); |
|
332
|
|
|
|
|
333
|
|
|
if ( ! empty( $user_roles_data ) ) { |
|
334
|
|
|
$args['role__in'] = array_keys( $user_roles_data ); |
|
335
|
|
|
} |
|
336
|
|
|
} |
|
337
|
|
|
|
|
338
|
|
|
return $args; |
|
339
|
|
|
} |
|
340
|
|
|
|