PluginProbe
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI / 7.9.8
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI v7.9.8
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 7.8.7 All 46 releases
gamipress / includes / shortcodes / gamipress_earnings.php

gamipress_earnings.php in GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI 7.9.8, at includes/shortcodes/gamipress_earnings.php

623 lines 23.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * GamiPress Earnings Shortcode
4 *
5 * @package GamiPress\Shortcodes\Shortcode\GamiPress_Earnings
6 * @author GamiPress <[email protected]>, Ruben Garcia <[email protected]>
7 * @since 1.3.9
8 */
9 // Exit if accessed directly
10 if( !defined( 'ABSPATH' ) ) exit;
11
12 /**
13 * Register [gamipress_earnings] shortcode
14 *
15 * @since 1.3.9
16 */
17 function gamipress_register_earnings_shortcode() {
18
19 gamipress_register_shortcode( 'gamipress_earnings', array(
20 'name' => __( 'User Earnings', 'gamipress' ),
21 'description' => __( 'Display a list of user earnings.', 'gamipress' ),
22 'group' => 'gamipress',
23 'output_callback' => 'gamipress_earnings_shortcode',
24 'tabs' => array(
25 'general' => array(
26 'icon' => 'dashicons-admin-generic',
27 'title' => __( 'General', 'gamipress' ),
28 'fields' => array(
29 'current_user',
30 'user_id',
31 'force_responsive',
32 'limit',
33 'pagination',
34 'order',
35 'include',
36 'exclude',
37 ),
38 ),
39 'points' => array(
40 'icon' => 'dashicons-star-filled',
41 'title' => __( 'Points', 'gamipress' ),
42 'fields' => array(
43 'points',
44 'points_types',
45 'awards',
46 'deducts'
47 ),
48 ),
49 'achievements' => array(
50 'icon' => 'dashicons-awards',
51 'title' => __( 'Achievements', 'gamipress' ),
52 'fields' => array(
53 'achievements',
54 'achievement_types',
55 'steps',
56 'achievements_without_points',
57 ),
58 ),
59 'ranks' => array(
60 'icon' => 'dashicons-rank',
61 'title' => __( 'Ranks', 'gamipress' ),
62 'fields' => array(
63 'ranks',
64 'rank_types',
65 'rank_requirements',
66 ),
67 ),
68 ),
69 'fields' => array(
70 'current_user' => array(
71 'name' => __( 'Current User', 'gamipress' ),
72 'tooltip' => __( 'Show only earned items of the current logged in user.', 'gamipress' ),
73 'label_cb' => 'cmb_tooltip_label_cb',
74 'type' => 'checkbox',
75 'classes' => 'gamipress-switch',
76 'default' => 'yes',
77 ),
78 'user_id' => array(
79 'name' => __( 'User', 'gamipress' ),
80 'tooltip' => __( 'Show only earned items by a specific user. Leave blank to show earned items of all users.', 'gamipress' ),
81 'label_cb' => 'cmb_tooltip_label_cb',
82 'type' => 'select',
83 'default' => '',
84 'options_cb' => 'gamipress_options_cb_users'
85 ),
86 'force_responsive' => array(
87 'name' => __( 'Force Responsive', 'gamipress' ),
88 'tooltip' => __( 'Force to display the earnings table with the responsive style.', 'gamipress' ),
89 'label_cb' => 'cmb_tooltip_label_cb',
90 'type' => 'checkbox',
91 'classes' => 'gamipress-switch',
92 ),
93 'limit' => array(
94 'name' => __( 'Limit', 'gamipress' ),
95 'tooltip' => __( 'Number of items to display.', 'gamipress' ),
96 'label_cb' => 'cmb_tooltip_label_cb',
97 'type' => 'text',
98 'default' => 10,
99 ),
100 'pagination' => array(
101 'name' => __( 'Enable Pagination', 'gamipress' ),
102 'tooltip' => __( 'Show pagination links to navigate through all earned items.', 'gamipress' ),
103 'label_cb' => 'cmb_tooltip_label_cb',
104 'type' => 'checkbox',
105 'classes' => 'gamipress-switch',
106 'default' => 'yes',
107 ),
108 'order' => array(
109 'name' => __( 'Order', 'gamipress' ),
110 'tooltip' => __( 'Sort order.', 'gamipress' ),
111 'label_cb' => 'cmb_tooltip_label_cb',
112 'type' => 'select',
113 'options' => array( 'DESC' => __( 'Newest', 'gamipress' ), 'ASC' => __( 'Older', 'gamipress' ) ),
114 'default' => 'DESC',
115 ),
116 'include' => array(
117 'name' => __( 'Include', 'gamipress' ),
118 'tooltip' => __( 'Comma-separated list of specific earnings IDs to include.', 'gamipress' ),
119 'label_cb' => 'cmb_tooltip_label_cb',
120 'type' => 'text',
121 ),
122 'exclude' => array(
123 'name' => __( 'Exclude', 'gamipress' ),
124 'tooltip' => __( 'Comma-separated list of specific earnings IDs to exclude.', 'gamipress' ),
125 'label_cb' => 'cmb_tooltip_label_cb',
126 'type' => 'text',
127 ),
128
129 // Points types
130
131 'points' => array(
132 'name' => __( 'Show Points', 'gamipress' ),
133 'tooltip' => __( 'Show points earned and deducted.', 'gamipress' ),
134 'label_cb' => 'cmb_tooltip_label_cb',
135 'type' => 'checkbox',
136 'classes' => 'gamipress-switch',
137 'default' => 'yes',
138 ),
139 'points_types' => array(
140 'name' => __( 'Points Type(s)', 'gamipress' ),
141 'tooltip' => __( 'Points type(s) to display.', 'gamipress' ),
142 'label_cb' => 'cmb_tooltip_label_cb',
143 'shortcode_desc' => __( 'Single or comma-separated list of points type(s) to display.', 'gamipress' ),
144 'type' => 'advanced_select',
145 'multiple' => true,
146 'classes' => 'gamipress-selector',
147 'attributes' => array(
148 'data-placeholder' => __( 'Default: All', 'gamipress' ),
149 ),
150 'options_cb' => 'gamipress_options_cb_points_types',
151 'default' => 'all',
152 ),
153 'awards' => array(
154 'name' => __( 'Show Points Awards', 'gamipress' ),
155 'tooltip' => __( 'Show points awarded.', 'gamipress' ),
156 'label_cb' => 'cmb_tooltip_label_cb',
157 'type' => 'checkbox',
158 'classes' => 'gamipress-switch',
159 'default' => 'yes',
160 ),
161 'deducts' => array(
162 'name' => __( 'Show Points Deductions', 'gamipress' ),
163 'tooltip' => __( 'Show points deducted.', 'gamipress' ),
164 'label_cb' => 'cmb_tooltip_label_cb',
165 'type' => 'checkbox',
166 'classes' => 'gamipress-switch',
167 'default' => 'yes',
168 ),
169
170 // Achievement types
171
172 'achievements' => array(
173 'name' => __( 'Show Achievements', 'gamipress' ),
174 'tooltip' => __( 'Show achievements earned.', 'gamipress' ),
175 'label_cb' => 'cmb_tooltip_label_cb',
176 'type' => 'checkbox',
177 'classes' => 'gamipress-switch',
178 'default' => 'yes',
179 ),
180 'achievement_types' => array(
181 'name' => __( 'Achievement Type(s)', 'gamipress' ),
182 'tooltip' => __( 'Achievements type(s) to display.', 'gamipress' ),
183 'label_cb' => 'cmb_tooltip_label_cb',
184 'shortcode_desc' => __( 'Single or comma-separated list of achievements type(s) to display.', 'gamipress' ),
185 'type' => 'advanced_select',
186 'multiple' => true,
187 'classes' => 'gamipress-selector',
188 'attributes' => array(
189 'data-placeholder' => __( 'Default: All', 'gamipress' ),
190 ),
191 'options_cb' => 'gamipress_options_cb_achievement_types',
192 'default' => 'all',
193 ),
194 'steps' => array(
195 'name' => __( 'Show Steps', 'gamipress' ),
196 'tooltip' => __( 'Show steps completed.', 'gamipress' ),
197 'label_cb' => 'cmb_tooltip_label_cb',
198 'type' => 'checkbox',
199 'classes' => 'gamipress-switch',
200 'default' => 'yes',
201 ),
202 'achievements_without_points' => array(
203 'name' => __( 'Show Achievements Without Points', 'gamipress' ),
204 'tooltip' => __( 'Show achievements that do not award points.', 'gamipress' ),
205 'label_cb' => 'cmb_tooltip_label_cb',
206 'type' => 'checkbox',
207 'classes' => 'gamipress-switch',
208 'default' => 'yes',
209 ),
210
211 // Rank types
212
213 'ranks' => array(
214 'name' => __( 'Show Ranks', 'gamipress' ),
215 'tooltip' => __( 'Show ranks reached.', 'gamipress' ),
216 'label_cb' => 'cmb_tooltip_label_cb',
217 'type' => 'checkbox',
218 'classes' => 'gamipress-switch',
219 'default' => 'yes',
220 ),
221 'rank_types' => array(
222 'name' => __( 'Rank Type(s)', 'gamipress' ),
223 'tooltip' => __( 'Ranks type(s) to display.', 'gamipress' ),
224 'label_cb' => 'cmb_tooltip_label_cb',
225 'shortcode_desc' => __( 'Single or comma-separated list of ranks type(s) to display.', 'gamipress' ),
226 'type' => 'advanced_select',
227 'multiple' => true,
228 'classes' => 'gamipress-selector',
229 'attributes' => array(
230 'data-placeholder' => __( 'Default: All', 'gamipress' ),
231 ),
232 'options_cb' => 'gamipress_options_cb_rank_types',
233 'default' => 'all',
234 ),
235 'rank_requirements' => array(
236 'name' => __( 'Show Rank Requirements', 'gamipress' ),
237 'tooltip' => __( 'Show rank requirements completed.', 'gamipress' ),
238 'label_cb' => 'cmb_tooltip_label_cb',
239 'type' => 'checkbox',
240 'classes' => 'gamipress-switch',
241 'default' => 'yes',
242 ),
243 ),
244 ) );
245
246 }
247 add_action( 'init', 'gamipress_register_earnings_shortcode' );
248
249 /**
250 * User Earnings Shortcode
251 *
252 * @since 1.3.9
253 *
254 * @param array $atts Shortcode attributes
255 * @param string $content Shortcode content
256 *
257 * @return string HTML markup
258 */
259 function gamipress_earnings_shortcode( $atts = array(), $content = '' ) {
260
261 global $gamipress_template_args;
262
263 // Initialize GamiPress template args global
264 $gamipress_template_args = array();
265
266 $shortcode = 'gamipress_earnings';
267
268 $atts = shortcode_atts( gamipress_earnings_shortcode_defaults(), $atts, $shortcode );
269
270 gamipress_enqueue_scripts();
271
272 // On network wide active installs, we need to switch to main blog mostly for posts permalinks and thumbnails
273 $blog_id = gamipress_switch_to_main_site_if_network_wide_active();
274
275 // Force to set current user as user ID
276 if( $atts['current_user'] === 'yes' ) {
277
278 /**
279 * Filter to override shortcode workflow with not logged in users when current user is set to yes
280 *
281 * @since 1.7.4.2
282 *
283 * @param bool $empty_if_not_logged_in Final workflow to follow
284 * @param array $atts Shortcode attributes
285 * @param string $content Shortcode content
286 */
287 $empty_if_not_logged_in = apply_filters( 'gamipress_earnings_shortcode_empty_if_not_logged_in', true, $atts, $content );
288
289 // Return if current_user is set to yes and current user is a guest
290 if( get_current_user_id() === 0 && $empty_if_not_logged_in )
291 return '';
292
293 $atts['user_id'] = get_current_user_id();
294
295 }
296
297 // GamiPress template args global
298 $gamipress_template_args = $atts;
299
300 // Earnings query
301 $gamipress_template_args['query'] = gamipress_earnings_shortcode_query( $atts );
302
303 if( ! $gamipress_template_args['query'] ) {
304 return '';
305 }
306
307 // Earnings columns
308 $gamipress_template_args['columns'] = array();
309
310 if( absint( $atts['user_id'] ) === 0 ) {
311 $gamipress_template_args['columns']['user'] = __( 'User', 'gamipress' );
312 }
313
314 $gamipress_template_args['columns']['thumbnail'] = __( 'Thumbnail', 'gamipress' );
315 $gamipress_template_args['columns']['description'] = __( 'Description', 'gamipress' );
316 $gamipress_template_args['columns']['date'] = __( 'Date', 'gamipress' );
317 $gamipress_template_args['columns']['points'] = __( 'Points', 'gamipress' );
318
319 // Render the earnings template
320 ob_start();
321 gamipress_get_template_part( 'earnings' );
322 $output = ob_get_clean();
323
324 // If switched to blog, return back to que current blog
325 if( $blog_id !== get_current_blog_id() && is_multisite() ) {
326 restore_current_blog();
327 }
328
329 /**
330 * Filter to override shortcode output
331 *
332 * @since 1.6.5
333 *
334 * @param string $output Final output
335 * @param array $atts Shortcode attributes
336 * @param string $content Shortcode content
337 */
338 return apply_filters( 'gamipress_earnings_shortcode_output', $output, $atts, $content );
339
340 }
341
342 /**
343 * User Earnings Shortcode Query
344 *
345 * @since 1.4.9
346 *
347 * @param array $args Query arguments
348 *
349 * @return CT_Query
350 */
351 function gamipress_earnings_shortcode_query( $args = array () ) {
352
353 // Query args
354 $query_args = array(
355 'orderby' => 'date',
356 'order' => $args['order'],
357 'items_per_page' => $args['limit'],
358 'paged' => max( 1, get_query_var( 'paged' ) )
359 );
360
361 $query_args['post_type'] = array();
362 $query_args['points_type'] = array();
363 $query_args['post_type__not_in'] = array();
364 $query_args['parent_post_type'] = array();
365
366 // User
367 if( isset( $args['user_id'] ) && absint( $args['user_id'] ) !== 0 ) {
368 $query_args['user_id'] = $args['user_id'];
369 }
370
371 // Build $include array
372 if ( ! is_array( $args['include'] ) && ! empty( $args['include'] ) ) {
373 $include = explode( ',', $args['include'] );
374 }
375
376 // Build $exclude array
377 if ( ! is_array( $args['exclude'] ) && ! empty( $args['exclude'] ) ) {
378 $exclude = explode( ',', $args['exclude'] );
379 }
380
381 // Include certain user earnings
382 if ( isset( $include ) && ! empty( $include ) ) {
383 $query_args[ 'user_earning__in' ] = $include;
384 }
385
386 // Exclude certain user earnings
387 if ( isset( $exclude ) && ! empty( $exclude ) ) {
388 $query_args[ 'user_earning__not_in' ] = $exclude;
389 }
390
391 // Points types
392 if( $args['points'] === 'yes' ) {
393
394 if( $args['points_types'] === 'all') {
395 $query_args['points_type'] = gamipress_get_points_types_slugs();
396 } else {
397 $point_types = explode( ',', $args['points_types'] );
398 $query_args['points_type'] = gamipress_sanitize_point_types_slugs_array( $point_types );
399 }
400
401 // For custom earnings points to the points type
402 $query_args['post_type'][] = 'points-type';
403
404 // Points awards
405 if( $args['awards'] === 'yes' ) {
406 $query_args['post_type'][] = 'points-award';
407 } else {
408 $query_args['post_type__not_in'][] = 'points-award';
409 }
410
411 // Points deducts
412 if( $args['deducts'] === 'yes' ) {
413 $query_args['post_type'][] = 'points-deduct';
414 } else {
415 $query_args['post_type__not_in'][] = 'points-deduct';
416 }
417
418 } else {
419 $query_args['post_type__not_in'][] = 'points-type';
420 $query_args['post_type__not_in'][] = 'points-award';
421 $query_args['post_type__not_in'][] = 'points-deduct';
422 }
423
424 // Achievement types
425 if( $args['achievements'] === 'yes' ) {
426
427 if( $args['achievement_types'] === 'all') {
428 $achievement_types = gamipress_get_achievement_types_slugs();
429 } else {
430 $achievement_types = explode( ',', $args['achievement_types'] );
431 $achievement_types = gamipress_sanitize_achievement_types_slugs_array( $achievement_types );
432 }
433 $query_args['post_type'] = array_merge( $query_args['post_type'], $achievement_types );
434
435 // Step
436 if( $args['steps'] === 'yes' ) {
437 if( $args['achievement_types'] === 'all') {
438 $query_args['post_type'][] = 'step';
439 } else {
440 $query_args['parent_post_type'] = array_merge( $query_args['parent_post_type'], $achievement_types );
441 }
442 } else {
443 $query_args['post_type__not_in'][] = 'step';
444 }
445
446 } else {
447 $query_args['post_type__not_in'] = array_merge( $query_args['post_type__not_in'], gamipress_get_achievement_types_slugs() );
448 $query_args['post_type__not_in'][] = 'step';
449 }
450
451 // Rank types
452 if( $args['ranks'] === 'yes' ) {
453
454 if( $args['rank_types'] === 'all') {
455 $rank_types = gamipress_get_rank_types_slugs();
456 } else {
457 $rank_types = explode( ',', $args['rank_types'] );
458 $rank_types = gamipress_sanitize_rank_types_slugs_array( $rank_types );
459 }
460
461 $query_args['post_type'] = array_merge( $query_args['post_type'], $rank_types );
462
463 // Rank requirements
464 if( $args['rank_requirements'] === 'yes' ) {
465 if( $args['rank_types'] === 'all') {
466 $query_args['post_type'][] = 'rank-requirement';
467 } else {
468 $query_args['parent_post_type'] = array_merge( $query_args['parent_post_type'], $rank_types );
469 }
470 } else {
471 $query_args['post_type__not_in'][] = 'rank-requirement';
472 }
473
474 } else {
475 $query_args['post_type__not_in'] = array_merge( $query_args['post_type__not_in'], gamipress_get_rank_types_slugs() );
476 $query_args['post_type__not_in'][] = 'rank-requirement';
477 }
478
479 // Remove types that has 'all' value
480 foreach( $query_args['post_type'] as $index => $type ) {
481 if( $type === 'all' ) {
482 unset( $query_args['post_type'][$index] );
483 }
484 }
485
486 // Return if not types selected
487 if( empty( $query_args['post_type'] ) ) {
488 return false;
489 }
490
491 if( ! empty( $query_args['points_type'] ) ) {
492 $query_args['force_types'] = true;
493 }
494
495 // If looking to show achievements that do not award any points, then need to add the empty points type value and force the post and points types queries
496 if( $args['achievements_without_points'] === 'yes' ) {
497 $query_args['points_type'][] = '';
498 $query_args['force_types'] = true;
499 }
500
501 /**
502 * Filters earnings shortcode query args
503 *
504 * @since 2.0.7
505 *
506 * @param array $query_args Query args to be passed to CT_Query
507 * @param array $args Function received args
508 *
509 * @return array
510 */
511 $query_args = apply_filters( 'gamipress_earnings_shortcode_query_args', $query_args, $args );
512
513 // Setup table
514 $ct_table = ct_setup_table( 'gamipress_user_earnings' );
515
516 // Sanitize query args
517 $query_args = gamipress_sanitize_query_args( $query_args, gamipress_user_earnings_query_vars_rules() );
518
519 return new CT_Query( $query_args );
520
521 }
522
523 /**
524 * Earnings shortcode defaults attributes values
525 *
526 * @since 7.1.6
527 *
528 * @return array
529 */
530 function gamipress_earnings_shortcode_defaults() {
531
532 return apply_filters( 'gamipress_earnings_shortcode_defaults', array(
533 'current_user' => 'yes',
534 'user_id' => '0',
535 'force_responsive' => '',
536 'limit' => '10',
537 'pagination' => 'yes',
538 'order' => 'DESC',
539 'include' => '',
540 'exclude' => '',
541 'points' => 'yes',
542 'points_types' => 'all',
543 'awards' => 'yes',
544 'deducts' => 'yes',
545 'achievements' => 'yes',
546 'achievement_types' => 'all',
547 'steps' => 'yes',
548 'achievements_without_points' => 'yes',
549 'ranks' => 'yes',
550 'rank_types' => 'all',
551 'rank_requirements' => 'yes',
552 ) );
553
554 }
555
556 /**
557 * User Earnings query vars rules
558 *
559 * @since 7.8.8
560 *
561 * @return array
562 */
563 function gamipress_user_earnings_query_vars_rules() {
564
565 // Setup table
566 $ct_table = ct_setup_table( 'gamipress_user_earnings' );
567
568 $rules = apply_filters( 'gamipress_user_earnings_query_vars_rules', array(
569 // Query fields
570 'orderby' => array(
571 'type' => 'string',
572 'sanitize' => 'text',
573 'allowed_values' => array_keys( $ct_table->db->schema->fields ),
574 ),
575 'order' => array(
576 'type' => 'string',
577 'sanitize' => 'uppercase',
578 'allowed_values' => array( 'ASC', 'DESC' ),
579 ),
580 'items_per_page' => array(
581 'type' => 'integer',
582 ),
583 'paged' => array(
584 'type' => 'integer',
585 ),
586 // Earning fields
587 'user_id' => array(
588 'type' => 'integer',
589 ),
590 'user_earning__in' => array(
591 'type' => 'array',
592 'sanitize' => 'integer',
593 ),
594 'user_earning__not_in' => array(
595 'type' => 'array',
596 'sanitize' => 'integer',
597 ),
598 'post_type' => array(
599 'type' => 'array',
600 'sanitize' => 'text',
601 ),
602 'post_type__not_in' => array(
603 'type' => 'array',
604 'sanitize' => 'text',
605 ),
606 'parent_post_type' => array(
607 'type' => 'array',
608 'sanitize' => 'text',
609 ),
610 'points_type' => array(
611 'type' => 'array',
612 'sanitize' => 'text',
613 ),
614 'force_types' => array(
615 'type' => 'boolean',
616 ),
617 ) );
618
619 ct_reset_setup_table();
620
621 return $rules;
622
623 }