PluginProbe
Bulk Delete / trunk
Bulk Delete vtrunk
6.12 trunk 0.2 0.3 0.4 0.6 0.7 0.8 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.2.1 2.2.2 3.0 3.1 All 64 releases
bulk-delete / include / Core / Users / UsersModule.php

UsersModule.php in Bulk Delete trunk, at include/Core/Users/UsersModule.php

399 lines 11.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace BulkWP\BulkDelete\Core\Users;
4
5 use BulkWP\BulkDelete\Core\Base\BaseModule;
6
7 defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
8
9 /**
10 * Encapsulates the Bulk Delete User Meta box Module Logic.
11 * All Bulk Delete User Meta box Modules should extend this class.
12 *
13 * @see BaseModule
14 * @since 5.5.2
15 * @since 6.0.0 Renamed to UsersModule.
16 */
17 abstract class UsersModule extends BaseModule {
18 /**
19 * Build query params for WP_User_Query by using delete options.
20 *
21 * Return an empty query array to short-circuit deletion.
22 *
23 * @since 6.0.0
24 *
25 * @param array $options Delete options.
26 *
27 * @return array Query.
28 */
29 abstract protected function build_query( $options );
30
31 protected function parse_common_filters( $request ) {
32 $options = array();
33
34 $options['login_restrict'] = bd_array_get_bool( $request, "smbd_{$this->field_slug}_login_restrict", false );
35 $options['login_days'] = absint( bd_array_get( $request, "smbd_{$this->field_slug}_login_days", 0 ) );
36
37 $options['registered_restrict'] = bd_array_get_bool( $request, "smbd_{$this->field_slug}_registered_restrict", false );
38 $options['registered_date_op'] = bd_array_get( $request, 'smbd_' . $this->field_slug . '_op' );
39 $options['registered_days'] = absint( bd_array_get( $request, "smbd_{$this->field_slug}_registered_days", 0 ) );
40
41 $options['no_posts'] = bd_array_get_bool( $request, "smbd_{$this->field_slug}_no_posts", false );
42 $options['no_posts_post_types'] = bd_array_get( $request, "smbd_{$this->field_slug}_no_post_post_types", array() );
43
44 $options['reassign_user'] = bd_array_get_bool( $request, "smbd_{$this->field_slug}_post_reassign", false );
45 $options['reassign_user_id'] = absint( bd_array_get( $request, "smbd_{$this->field_slug}_reassign_user_id", 0 ) );
46 $options['limit_to'] = absint( bd_array_get( $request, "smbd_{$this->field_slug}_limit_to", 0 ) );
47
48 return $options;
49 }
50
51 protected function do_delete( $options ) {
52 $query = $this->build_query( $options );
53
54 if ( empty( $query ) ) {
55 // Short circuit deletion, if nothing needs to be deleted.
56 return 0;
57 }
58
59 $query = $this->exclude_users_from_deletion( $query );
60 $query = $this->exclude_current_user( $query );
61
62 return $this->delete_users_from_query( $query, $options );
63 }
64
65 /**
66 * Query and Delete users.
67 *
68 * @since 5.5.2
69 * @access protected
70 *
71 * @param array $query Options to query users.
72 * @param array $options Delete options.
73 *
74 * @return int Number of users who were deleted.
75 */
76 protected function delete_users_from_query( $query, $options ) {
77 $count = 0;
78 $users = $this->query_users( $query );
79
80 if ( ! function_exists( 'wp_delete_user' ) ) {
81 require_once ABSPATH . 'wp-admin/includes/user.php';
82 }
83
84 foreach ( $users as $user ) {
85 if ( ! $this->can_delete_by_logged_date( $options, $user ) ) {
86 continue;
87 }
88
89 if ( ! $this->can_delete_by_post_count( $options, $user ) ) {
90 continue;
91 }
92
93 /**
94 * Can a user be deleted.
95 *
96 * @since 6.0.0
97 *
98 * @param bool Can Delete the User. (Default true)
99 * @param \WP_User $user User Object of the user who is about to be deleted.
100 * @param array $options Delete options.
101 * @param \BulkWP\BulkDelete\Core\Base\BaseModule $this Module that is triggering deletion.
102 */
103 if ( ! apply_filters( 'bd_can_delete_user', true, $user, $options, $this ) ) { //phpcs:ignore
104 continue;
105 }
106
107 if ( isset( $options['reassign_user'] ) && $options['reassign_user'] ) {
108 $deleted = wp_delete_user( $user->ID, $options['reassign_user_id'] );
109 } else {
110 $deleted = wp_delete_user( $user->ID );
111 }
112
113 if ( $deleted ) {
114 $count ++;
115 }
116 }
117
118 return $count;
119 }
120
121 /**
122 * Query users using options.
123 *
124 * @param array $options Query options.
125 *
126 * @return \WP_User[] List of users.
127 */
128 protected function query_users( $options ) {
129 $defaults = array(
130 'count_total' => false,
131 );
132
133 $options = wp_parse_args( $options, $defaults );
134
135 $wp_user_query = new \WP_User_Query( $options );
136
137 /**
138 * This action before the query happens.
139 *
140 * @since 6.0.0
141 *
142 * @param \WP_User_Query $wp_user_query Query object.
143 */
144 do_action( 'bd_before_query', $wp_user_query ); //phpcs:ignore
145
146 $users = (array) $wp_user_query->get_results();
147
148 /**
149 * This action runs after the query happens.
150 *
151 * @since 6.0.0
152 *
153 * @param \WP_User_Query $wp_user_query Query object.
154 */
155 do_action( 'bd_after_query', $wp_user_query ); //phpcs:ignore
156
157 return $users;
158 }
159
160 /**
161 * Can the user be deleted based on the 'post count' option?
162 *
163 * This doesn't work well in batches.
164 *
165 * @link https://github.com/sudar/bulk-delete/issues/511 Github issue.
166 * @since 5.5.2
167 * @access protected
168 *
169 * @param array $delete_options Delete Options.
170 * @param \WP_User $user User object that needs to be deleted.
171 *
172 * @return bool True if the user can be deleted, false otherwise.
173 */
174 protected function can_delete_by_post_count( $delete_options, $user ) {
175 return ! (
176 $delete_options['no_posts'] &&
177 count_user_posts( $user->ID, $delete_options['no_posts_post_types'] ) > 0
178 );
179 }
180
181 /**
182 * Get the date query part for WP_User_Query.
183 *
184 * Date query corresponds to user registered date.
185 *
186 * @since 6.0.0
187 *
188 * @param array $options Delete options.
189 *
190 * @return array Date Query.
191 */
192 protected function get_date_query( $options ) {
193 if ( ! $options['registered_restrict'] ) {
194 return array();
195 }
196
197 if ( $options['registered_days'] <= 0 ) {
198 return array();
199 }
200
201 if ( ! isset( $options['registered_date_op'] ) ) {
202 return array(
203 'before' => $options['registered_days'] . ' days ago',
204 );
205 }
206
207 if ( 'before' === $options['registered_date_op'] || 'after' === $options['registered_date_op'] ) {
208 return array(
209 $options['registered_date_op'] => $options['registered_days'] . ' days ago',
210 );
211 }
212
213 return array();
214 }
215
216 /**
217 * Can the user be deleted based on the 'logged in date' option?
218 *
219 * This doesn't work well in batches.
220 *
221 * @link https://github.com/sudar/bulk-delete/issues/511 Github issue.
222 * @since 5.5.2
223 * @access protected
224 *
225 * @param array $delete_options Delete Options.
226 * @param \WP_User $user User object that needs to be deleted.
227 *
228 * @return bool True if the user can be deleted, false otherwise.
229 */
230 protected function can_delete_by_logged_date( $delete_options, $user ) {
231 if ( $delete_options['login_restrict'] ) {
232 $login_days = $delete_options['login_days'];
233 $last_login = bd_get_last_login( $user->ID );
234
235 if ( null !== $last_login ) {
236 // we have a logged-in entry for the user in simple login log plugin.
237 if ( strtotime( $last_login ) > strtotime( '-' . $login_days . 'days' ) ) {
238 return false;
239 }
240 } else {
241 // we don't have a logged-in entry for the user in simple login log plugin.
242 if ( $login_days > 0 ) {
243 // non-zero value for login date. So don't delete this user.
244 return false;
245 }
246 }
247 }
248
249 return true;
250 }
251
252 /**
253 * Render User Login restrict settings.
254 *
255 * @since 5.5
256 */
257 protected function render_user_login_restrict_settings() {
258 ?>
259 <tr>
260 <td scope="row" colspan="2">
261 <label for="smbd_<?php echo esc_attr( $this->field_slug ); ?>_registered_restrict">
262 <input name="smbd_<?php echo esc_attr( $this->field_slug ); ?>_registered_restrict" id="smbd_<?php echo esc_attr( $this->field_slug ); ?>_registered_restrict" value="true" type="checkbox">
263 <?php esc_html_e( 'Restrict to users who are registered in the site ', 'bulk-delete' ); ?>
264 </label>
265 <select name="smbd_<?php echo esc_attr( $this->field_slug ); ?>_op" id="smbd_<?php echo esc_attr( $this->field_slug ); ?>_op" disabled>
266 <option value="before"><?php esc_html_e( 'for at least', 'bulk-delete' ); ?></option>
267 <option value="after"><?php esc_html_e( 'in the last', 'bulk-delete' ); ?></option>
268 </select>
269 <input type="number" name="smbd_<?php echo esc_attr( $this->field_slug ); ?>_registered_days" id="smbd_<?php echo esc_attr( $this->field_slug ); ?>_registered_days" class="screen-per-page" disabled value="0" min="0"><?php esc_html_e( ' days.', 'bulk-delete' ); ?>
270 </td>
271 </tr>
272 <tr>
273 <td scope="row" colspan="2">
274 <label>
275 <input name="smbd_<?php echo esc_attr( $this->field_slug ); ?>_login_restrict" id="smbd_<?php echo esc_attr( $this->field_slug ); ?>_login_restrict"
276 value="true" type="checkbox" <?php disabled( false, bd_is_simple_login_log_present() ); ?>>
277 <?php esc_html_e( 'Restrict to users who have not logged in the last ', 'bulk-delete' ); ?>
278 </label>
279 <input type="number" name="smbd_<?php echo esc_attr( $this->field_slug ); ?>_login_days" id="smbd_<?php echo esc_attr( $this->field_slug ); ?>_login_days" class="screen-per-page" value="0" min="0" disabled> <?php esc_html_e( 'days', 'bulk-delete' ); ?>.
280
281 <?php if ( ! bd_is_simple_login_log_present() ) : ?>
282 <span style = "color:red">
283 <?php esc_html_e( 'Need the free "Simple Login Log" Plugin', 'bulk-delete' ); ?> <a href = "https://wordpress.org/plugins/simple-login-log/">Install now</a>
284 </span>
285 <?php endif; ?>
286 </td>
287 </tr>
288
289 <?php if ( bd_is_simple_login_log_present() ) : ?>
290 <tr>
291 <td scope="row" colspan="2">
292 <?php esc_html_e( 'Enter "0 days" to delete users who have never logged in after the "Simple Login Log" plugin has been installed.', 'bulk-delete' ); ?>
293 </tr>
294 <?php endif; ?>
295 <?php
296 }
297
298 /**
299 * Render delete user with no posts settings.
300 *
301 * @since 5.5
302 */
303 protected function render_user_with_no_posts_settings() {
304 ?>
305 <tr>
306 <td scope="row" colspan="2">
307 <input type="checkbox" value="true"
308 name="smbd_<?php echo esc_attr( $this->field_slug ); ?>_no_posts"
309 id="smbd_<?php echo esc_attr( $this->field_slug ); ?>_no_posts" class="user_restrict_to_no_posts_filter">
310 <label for="smbd_<?php echo esc_attr( $this->field_slug ); ?>_no_posts">
311 <?php esc_html_e( "Restrict to users who don't have any posts.", 'bulk-delete' ); ?>
312 </label>
313 </td>
314 </tr>
315
316 <tr class="user_restrict_to_no_posts_filter_items visually-hidden">
317 <td scope="row" colspan="2">
318 <table class="filter-items">
319 <tr>
320 <td scope="row">
321 <?php esc_html_e( 'Select the post types. By default all post types are considered.', 'bulk-delete' ); ?>
322 </td>
323 </tr>
324
325 <?php $this->render_post_type_checkboxes( "smbd_{$this->field_slug}_no_post_post_types" ); ?>
326 </table>
327 </td>
328 </tr>
329
330 <?php
331 }
332
333 /**
334 * Get unique user meta keys.
335 *
336 * @since 5.5
337 *
338 * @return array List of unique meta keys.
339 */
340 protected function get_unique_user_meta_keys() {
341 global $wpdb;
342
343 return $wpdb->get_col( "SELECT DISTINCT(meta_key) FROM {$wpdb->prefix}usermeta ORDER BY meta_key" ); //phpcs:ignore
344 }
345
346 /**
347 * Exclude current user from being deleted.
348 *
349 * @param array $query WP_User_Query args.
350 *
351 * @return array Modified query args.
352 */
353 protected function exclude_current_user( $query ) {
354 $current_user_id = get_current_user_id();
355
356 if ( $current_user_id <= 0 ) {
357 return $query;
358 }
359
360 if ( isset( $query['exclude'] ) ) {
361 $query['exclude'] = array_merge( $query['exclude'], array( $current_user_id ) );
362 } else {
363 $query['exclude'] = array( $current_user_id );
364 }
365
366 return $query;
367 }
368
369 /**
370 * Exclude users from deletion.
371 *
372 * @since 6.0.0
373 *
374 * @param array $query Pre-built query.
375 *
376 * @return array Modified query.
377 */
378 protected function exclude_users_from_deletion( array $query ) {
379 /**
380 * Filter the list of user ids that will be excluded from deletion.
381 *
382 * @since 6.0.0
383 *
384 * @param array $excluded_ids User IDs to be excluded during deletion.
385 */
386 $excluded_user_ids = apply_filters( 'bd_excluded_user_ids', array() ); //phpcs:ignore
387
388 if ( is_array( $excluded_user_ids ) && ! empty( $excluded_user_ids ) ) {
389 if ( isset( $query['exclude'] ) ) {
390 $query['exclude'] = array_merge( $query['exclude'], $excluded_user_ids );
391 } else {
392 $query['exclude'] = $excluded_user_ids;
393 }
394 }
395
396 return $query;
397 }
398 }
399