PluginProbe
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI / 8.0.5
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI v8.0.5
8.0.5 8.0.4 8.0.3 8.0.1 8.0.2 8.0.0 7.9.9.7 7.9.9.6 7.9.9.5 7.9.9.4 7.9.9.3 7.9.9.2 7.9.9.1 7.9.9 7.9.8 7.9.7 7.9.6 7.9.5 7.9.4 7.9.3 7.9.2 7.9.1 7.9.0 7.8.9 7.8.8 All 47 releases
← All changes | includes/admin/tools/bulk-revokes.php +648 -0 7.9.1 → 8.0.5 View file →
@@ -1,0 +1,648 @@
1 +<?php
2 +/**
3 + * Bulk Revokes Tool
4 + *
5 + * @package GamiPress\Admin\Tools\Bulk_Revokes
6 + * @author GamiPress <[email protected]>, Ruben Garcia <[email protected]>
7 + * @since 1.4.3
8 + */
9 +// Exit if accessed directly
10 +if( !defined( 'ABSPATH' ) ) exit;
11 +
12 +/**
13 + * Register Bulk Revokes Tool meta boxes
14 + *
15 + * @since 1.4.3
16 + *
17 + * @param array $meta_boxes
18 + *
19 + * @return array
20 + */
21 +function gamipress_bulk_revokes_tool_meta_boxes( $meta_boxes ) {
22 +
23 + // Grab our points types as an array
24 + $points_types_options = array(
25 + '' => __( 'Choose a points type', 'gamipress' )
26 + );
27 +
28 + foreach( gamipress_get_points_types() as $slug => $data ) {
29 + $points_types_options[$slug] = $data['plural_name'];
30 + }
31 +
32 + // Grab our requirement types as an array
33 + $requirement_types_options = array(
34 + '' => __( 'Choose a requirement type', 'gamipress' )
35 + );
36 +
37 + foreach( gamipress_get_requirement_types() as $slug => $data ) {
38 + $requirement_types_options[$slug] = $data['singular_name'];
39 + }
40 +
41 + $meta_boxes['bulk-revokes'] = array(
42 + 'title' => gamipress_dashicon( 'no-alt' ) . __( 'Bulk Revokes', 'gamipress' ),
43 + 'fields' => apply_filters( 'gamipress_bulk_revokes_tool_fields', array(
44 +
45 + // Points
46 +
47 + 'bulk_revoke_points' => array(
48 + 'name' => __( 'Points to Deduct', 'gamipress' ),
49 + 'tooltip' => __( 'Points amount to deduct (the amount will be deducted to the current user balance).', 'gamipress' ),
50 + 'label_cb' => 'cmb_tooltip_label_cb',
51 + 'type' => 'text_small',
52 + 'default' => '0',
53 + ),
54 + 'bulk_revoke_points_type' => array(
55 + 'name' => __( 'Points Type', 'gamipress' ),
56 + 'tooltip' => __( 'Points type of points amount to deduct.', 'gamipress' ),
57 + 'label_cb' => 'cmb_tooltip_label_cb',
58 + 'type' => 'select',
59 + 'options' => $points_types_options
60 + ),
61 + 'bulk_revoke_points_register_movement' => array(
62 + 'name' => __( 'Register on user earnings', 'gamipress' ),
63 + 'tooltip' => __( 'Check this option to register this balance movement on user earnings.', 'gamipress' ),
64 + 'label_cb' => 'cmb_tooltip_label_cb',
65 + 'type' => 'checkbox',
66 + 'classes' => 'gamipress-switch'
67 + ),
68 + 'bulk_revoke_points_earnings_text' => array(
69 + 'name' => __( 'Earning entry text', 'gamipress' ),
70 + 'tooltip' => __( 'Enter the line text to be displayed on user earnings.', 'gamipress' ),
71 + 'label_cb' => 'cmb_tooltip_label_cb',
72 + 'type' => 'text',
73 + 'show_if' => array( 'bulk_revoke_points_register_movement' => 'checked' ),
74 + 'classes_cb' => 'cmb_conditional_fields_classes_cb',
75 + 'default' => __( 'Manual balance adjustment', 'gamipress' ),
76 + ),
77 + 'bulk_revoke_points_all_users' => array(
78 + 'name' => __( 'Deduct to all users', 'gamipress' ),
79 + 'tooltip' => __( 'Check this option to deduct the points amount to all users.', 'gamipress' ),
80 + 'label_cb' => 'cmb_tooltip_label_cb',
81 + 'type' => 'checkbox',
82 + 'classes' => 'gamipress-switch'
83 + ),
84 + 'bulk_revoke_points_users' => array(
85 + 'name' => __( 'Users to deduct', 'gamipress' ),
86 + 'tooltip' => __( 'Choose users to deduct this points amount.', 'gamipress' ),
87 + 'label_cb' => 'cmb_tooltip_label_cb',
88 + 'type' => 'advanced_select',
89 + 'multiple' => true,
90 + 'custom_classes' => 'gamipress-user-selector',
91 + 'attributes' => array(
92 + 'data-placeholder' => __( 'Choose users(s)', 'gamipress' ),
93 + 'data-close-on-select' => 'false',
94 + ),
95 + 'options_cb' => 'gamipress_options_cb_users',
96 + 'hide_if' => array( 'bulk_revoke_points_all_users' => 'checked' ),
97 + 'classes_cb' => 'cmb_conditional_fields_classes_cb',
98 + ),
99 + 'bulk_revoke_points_roles' => array(
100 + 'name' => __( 'Roles to deduct', 'gamipress' ),
101 + 'tooltip' => __( 'Choose roles to deduct this points amount.', 'gamipress' ),
102 + 'label_cb' => 'cmb_tooltip_label_cb',
103 + 'type' => 'advanced_select',
104 + 'multiple' => true,
105 + 'custom_classes' => 'gamipress-selector',
106 + 'attributes' => array(
107 + 'data-placeholder' => __( 'Choose role(s)', 'gamipress' ),
108 + 'data-close-on-select' => 'false',
109 + ),
110 + 'options_cb' => 'gamipress_options_cb_roles',
111 + 'hide_if' => array( 'bulk_revoke_points_all_users' => 'checked' ),
112 + 'classes_cb' => 'cmb_conditional_fields_classes_cb',
113 + ),
114 + 'bulk_revoke_points_button' => array(
115 + 'label' => __( 'Deduct Points', 'gamipress' ),
116 + 'type' => 'button',
117 + 'button' => 'primary'
118 + ),
119 +
120 + // Achievements
121 +
122 + 'bulk_revoke_achievements' => array(
123 + 'name' => __( 'Achievements to Revoke', 'gamipress' ),
124 + 'tooltip' => __( 'Choose the achievements to revoke.', 'gamipress' ),
125 + 'label_cb' => 'cmb_tooltip_label_cb',
126 + 'type' => 'advanced_select',
127 + 'multiple' => true,
128 + 'classes' => 'gamipress-post-selector',
129 + 'attributes' => array(
130 + 'data-post-type' => implode( ',', gamipress_get_achievement_types_slugs() ),
131 + 'data-placeholder' => __( 'Choose achievement(s)', 'gamipress' ),
132 + 'data-close-on-select' => 'false',
133 + ),
134 + 'options_cb' => 'gamipress_options_cb_posts',
135 + ),
136 + 'bulk_revoke_achievements_all_users' => array(
137 + 'name' => __( 'Revoke to all users', 'gamipress' ),
138 + 'tooltip' => __( 'Check this option to revoke the achievements to all users.', 'gamipress' ),
139 + 'label_cb' => 'cmb_tooltip_label_cb',
140 + 'type' => 'checkbox',
141 + 'classes' => 'gamipress-switch'
142 + ),
143 + 'bulk_revoke_achievements_users' => array(
144 + 'name' => __( 'Users to revoke', 'gamipress' ),
145 + 'tooltip' => __( 'Choose users to revoke this achievements.', 'gamipress' ),
146 + 'label_cb' => 'cmb_tooltip_label_cb',
147 + 'type' => 'advanced_select',
148 + 'multiple' => true,
149 + 'custom_classes' => 'gamipress-user-selector',
150 + 'attributes' => array(
151 + 'data-placeholder' => __( 'Choose users(s)', 'gamipress' ),
152 + 'data-close-on-select' => 'false',
153 + ),
154 + 'options_cb' => 'gamipress_options_cb_users',
155 + 'hide_if' => array( 'bulk_revoke_achievements_all_users' => 'checked' ),
156 + 'classes_cb' => 'cmb_conditional_fields_classes_cb',
157 + ),
158 + 'bulk_revoke_achievements_roles' => array(
159 + 'name' => __( 'Roles to revoke', 'gamipress' ),
160 + 'tooltip' => __( 'Choose roles to revoke this achievements.', 'gamipress' ),
161 + 'label_cb' => 'cmb_tooltip_label_cb',
162 + 'type' => 'advanced_select',
163 + 'multiple' => true,
164 + 'custom_classes' => 'gamipress-selector',
165 + 'attributes' => array(
166 + 'data-placeholder' => __( 'Choose role(s)', 'gamipress' ),
167 + 'data-close-on-select' => 'false',
168 + ),
169 + 'options_cb' => 'gamipress_options_cb_roles',
170 + 'hide_if' => array( 'bulk_revoke_achievements_all_users' => 'checked' ),
171 + 'classes_cb' => 'cmb_conditional_fields_classes_cb',
172 + ),
173 + 'bulk_revoke_achievements_button' => array(
174 + 'label' => __( 'Revoke Achievements', 'gamipress' ),
175 + 'type' => 'button',
176 + 'button' => 'primary'
177 + ),
178 +
179 + // Ranks
180 +
181 + 'bulk_revoke_rank' => array(
182 + 'name' => __( 'Rank to Revoke', 'gamipress' ),
183 + 'tooltip' => __( 'Choose the rank to revoke.', 'gamipress' ),
184 + 'label_cb' => 'cmb_tooltip_label_cb',
185 + 'desc' => __( '<strong>Important!</strong> Users on higher rank will be downgrade to this rank.', 'gamipress' ),
186 + 'type' => 'advanced_select',
187 + 'classes' => 'gamipress-post-selector',
188 + 'attributes' => array(
189 + 'data-post-type' => implode( ',', gamipress_get_rank_types_slugs() ),
190 + 'data-placeholder' => __( 'Choose rank', 'gamipress' ),
191 + ),
192 + 'options_cb' => 'gamipress_options_cb_posts',
193 + ),
194 + 'bulk_revoke_rank_all_users' => array(
195 + 'name' => __( 'Revoke to all users', 'gamipress' ),
196 + 'tooltip' => __( 'Check this option to revoke the rank to all users.', 'gamipress' ),
197 + 'label_cb' => 'cmb_tooltip_label_cb',
198 + 'type' => 'checkbox',
199 + 'classes' => 'gamipress-switch'
200 + ),
201 + 'bulk_revoke_rank_users' => array(
202 + 'name' => __( 'Users to revoke', 'gamipress' ),
203 + 'tooltip' => __( 'Choose users to revoke this rank.', 'gamipress' ),
204 + 'label_cb' => 'cmb_tooltip_label_cb',
205 + 'type' => 'advanced_select',
206 + 'multiple' => true,
207 + 'custom_classes' => 'gamipress-user-selector',
208 + 'attributes' => array(
209 + 'data-placeholder' => __( 'Choose users(s)', 'gamipress' ),
210 + 'data-close-on-select' => 'false',
211 + ),
212 + 'options_cb' => 'gamipress_options_cb_users',
213 + 'hide_if' => array( 'bulk_revoke_rank_all_users' => 'checked' ),
214 + 'classes_cb' => 'cmb_conditional_fields_classes_cb',
215 + ),
216 + 'bulk_revoke_rank_roles' => array(
217 + 'name' => __( 'Roles to revoke', 'gamipress' ),
218 + 'tooltip' => __( 'Choose roles to revoke this rank.', 'gamipress' ),
219 + 'label_cb' => 'cmb_tooltip_label_cb',
220 + 'type' => 'advanced_select',
221 + 'multiple' => true,
222 + 'custom_classes' => 'gamipress-selector',
223 + 'attributes' => array(
224 + 'data-placeholder' => __( 'Choose role(s)', 'gamipress' ),
225 + 'data-close-on-select' => 'false',
226 + ),
227 + 'options_cb' => 'gamipress_options_cb_roles',
228 + 'hide_if' => array( 'bulk_revoke_rank_all_users' => 'checked' ),
229 + 'classes_cb' => 'cmb_conditional_fields_classes_cb',
230 + ),
231 + 'bulk_revoke_rank_button' => array(
232 + 'label' => __( 'Revoke Rank', 'gamipress' ),
233 + 'type' => 'button',
234 + 'button' => 'primary'
235 + ),
236 +
237 + // Requirements
238 +
239 + 'bulk_revoke_requirements_type' => array(
240 + 'name' => __( 'Requirement Type', 'gamipress' ),
241 + 'tooltip' => __( 'Choose the requirement type to revoke.', 'gamipress' ),
242 + 'label_cb' => 'cmb_tooltip_label_cb',
243 + 'type' => 'select',
244 + 'options' => $requirement_types_options,
245 + ),
246 + 'bulk_revoke_requirements' => array(
247 + 'name' => __( 'Requirements to Award', 'gamipress' ),
248 + 'tooltip' => __( 'Choose the requirements to revoke.', 'gamipress' ),
249 + 'label_cb' => 'cmb_tooltip_label_cb',
250 + 'type' => 'advanced_select',
251 + 'multiple' => true,
252 + 'custom_classes' => 'gamipress-post-selector',
253 + 'attributes' => array(
254 + 'data-action' => 'gamipress_get_requirements',
255 + 'data-post-type' => implode( ',', gamipress_get_requirement_types_slugs() ),
256 + 'data-placeholder' => __( 'Choose requirement(s)', 'gamipress' ),
257 + 'data-close-on-select' => 'false',
258 + ),
259 + 'options_cb' => 'gamipress_options_cb_posts',
260 + 'hide_if' => array( 'bulk_revoke_requirements_type' => '' ),
261 + 'classes_cb' => 'cmb_conditional_fields_classes_cb',
262 + ),
263 + 'bulk_revoke_requirements_all_users' => array(
264 + 'name' => __( 'Award to all users', 'gamipress' ),
265 + 'tooltip' => __( 'Check this option to revoke the requirements to all users.', 'gamipress' ),
266 + 'label_cb' => 'cmb_tooltip_label_cb',
267 + 'type' => 'checkbox',
268 + 'classes' => 'gamipress-switch'
269 + ),
270 + 'bulk_revoke_requirements_users' => array(
271 + 'name' => __( 'Users to revoke', 'gamipress' ),
272 + 'tooltip' => __( 'Choose users to revoke this requirements.', 'gamipress' ),
273 + 'label_cb' => 'cmb_tooltip_label_cb',
274 + 'type' => 'advanced_select',
275 + 'multiple' => true,
276 + 'custom_classes' => 'gamipress-user-selector',
277 + 'attributes' => array(
278 + 'data-placeholder' => __( 'Choose users(s)', 'gamipress' ),
279 + 'data-close-on-select' => 'false',
280 + ),
281 + 'options_cb' => 'gamipress_options_cb_users',
282 + 'hide_if' => array( 'bulk_revoke_requirements_all_users' => 'checked' ),
283 + 'classes_cb' => 'cmb_conditional_fields_classes_cb',
284 + ),
285 + 'bulk_revoke_requirements_roles' => array(
286 + 'name' => __( 'Roles to revoke', 'gamipress' ),
287 + 'tooltip' => __( 'Choose roles to revoke this requirements.', 'gamipress' ),
288 + 'label_cb' => 'cmb_tooltip_label_cb',
289 + 'type' => 'advanced_select',
290 + 'multiple' => true,
291 + 'custom_classes' => 'gamipress-selector',
292 + 'attributes' => array(
293 + 'data-placeholder' => __( 'Choose role(s)', 'gamipress' ),
294 + 'data-close-on-select' => 'false',
295 + ),
296 + 'options_cb' => 'gamipress_options_cb_roles',
297 + 'hide_if' => array( 'bulk_revoke_requirements_all_users' => 'checked' ),
298 + 'classes_cb' => 'cmb_conditional_fields_classes_cb',
299 + ),
300 + 'bulk_revoke_requirements_button' => array(
301 + 'label' => __( 'Award Requirements', 'gamipress' ),
302 + 'type' => 'button',
303 + 'button' => 'primary'
304 + ),
305 + ) ),
306 + 'vertical_tabs' => true,
307 + 'tabs' => apply_filters( 'gamipress_bulk_revokes_tool_tabs', array(
308 + 'bulk_revoke_points' => array(
309 + 'icon' => 'dashicons-star-filled',
310 + 'title' => __( 'Points', 'gamipress' ),
311 + 'fields' => array(
312 + 'bulk_revoke_points',
313 + 'bulk_revoke_points_type',
314 + 'bulk_revoke_points_register_movement',
315 + 'bulk_revoke_points_earnings_text',
316 + 'bulk_revoke_points_all_users',
317 + 'bulk_revoke_points_users',
318 + 'bulk_revoke_points_roles',
319 + 'bulk_revoke_points_button',
320 + ),
321 + ),
322 + 'bulk_revoke_achievements' => array(
323 + 'icon' => 'dashicons-awards',
324 + 'title' => __( 'Achievements', 'gamipress' ),
325 + 'fields' => array(
326 + 'bulk_revoke_achievements',
327 + 'bulk_revoke_achievements_all_users',
328 + 'bulk_revoke_achievements_users',
329 + 'bulk_revoke_achievements_roles',
330 + 'bulk_revoke_achievements_button',
331 + ),
332 + ),
333 + 'bulk_revoke_rank' => array(
334 + 'icon' => 'dashicons-rank',
335 + 'title' => __( 'Ranks', 'gamipress' ),
336 + 'fields' => array(
337 + 'bulk_revoke_rank',
338 + 'bulk_revoke_rank_all_users',
339 + 'bulk_revoke_rank_users',
340 + 'bulk_revoke_rank_roles',
341 + 'bulk_revoke_rank_button',
342 + ),
343 + ),
344 + 'bulk_revoke_requirement' => array(
345 + 'icon' => 'dashicons-editor-ol',
346 + 'title' => __( 'Requirements', 'gamipress' ),
347 + 'fields' => array(
348 + 'bulk_revoke_requirements_type',
349 + 'bulk_revoke_requirements',
350 + 'bulk_revoke_requirements_all_users',
351 + 'bulk_revoke_requirements_users',
352 + 'bulk_revoke_requirements_roles',
353 + 'bulk_revoke_requirements_button',
354 + ),
355 + )
356 + ) )
357 + );
358 +
359 + return $meta_boxes;
360 +
361 +}
362 +add_filter( 'gamipress_tools_general_meta_boxes', 'gamipress_bulk_revokes_tool_meta_boxes' );
363 +
364 +/**
365 + * AJAX handler for the recount activity tool
366 + *
367 + * @since 1.4.3
368 + */
369 +function gamipress_ajax_bulk_revokes_tool() {
370 + // Security check, forces to die if not security passed
371 + check_ajax_referer( 'gamipress_admin', 'nonce' );
372 +
373 + global $wpdb;
374 +
375 + // Check user capabilities
376 + if( ! current_user_can( gamipress_get_manager_capability() ) )
377 + wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) );
378 +
379 + // Check parameters received
380 + if( ! isset( $_POST['bulk_revoke'] ) || empty( $_POST['bulk_revoke'] ) )
381 + wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) );
382 +
383 + $bulk_revoke = sanitize_text_field( $_POST['bulk_revoke'] );
384 + $loop = ( ! isset( $_POST['loop'] ) ? 0 : absint( $_POST['loop'] ) );
385 + $limit = 100;
386 + $offset = $limit * $loop;
387 + $run_again = false;
388 +
389 + ignore_user_abort( true );
390 +
391 + if ( ! gamipress_is_function_disabled( 'set_time_limit' ) )
392 + set_time_limit( 0 );
393 +
394 + $points_types = gamipress_get_points_types();
395 + $rank_types = gamipress_get_rank_types();
396 + $to_all_users = false;
397 + $specific_users = array();
398 + $specific_roles = array();
399 + $join = array();
400 + $where = array();
401 +
402 + if( $bulk_revoke === 'points' ) {
403 + // Check points parameters
404 +
405 + $points_to_revoke = absint( $_POST['bulk_revoke_points'] );
406 +
407 + if( $points_to_revoke === 0 ) {
408 + wp_send_json_error( __( 'Choose a valid points amount to deduct.', 'gamipress' ) );
409 + }
410 +
411 + $points_type_to_revoke = sanitize_text_field( $_POST['bulk_revoke_points_type'] );
412 +
413 + if( $points_type_to_revoke === '' || ! isset( $points_types[$points_type_to_revoke] ) ) {
414 + wp_send_json_error( __( 'Choose a valid points type.', 'gamipress' ) );
415 + }
416 +
417 + $to_all_users = isset( $_POST['bulk_revoke_points_all_users'] );
418 +
419 + if( ! $to_all_users ) {
420 + $specific_users = isset( $_POST['bulk_revoke_points_users'] ) ? $_POST['bulk_revoke_points_users'] : array();
421 + $specific_roles = isset( $_POST['bulk_revoke_points_roles'] ) ? $_POST['bulk_revoke_points_roles'] : array();
422 + }
423 +
424 + } else if( $bulk_revoke === 'achievements' ) {
425 + // Check achievements parameters
426 +
427 + $achievements = isset( $_POST['bulk_revoke_achievements'] ) ? $_POST['bulk_revoke_achievements'] : array();
428 +
429 + if( empty( $achievements ) ) {
430 + wp_send_json_error( __( 'Choose at least one achievement to be revoked.', 'gamipress' ) );
431 + }
432 +
433 + $to_all_users = isset( $_POST['bulk_revoke_achievements_all_users'] );
434 +
435 + if( ! $to_all_users ) {
436 + $specific_users = isset( $_POST['bulk_revoke_achievements_users'] ) ? $_POST['bulk_revoke_achievements_users'] : array();
437 + $specific_roles = isset( $_POST['bulk_revoke_achievements_roles'] ) ? $_POST['bulk_revoke_achievements_roles'] : array();
438 + }
439 +
440 + } else if( $bulk_revoke === 'rank' ) {
441 + // Check rank parameters
442 +
443 + $rank_id = absint( $_POST['bulk_revoke_rank'] );
444 +
445 + $rank = get_post( $rank_id );
446 +
447 + if( ! $rank || ! isset( $rank_types[$rank->post_type] ) ) {
448 + wp_send_json_error( __( 'Choose a valid rank to be revoked.', 'gamipress' ) );
449 + }
450 +
451 + $to_all_users = isset( $_POST['bulk_revoke_rank_all_users'] );
452 +
453 + if( ! $to_all_users ) {
454 + $specific_users = isset( $_POST['bulk_revoke_rank_users'] ) ? $_POST['bulk_revoke_rank_users'] : array();
455 + $specific_roles = isset( $_POST['bulk_revoke_rank_roles'] ) ? $_POST['bulk_revoke_rank_roles'] : array();
456 + }
457 +
458 + } else if( $bulk_revoke === 'requirements' ) {
459 + // Check requirements parameters
460 +
461 + $requirements = isset( $_POST['bulk_revoke_requirements'] ) ? $_POST['bulk_revoke_requirements'] : array();
462 +
463 + if( empty( $requirements ) ) {
464 + wp_send_json_error( __( 'Choose at least one requirement to be revoked.', 'gamipress' ) );
465 + }
466 +
467 + $to_all_users = isset( $_POST['bulk_revoke_requirements_all_users'] );
468 +
469 + if( ! $to_all_users ) {
470 + $specific_users = isset( $_POST['bulk_revoke_requirements_users'] ) ? $_POST['bulk_revoke_requirements_users'] : array();
471 + $specific_roles = isset( $_POST['bulk_revoke_requirements_roles'] ) ? $_POST['bulk_revoke_requirements_roles'] : array();
472 + }
473 +
474 + }
475 +
476 + // Ensure all specific users are correct
477 + foreach( $specific_users as $i => $specific_user ) {
478 + if( absint( $specific_user ) === 0 )
479 + unset( $specific_users[$i] );
480 + }
481 +
482 + // Ensure all specific roles are correct
483 + $editable_roles = get_editable_roles();
484 +
485 + foreach( $specific_roles as $i => $specific_role ) {
486 + if( ! isset( $editable_roles[$specific_role] ) )
487 + unset( $specific_roles[$i] );
488 + }
489 +
490 + // Check users parameters
491 + if( ! $to_all_users && empty( $specific_users ) && empty( $specific_roles ) )
492 + wp_send_json_error( __( 'Choose at least one user to revoke.', 'gamipress' ) );
493 +
494 + if( $to_all_users ) {
495 +
496 + // Get stored users
497 + $users = gamipress_get_users( array(
498 + 'offset' => $offset,
499 + 'limit' => $limit,
500 + ) );
501 +
502 + // Return a success message if finished, else run again
503 + if( empty( $users ) && $loop !== 0 ) {
504 + wp_send_json_success( __( 'Bulk revoke process has been done successfully.', 'gamipress' ) );
505 + } else {
506 + $run_again = true;
507 + }
508 +
509 + } else {
510 + // Get specific stored users
511 +
512 + // Setup specific users where
513 + if( ! empty( $specific_users ) && count( $specific_users ) > 0 ) {
514 +
515 + // Sanitize user IDs
516 + foreach ( $specific_users as $i => $user_id ) {
517 + $specific_users[$i] = absint( $user_id );
518 + }
519 +
520 + $where[] = "u.ID IN( " . implode( ', ', $specific_users ) . " )";
521 + }
522 +
523 + // Setup specific users join
524 + if( ! empty( $specific_roles ) && count( $specific_roles ) > 0 ) {
525 + // Setup join to the users meta table
526 + $join[] = "LEFT JOIN {$wpdb->usermeta} AS umcap ON ( umcap.user_id = u.ID AND umcap.meta_key = '" . $wpdb->get_blog_prefix() . "capabilities' )";
527 +
528 + foreach( $specific_roles as $role ) {
529 + $role = esc_sql( $role );
530 +
531 + $where[] = "umcap.meta_value LIKE '%\\\"{$role}\\\"%'";
532 + }
533 +
534 + }
535 +
536 + // Setup each query part
537 + $where = ( ! empty( $where ) ? "WHERE (" . implode( ') OR (', $where ) . ")" : '' );
538 + $join = ( ! empty( $join ) ? implode( ' ', $join ) : '' );
539 +
540 + $sql = "SELECT u.ID
541 + FROM {$wpdb->users} AS u
542 + {$join}
543 + {$where}
544 + ORDER BY u.ID ASC LIMIT {$offset}, {$limit}";
545 +
546 + $users = $wpdb->get_results( $sql );
547 +
548 + // Return a success message if finished, else run again
549 + if( empty( $users ) && $loop !== 0 ) {
550 + wp_send_json_success( __( 'Bulk revoke process has been done successfully.', 'gamipress' ) );
551 + } else {
552 + $run_again = true;
553 + }
554 + }
555 +
556 + if( empty( $users ) ) {
557 + wp_send_json_error( __( 'Could not find users to revoke.', 'gamipress' ) );
558 + }
559 +
560 + // Let's to bulk revoke
561 + foreach( $users as $user ) {
562 +
563 + if( $bulk_revoke === 'points' ) {
564 +
565 + // When an admin revokes points to user is required to set the total points balance
566 + $user_points = gamipress_get_user_points( $user->ID, $points_type_to_revoke );
567 +
568 + // Deduct points
569 + gamipress_deduct_points_to_user( $user->ID, $user_points - $points_to_revoke, $points_type_to_revoke, array( 'admin_id' => get_current_user_id() ) );
570 +
571 + $register_movement = isset( $_POST['bulk_revoke_points_register_movement'] ) ? true : false;
572 + $earnings_text = isset( $_POST['bulk_revoke_points_earnings_text'] ) ? stripslashes( sanitize_text_field( $_POST['bulk_revoke_points_earnings_text'] ) ) : '';
573 +
574 + if( $register_movement ) {
575 +
576 + // Insert the custom user earning for the manual balance adjustment
577 + gamipress_insert_user_earning( $user->ID, array(
578 + 'title' => $earnings_text,
579 + 'user_id' => $user->ID,
580 + 'post_id' => gamipress_get_points_type_id( $points_type_to_revoke ),
581 + 'post_type' => 'points-type',
582 + 'points' => $points_to_revoke * -1, // Insert as a negative value
583 + 'points_type' => $points_type_to_revoke,
584 + 'date' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ),
585 + ) );
586 +
587 + }
588 +
589 + } else if( $bulk_revoke === 'achievements' ) {
590 +
591 + // Revoke achievements
592 + foreach( $achievements as $achievement ) {
593 + gamipress_revoke_achievement_to_user( absint( $achievement ), $user->ID );
594 + }
595 +
596 + } else if( $bulk_revoke === 'rank' ) {
597 +
598 + $user_rank_id = gamipress_get_user_rank_id( $user->ID, $rank->post_type );
599 +
600 + if( $user_rank_id === $rank_id ) {
601 + // Revoke rank
602 + gamipress_revoke_rank_to_user( $user->ID, $rank_id, 0, array( 'admin_id' => get_current_user_id() ) );
603 + }
604 +
605 + } else if( $bulk_revoke === 'requirements' ) {
606 +
607 + // Revoke requirements
608 + foreach( $requirements as $requirement ) {
609 + gamipress_revoke_achievement_to_user( absint( $requirement ), $user->ID );
610 + }
611 +
612 + }
613 +
614 + }
615 +
616 + if( $run_again ) {
617 +
618 + $revoked_users = $limit * ( $loop + 1 );
619 +
620 + if( $to_all_users ) {
621 + // Get the users count
622 + $users_count = gamipress_get_users_count();
623 + } else {
624 + $users_count = absint( $wpdb->get_var(
625 + "SELECT COUNT(*)
626 + FROM {$wpdb->users} AS u
627 + {$join}
628 + {$where}
629 + ORDER BY u.ID ASC"
630 + ) );
631 + }
632 +
633 + $remaining_users = $users_count - $revoked_users;
634 +
635 + // Return a run again message (just when revoking to all users)
636 + wp_send_json_success( array(
637 + 'run_again' => $run_again,
638 + 'message' => sprintf( __( '%d remaining users', 'gamipress' ), ( $remaining_users > 0 ? $remaining_users : 0 ) ),
639 + ) );
640 +
641 + } else {
642 + // Return a success message
643 + wp_send_json_success( __( 'Bulk revoke process has been done successfully.', 'gamipress' ) );
644 + }
645 +
646 +
647 +}
648 +add_action( 'wp_ajax_gamipress_bulk_revokes_tool', 'gamipress_ajax_bulk_revokes_tool' );