Completed
Push — dev/6.0.0 ( ee7fd2...7ea4f4 )
by Sudar
12:00
created

UsersModule::delete_users_from_query()   C

Complexity

Conditions 7
Paths 12

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 7.0957

Importance

Changes 0
Metric Value
cc 7
eloc 15
nc 12
nop 2
dl 0
loc 28
ccs 14
cts 16
cp 0.875
crap 7.0957
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
namespace BulkWP\BulkDelete\Core\Users;
4
5
use BulkWP\BulkDelete\Core\Base\BaseModule;
6
7 1
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
 *
15
 * @since 5.5.2
16
 * @since 6.0.0 Renamed to UsersModule.
17
 */
18
abstract class UsersModule extends BaseModule {
19
	/**
20
	 * Build query params for WP_User_Query by using delete options.
21
	 *
22
	 * Return an empty query array to short-circuit deletion.
23
	 *
24
	 * @since 6.0.0
25
	 *
26
	 * @param array $options Delete options.
27
	 *
28
	 * @return array Query.
29
	 */
30
	abstract protected function build_query( $options );
31
32
	/**
33
	 * Handle common filters.
34
	 *
35
	 * @param array $request Request array.
36
	 *
37
	 * @return array User options.
38
	 */
39
	protected function parse_common_filters( $request ) {
40
		$options = array();
41
42
		$options['login_restrict'] = bd_array_get_bool( $request, "smbd_{$this->field_slug}_login_restrict", false );
43
		$options['login_days']     = absint( bd_array_get( $request, "smbd_{$this->field_slug}_login_days", 0 ) );
44
45
		$options['registered_restrict'] = bd_array_get_bool( $request, "smbd_{$this->field_slug}_registered_restrict", false );
46
		$options['registered_days']     = absint( bd_array_get( $request, "smbd_{$this->field_slug}_registered_days", 0 ) );
47
48
		$options['no_posts']            = bd_array_get_bool( $request, "smbd_{$this->field_slug}_no_posts", false );
49
		$options['no_posts_post_types'] = bd_array_get( $request, "smbd_{$this->field_slug}_no_post_post_types", array() );
0 ignored issues
show
Bug introduced by
array() of type array is incompatible with the type string expected by parameter $default of bd_array_get(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

49
		$options['no_posts_post_types'] = bd_array_get( $request, "smbd_{$this->field_slug}_no_post_post_types", /** @scrutinizer ignore-type */ array() );
Loading history...
50
51
		$options['limit_to'] = absint( bd_array_get( $request, "smbd_{$this->field_slug}_limit_to", 0 ) );
52
53
		return $options;
54
	}
55
56 8
	protected function do_delete( $options ) {
57 8
		$query = $this->build_query( $options );
58
59 8
		if ( empty( $query ) ) {
60
			// Short circuit deletion, if nothing needs to be deleted.
61
			return 0;
62
		}
63
64 8
		return $this->delete_users_from_query( $query, $options );
65
	}
66
67
	/**
68
	 * Query and Delete users.
69
	 *
70
	 * @since  5.5.2
71
	 * @access protected
72
	 *
73
	 * @param array $query   Options to query users.
74
	 * @param array $options Delete options.
75
	 *
76
	 * @return int Number of users who were deleted.
77
	 */
78 8
	protected function delete_users_from_query( $query, $options ) {
79 8
		$count = 0;
80 8
		$users = get_users( $query );
81
82 8
		if ( ! function_exists( 'wp_delete_user' ) ) {
83
			require_once ABSPATH . 'wp-admin/includes/user.php';
84
		}
85
86 8
		foreach ( $users as $user ) {
87 8
			if ( ! $this->can_delete_by_registered_date( $options, $user ) ) {
88 2
				continue;
89
			}
90
91 6
			if ( ! $this->can_delete_by_logged_date( $options, $user ) ) {
92
				continue;
93
			}
94
95 6
			if ( ! $this->can_delete_by_post_count( $options, $user ) ) {
96 2
				continue;
97
			}
98
99 6
			$deleted = wp_delete_user( $user->ID );
100 6
			if ( $deleted ) {
101 6
				$count ++;
102
			}
103
		}
104
105 8
		return $count;
106
	}
107
108
	/**
109
	 * Can the user be deleted based on the 'post count' option?
110
	 *
111
	 * @since  5.5.2
112
	 * @access protected
113
	 *
114
	 * @param array  $delete_options Delete Options.
115
	 * @param object $user           User object that needs to be deleted.
116
	 *
117
	 * @return bool True if the user can be deleted, false otherwise.
118
	 */
119 6
	protected function can_delete_by_post_count( $delete_options, $user ) {
120
		return ! (
121 6
			$delete_options['no_posts'] &&
122 6
			count_user_posts( $user->ID, $delete_options['no_posts_post_types'] ) > 0
123
		);
124
	}
125
126
	/**
127
	 * Can the user be deleted based on the 'registered date' option?
128
	 *
129
	 * @since  5.5.3
130
	 * @access protected
131
	 *
132
	 * @param array  $delete_options Delete Options.
133
	 * @param object $user           User object that needs to be deleted.
134
	 *
135
	 * @return bool True if the user can be deleted, false otherwise.
136
	 */
137 8
	protected function can_delete_by_registered_date( $delete_options, $user ) {
138 8
		if ( $delete_options['registered_restrict'] ) {
139 4
			$registered_days = $delete_options['registered_days'];
140
141 4
			if ( $registered_days > 0 ) {
142 4
				$user_meta = get_userdata( $user->ID );
143 4
				if ( strtotime( $user_meta->user_registered ) > strtotime( '-' . $registered_days . 'days' ) ) {
144 2
					return false;
145
				}
146
			}
147
		}
148
149 6
		return true;
150
	}
151
152
	/**
153
	 * Can the user be deleted based on the 'logged in date' option?
154
	 *
155
	 * @since  5.5.2
156
	 * @access protected
157
	 *
158
	 * @param array  $delete_options Delete Options.
159
	 * @param object $user           User object that needs to be deleted.
160
	 *
161
	 * @return bool True if the user can be deleted, false otherwise.
162
	 */
163 6
	protected function can_delete_by_logged_date( $delete_options, $user ) {
164 6
		if ( $delete_options['login_restrict'] ) {
165
			$login_days = $delete_options['login_days'];
166
			$last_login = bd_get_last_login( $user->ID );
167
168
			if ( null !== $last_login ) {
0 ignored issues
show
introduced by
The condition null !== $last_login is always true.
Loading history...
169
				// we have a logged-in entry for the user in simple login log plugin.
170
				if ( strtotime( $last_login ) > strtotime( '-' . $login_days . 'days' ) ) {
171
					return false;
172
				}
173
			} else {
174
				// we don't have a logged-in entry for the user in simple login log plugin.
175
				if ( $login_days > 0 ) {
176
					// non-zero value for login date. So don't delete this user.
177
					return false;
178
				}
179
			}
180
		}
181
182 6
		return true;
183
	}
184
185
	/**
186
	 * Process user delete form.
187
	 *
188
	 * Helper function to handle common delete user fields.
189
	 * Nonce verification is done in the hook that calls this function.
190
	 * phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification
191
	 *
192
	 * @since 5.5.3
193
	 * @access protected
194
	 *
195
	 * @param array $delete_options Delete Options.
196
	 */
197
	protected function process_user_delete( $delete_options ) {
0 ignored issues
show
Unused Code introduced by
The parameter $delete_options is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

197
	protected function process_user_delete( /** @scrutinizer ignore-unused */ $delete_options ) {

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

Loading history...
198
199
	} // phpcs:disable
200
201
	/**
202
	 * Render User Login restrict settings.
203
	 *
204
	 * @since 5.5
205
	 */
206
	protected function render_user_login_restrict_settings() {
207
?>
208
		<tr>
209
			<td scope="row" colspan="2">
210
			<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">
211
				<?php _e( 'Restrict to users who are registered in the site for at least ', 'bulk-delete' );?>
212
				<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" value="0" min="0" disabled> <?php _e( 'days.', 'bulk-delete' );?>
213
			</td>
214
		</tr>
215
216
		<?php
217
		if ( bd_is_simple_login_log_present() ) {
218
			$disabled = '';
219
		} else {
220
			$disabled = 'disabled';
221
		}
222
?>
223
		<tr>
224
			<td scope="row" colspan="2">
225
			<input name="smbd_<?php echo $this->field_slug; ?>_login_restrict" id="smbd_<?php echo $this->field_slug; ?>_login_restrict" value="true" type="checkbox" <?php echo $disabled; ?>>
226
				<?php _e( 'Restrict to users who have not logged in the last ', 'bulk-delete' );?>
227
				<input type="number" name="smbd_<?php echo $this->field_slug; ?>_login_days" id="smbd_<?php echo $this->field_slug; ?>_login_days" class="screen-per-page" value="0" min="0" disabled> <?php _e( 'days', 'bulk-delete' );?>.
228
		<?php if ( 'disabled' == $disabled ) { ?>
229
				<span style = "color:red">
230
					<?php _e( 'Need the free "Simple Login Log" Plugin', 'bulk-delete' ); ?> <a href = "http://wordpress.org/plugins/simple-login-log/">Install now</a>
231
				</span>
232
		<?php } ?>
233
			</td>
234
		</tr>
235
236
		<?php if ( bd_is_simple_login_log_present() ) : ?>
237
			<tr>
238
				<td scope="row" colspan="2">
239
					<?php _e( 'Enter "0 days" to delete users who have never logged in after the "Simple Login Log" plugin has been installed.', 'bulk-delete' ); ?>
240
			</tr>
241
		<?php endif; ?>
242
<?php
243
	}
244
245
	/**
246
	 * Render delete user with no posts settings.
247
	 *
248
	 * @since 5.5
249
	 */
250
	protected function render_user_with_no_posts_settings() {
251
	?>
252
		<tr>
253
			<td scope="row" colspan="2">
254
				<input type="checkbox" value="true"
255
				       name="smbd_<?php echo esc_attr( $this->field_slug ); ?>_no_posts"
256
				       id="smbd_<?php echo esc_attr( $this->field_slug ); ?>_no_posts" class="user_restrict_to_no_posts_filter">
257
258
				<?php _e( "Restrict to users who don't have any posts.", 'bulk-delete' ); ?>
259
			</td>
260
		</tr>
261
262
		<tr class="user_restrict_to_no_posts_filter_items visually-hidden">
263
			<td scope="row" colspan="2">
264
				<table class="filter-items">
265
					<tr>
266
						<td scope="row">
267
							<?php _e( 'Select the post types. By default all post types are considered.', 'bulk-delete' ); ?>
268
						</td>
269
					</tr>
270
271
					<?php $this->render_post_type_checkboxes( "smbd_{$this->field_slug}_no_post_post_types" ); ?>
272
				</table>
273
			</td>
274
		</tr>
275
276
	<?php
277
	}
278
279
	/**
280
	 * Render Post Types as checkboxes.
281
	 *
282
	 * @since 5.6.0
283
	 *
284
	 * @param $name Name of post type checkboxes.
0 ignored issues
show
Bug introduced by
The type BulkWP\BulkDelete\Core\Users\Name was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
285
	 */
286
	protected function render_post_type_checkboxes( $name ) {
287
		$post_types = bd_get_post_types();
288
		?>
289
290
		<?php foreach( $post_types as $post_type ) : ?>
291
292
		<tr>
293
			<td scope="row">
294
				<input type="checkbox" name="<?php echo esc_attr( $name ); ?>[]" value="<?php echo esc_attr( $post_type->name ); ?>"
295
					id="smbd_post_type_<?php echo esc_html( $post_type->name ); ?>" checked>
296
297
				<label for="smbd_post_type_<?php echo esc_html( $post_type->name ); ?>">
298
					<?php echo esc_html( $post_type->label ); ?>
299
				</label>
300
			</td>
301
		</tr>
302
303
		<?php endforeach; ?>
304
		<?php
305
	}
306
}
307