PluginProbe
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI / 7.9.9
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI v7.9.9
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
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.9, at includes/shortcodes/gamipress_earnings.php

628 lines 23.4 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 // Previous column label, keep for translation
315 $gamipress_template_args['columns']['thumbnail'] = __( 'Thumbnail', 'gamipress' );
316
317 $gamipress_template_args['columns']['thumbnail'] = __( 'Image', 'gamipress' );
318 $gamipress_template_args['columns']['description'] = __( 'Description', 'gamipress' );
319 $gamipress_template_args['columns']['points'] = __( 'Points', 'gamipress' );
320 $gamipress_template_args['columns']['date'] = __( 'Date', 'gamipress' );
321 $gamipress_template_args['columns']['actions'] = __( 'Actions', 'gamipress' );
322
323
324 // Render the earnings template
325 ob_start();
326 gamipress_get_template_part( 'earnings' );
327 $output = ob_get_clean();
328
329 // If switched to blog, return back to que current blog
330 if( $blog_id !== get_current_blog_id() && is_multisite() ) {
331 restore_current_blog();
332 }
333
334 /**
335 * Filter to override shortcode output
336 *
337 * @since 1.6.5
338 *
339 * @param string $output Final output
340 * @param array $atts Shortcode attributes
341 * @param string $content Shortcode content
342 */
343 return apply_filters( 'gamipress_earnings_shortcode_output', $output, $atts, $content );
344
345 }
346
347 /**
348 * User Earnings Shortcode Query
349 *
350 * @since 1.4.9
351 *
352 * @param array $args Query arguments
353 *
354 * @return CT_Query
355 */
356 function gamipress_earnings_shortcode_query( $args = array () ) {
357
358 // Query args
359 $query_args = array(
360 'orderby' => 'date',
361 'order' => $args['order'],
362 'items_per_page' => $args['limit'],
363 'paged' => max( 1, get_query_var( 'paged' ) )
364 );
365
366 $query_args['post_type'] = array();
367 $query_args['points_type'] = array();
368 $query_args['post_type__not_in'] = array();
369 $query_args['parent_post_type'] = array();
370
371 // User
372 if( isset( $args['user_id'] ) && absint( $args['user_id'] ) !== 0 ) {
373 $query_args['user_id'] = $args['user_id'];
374 }
375
376 // Build $include array
377 if ( ! is_array( $args['include'] ) && ! empty( $args['include'] ) ) {
378 $include = explode( ',', $args['include'] );
379 }
380
381 // Build $exclude array
382 if ( ! is_array( $args['exclude'] ) && ! empty( $args['exclude'] ) ) {
383 $exclude = explode( ',', $args['exclude'] );
384 }
385
386 // Include certain user earnings
387 if ( isset( $include ) && ! empty( $include ) ) {
388 $query_args[ 'user_earning__in' ] = $include;
389 }
390
391 // Exclude certain user earnings
392 if ( isset( $exclude ) && ! empty( $exclude ) ) {
393 $query_args[ 'user_earning__not_in' ] = $exclude;
394 }
395
396 // Points types
397 if( $args['points'] === 'yes' ) {
398
399 if( $args['points_types'] === 'all') {
400 $query_args['points_type'] = gamipress_get_points_types_slugs();
401 } else {
402 $point_types = explode( ',', $args['points_types'] );
403 $query_args['points_type'] = gamipress_sanitize_point_types_slugs_array( $point_types );
404 }
405
406 // For custom earnings points to the points type
407 $query_args['post_type'][] = 'points-type';
408
409 // Points awards
410 if( $args['awards'] === 'yes' ) {
411 $query_args['post_type'][] = 'points-award';
412 } else {
413 $query_args['post_type__not_in'][] = 'points-award';
414 }
415
416 // Points deducts
417 if( $args['deducts'] === 'yes' ) {
418 $query_args['post_type'][] = 'points-deduct';
419 } else {
420 $query_args['post_type__not_in'][] = 'points-deduct';
421 }
422
423 } else {
424 $query_args['post_type__not_in'][] = 'points-type';
425 $query_args['post_type__not_in'][] = 'points-award';
426 $query_args['post_type__not_in'][] = 'points-deduct';
427 }
428
429 // Achievement types
430 if( $args['achievements'] === 'yes' ) {
431
432 if( $args['achievement_types'] === 'all') {
433 $achievement_types = gamipress_get_achievement_types_slugs();
434 } else {
435 $achievement_types = explode( ',', $args['achievement_types'] );
436 $achievement_types = gamipress_sanitize_achievement_types_slugs_array( $achievement_types );
437 }
438 $query_args['post_type'] = array_merge( $query_args['post_type'], $achievement_types );
439
440 // Step
441 if( $args['steps'] === 'yes' ) {
442 if( $args['achievement_types'] === 'all') {
443 $query_args['post_type'][] = 'step';
444 } else {
445 $query_args['parent_post_type'] = array_merge( $query_args['parent_post_type'], $achievement_types );
446 }
447 } else {
448 $query_args['post_type__not_in'][] = 'step';
449 }
450
451 } else {
452 $query_args['post_type__not_in'] = array_merge( $query_args['post_type__not_in'], gamipress_get_achievement_types_slugs() );
453 $query_args['post_type__not_in'][] = 'step';
454 }
455
456 // Rank types
457 if( $args['ranks'] === 'yes' ) {
458
459 if( $args['rank_types'] === 'all') {
460 $rank_types = gamipress_get_rank_types_slugs();
461 } else {
462 $rank_types = explode( ',', $args['rank_types'] );
463 $rank_types = gamipress_sanitize_rank_types_slugs_array( $rank_types );
464 }
465
466 $query_args['post_type'] = array_merge( $query_args['post_type'], $rank_types );
467
468 // Rank requirements
469 if( $args['rank_requirements'] === 'yes' ) {
470 if( $args['rank_types'] === 'all') {
471 $query_args['post_type'][] = 'rank-requirement';
472 } else {
473 $query_args['parent_post_type'] = array_merge( $query_args['parent_post_type'], $rank_types );
474 }
475 } else {
476 $query_args['post_type__not_in'][] = 'rank-requirement';
477 }
478
479 } else {
480 $query_args['post_type__not_in'] = array_merge( $query_args['post_type__not_in'], gamipress_get_rank_types_slugs() );
481 $query_args['post_type__not_in'][] = 'rank-requirement';
482 }
483
484 // Remove types that has 'all' value
485 foreach( $query_args['post_type'] as $index => $type ) {
486 if( $type === 'all' ) {
487 unset( $query_args['post_type'][$index] );
488 }
489 }
490
491 // Return if not types selected
492 if( empty( $query_args['post_type'] ) ) {
493 return false;
494 }
495
496 if( ! empty( $query_args['points_type'] ) ) {
497 $query_args['force_types'] = true;
498 }
499
500 // 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
501 if( $args['achievements_without_points'] === 'yes' ) {
502 $query_args['points_type'][] = '';
503 $query_args['force_types'] = true;
504 }
505
506 /**
507 * Filters earnings shortcode query args
508 *
509 * @since 2.0.7
510 *
511 * @param array $query_args Query args to be passed to CT_Query
512 * @param array $args Function received args
513 *
514 * @return array
515 */
516 $query_args = apply_filters( 'gamipress_earnings_shortcode_query_args', $query_args, $args );
517
518 // Setup table
519 $ct_table = ct_setup_table( 'gamipress_user_earnings' );
520
521 // Sanitize query args
522 $query_args = gamipress_sanitize_query_args( $query_args, gamipress_user_earnings_query_vars_rules() );
523
524 return new CT_Query( $query_args );
525
526 }
527
528 /**
529 * Earnings shortcode defaults attributes values
530 *
531 * @since 7.1.6
532 *
533 * @return array
534 */
535 function gamipress_earnings_shortcode_defaults() {
536
537 return apply_filters( 'gamipress_earnings_shortcode_defaults', array(
538 'current_user' => 'yes',
539 'user_id' => '0',
540 'force_responsive' => '',
541 'limit' => '10',
542 'pagination' => 'yes',
543 'order' => 'DESC',
544 'include' => '',
545 'exclude' => '',
546 'points' => 'yes',
547 'points_types' => 'all',
548 'awards' => 'yes',
549 'deducts' => 'yes',
550 'achievements' => 'yes',
551 'achievement_types' => 'all',
552 'steps' => 'yes',
553 'achievements_without_points' => 'yes',
554 'ranks' => 'yes',
555 'rank_types' => 'all',
556 'rank_requirements' => 'yes',
557 ) );
558
559 }
560
561 /**
562 * User Earnings query vars rules
563 *
564 * @since 7.8.8
565 *
566 * @return array
567 */
568 function gamipress_user_earnings_query_vars_rules() {
569
570 // Setup table
571 $ct_table = ct_setup_table( 'gamipress_user_earnings' );
572
573 $rules = apply_filters( 'gamipress_user_earnings_query_vars_rules', array(
574 // Query fields
575 'orderby' => array(
576 'type' => 'string',
577 'sanitize' => 'text',
578 'allowed_values' => array_keys( $ct_table->db->schema->fields ),
579 ),
580 'order' => array(
581 'type' => 'string',
582 'sanitize' => 'uppercase',
583 'allowed_values' => array( 'ASC', 'DESC' ),
584 ),
585 'items_per_page' => array(
586 'type' => 'integer',
587 ),
588 'paged' => array(
589 'type' => 'integer',
590 ),
591 // Earning fields
592 'user_id' => array(
593 'type' => 'integer',
594 ),
595 'user_earning__in' => array(
596 'type' => 'array',
597 'sanitize' => 'integer',
598 ),
599 'user_earning__not_in' => array(
600 'type' => 'array',
601 'sanitize' => 'integer',
602 ),
603 'post_type' => array(
604 'type' => 'array',
605 'sanitize' => 'text',
606 ),
607 'post_type__not_in' => array(
608 'type' => 'array',
609 'sanitize' => 'text',
610 ),
611 'parent_post_type' => array(
612 'type' => 'array',
613 'sanitize' => 'text',
614 ),
615 'points_type' => array(
616 'type' => 'array',
617 'sanitize' => 'text',
618 ),
619 'force_types' => array(
620 'type' => 'boolean',
621 ),
622 ) );
623
624 ct_reset_setup_table();
625
626 return $rules;
627
628 }