PluginProbe
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI / trunk
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI vtrunk
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 7.8.6 7.8.5 All 44 releases
gamipress / includes / filters.php

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

2,324 lines 80.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Filters
4 *
5 * @package GamiPress\Filters
6 * @author GamiPress <contact@gamipress.com>, Ruben Garcia <rubengcdev@gmail.com>
7 * @since 1.0.0
8 */
9 // Exit if accessed directly
10 if( !defined( 'ABSPATH' ) ) exit;
11
12 /**
13 * Add filters to remove stuff from our singular pages and add back in how we want it
14 *
15 * @since 1.0.0
16 */
17 function gamipress_do_single_filters() {
18 // Check we're in the right place
19 if ( gamipress_is_single_achievement() || gamipress_is_single_rank() ) {
20 // Filter out the post title
21 // add_filter( 'the_title', 'gamipress_remove_to_reformat_entries_title', 10, 2 );
22
23 // and filter out the post image
24 add_filter( 'post_thumbnail_html', 'gamipress_remove_to_reformat_entries_thumbnail', 10, 2 );
25 }
26 }
27 add_action( 'wp_enqueue_scripts', 'gamipress_do_single_filters' );
28
29 /**
30 * Filter out the post title/post image and add back (later) how we want it
31 *
32 * @since 1.0.0
33 *
34 * @param string $html The page content prior to filtering
35 * @param int $post_id The post ID.
36 *
37 * @return string The page content after being filtered
38 */
39 function gamipress_remove_to_reformat_entries_title( $html = '', $post_id = 0 ) {
40
41 global $gamipress_template_args;
42
43 // Remove, but only on the main loop!
44 if ( ( gamipress_is_single_achievement( $post_id ) || gamipress_is_single_rank( $post_id ) ) // Ensure that is an achievement or a rank
45 && empty( $GLOBALS['gamipress_reformat_title'] ) // Ensure to pass it only one time
46 && ! is_array( $gamipress_template_args ) // Prevents to pass this check on GamiPress shortcodes
47 ) {
48 // Now that we're where we want to be, tell the filters to stop removing
49 $GLOBALS['gamipress_reformat_title'] = true;
50 return '';
51 }
52
53 // Nothing to see here... move along
54 return $html;
55 }
56
57 /**
58 * Filter out the post title/post image and add back (later) how we want it
59 *
60 * @since 1.0.0
61 *
62 * @param string $html The page content prior to filtering
63 * @param int $post_id The post ID.
64 *
65 * @return string The page content after being filtered
66 */
67 function gamipress_remove_to_reformat_entries_thumbnail( $html = '', $post_id = 0 ) {
68
69 global $gamipress_template_args;
70
71 // Remove, but only on the main loop!
72 if ( ( gamipress_is_single_achievement( $post_id ) || gamipress_is_single_rank( $post_id ) ) // Ensure that is an achievement or a rank
73 && empty( $GLOBALS['gamipress_reformat_thumbnail'] ) // Ensure to pass it only one time
74 && ! is_array( $gamipress_template_args ) // Prevents to pass this check on GamiPress shortcodes
75 ) {
76 // Now that we're where we want to be, tell the filters to stop removing
77 $GLOBALS['gamipress_reformat_thumbnail'] = true;
78 return '';
79 }
80
81 // Nothing to see here... move along
82 return $html;
83 }
84
85 /**
86 * Filter achievement content to add our removed content back
87 *
88 * @since 1.0.0
89 *
90 * @param string $content The page content
91 *
92 * @return string The page content after reformat
93 */
94 function gamipress_reformat_entries( $content ) {
95
96 if ( gamipress_is_single_achievement( get_the_ID() ) ) {
97
98 // Filter content, but only is a single achievement!
99 return gamipress_apply_single_template( $content, 'single-achievement' );
100
101 } else if ( gamipress_is_single_rank( get_the_ID() ) ) {
102
103 // Filter content, but only is a single rank!
104 return gamipress_apply_single_template( $content, 'single-rank' );
105 }
106
107 return $content;
108 }
109 add_filter( 'the_content', 'gamipress_reformat_entries' );
110
111 /**
112 * Apply the given single template
113 *
114 * @since 1.3.1
115 *
116 * @param string $content
117 * @param string $single_template
118 *
119 * @return string
120 */
121 function gamipress_apply_single_template( $content, $single_template = '' ) {
122
123 global $gamipress_template_args;
124
125 // Now that we're where we want to be, tell the filters to stop removing
126 $GLOBALS['gamipress_reformat_content'] = true;
127
128 // Initialize GamiPress template args global
129 $gamipress_template_args = array();
130
131 // Get the original post content (to use as achievement description)
132 $gamipress_template_args['original_content'] = $content;
133
134 // Set the configured layout
135 $gamipress_template_args['layout'] = gamipress_get_post_meta( get_the_ID(), '_gamipress_layout' );
136
137 // If not layout defined, fallback to left layout
138 if( empty( $gamipress_template_args['layout'] ) ) {
139 $gamipress_template_args['layout'] = 'left';
140 }
141
142 // Set the configured alignment
143 $gamipress_template_args['align'] = gamipress_get_post_meta( get_the_ID(), '_gamipress_align' );
144
145 // If not alignment defined, fallback to none alignment
146 if( empty( $gamipress_template_args['align'] ) ) {
147 $gamipress_template_args['align'] = 'none';
148 }
149
150 /**
151 * Single template arguments
152 *
153 * @since 7.6.5
154 *
155 * @param array $gamipress_template_args
156 * @param string $single_template
157 */
158 $gamipress_template_args = apply_filters( 'gamipress_single_template_args', $gamipress_template_args, $single_template );
159
160 ob_start();
161
162 // Try to load single-{template}-{post_type}.php, if not exists load single-{template}.php
163 gamipress_get_template_part( $single_template, gamipress_get_post_type( get_the_ID() ) );
164
165 $new_content = ob_get_clean();
166
167 // Ok, we're done reformatting
168 $GLOBALS['gamipress_reformat_content'] = false;
169
170 return $new_content;
171
172 }
173
174 /**
175 * Helper function tests that we're in the main loop
176 *
177 * @since 1.3.1
178 *
179 * @param bool|integer $id The page id
180 *
181 * @return boolean A boolean determining if the function is in the main loop
182 */
183 function gamipress_is_single_achievement( $id = false ) {
184
185 $slugs = gamipress_get_achievement_types_slugs();
186
187 // only run our filters on the achievement singular page
188 if ( is_admin() || empty( $slugs ) || ! is_singular( $slugs ) )
189 return false;
190 // w/o id, we're only checking template context
191 if ( ! $id )
192 return true;
193
194 // Checks several variables to be sure we're in the main loop (and won't effect things like post pagination titles)
195 return ( ( $GLOBALS['post']->ID == $id ) && in_the_loop() && empty( $GLOBALS['gamipress_reformat_content'] ) );
196
197 }
198
199 /**
200 * Generate HTML markup for an points type's points awards
201 *
202 * @since 1.0.0
203 *
204 * @param array $points_awards An points type's points awards
205 * @param int $user_id The given user's ID
206 * @param array $template_args The given template args
207 *
208 * @return string The markup for our list
209 */
210 function gamipress_get_points_awards_for_points_types_list_markup( $points_awards = array(), $user_id = 0, $template_args = array() ) {
211
212 // If we don't have any points awards, or our points awards aren't an array, return nothing
213 if ( ! $points_awards || ! is_array( $points_awards ) ) {
214 return null;
215 }
216
217 $count = count( $points_awards );
218
219 // If we have no points awards, return nothing
220 if ( ! $count ) {
221 return null;
222 }
223
224 // Grab the current user's ID if none was specifed
225 if ( ! $user_id ) {
226 $user_id = get_current_user_id();
227 }
228
229 $a = wp_parse_args( $template_args, gamipress_points_types_shortcode_defaults() );
230
231 // Setup our variables
232 $output = '';
233
234 if( $a['heading'] === 'yes' ) {
235
236 $points_type = gamipress_get_points_award_points_type( $points_awards[0]->ID );
237
238 if( $points_type ) {
239 $plural_name = gamipress_get_post_meta( '_gamipress_plural_name', $points_type->ID );
240
241 if( ! $plural_name )
242 $plural_name = $points_type->post_title;
243
244 $points_awards_heading = sprintf( '%1$d %2$s %3$s', $count, $plural_name, _n( 'Award', 'Awards', $count, 'gamipress' ) ); // 2 Credits Awards
245 } else {
246 $points_awards_heading = sprintf( '%1$d %2$s', $count, _n( 'Award', 'Awards', $count, 'gamipress' ) ); // 2 Awards
247 }
248
249 /**
250 * Filters the points award heading text
251 *
252 * @since 1.0.0
253 *
254 * @param string $points_awards_heading The heading text (eg: 2 Points Awards)
255 * @param array $points_awards The points awards
256 * @param int $user_id The user's ID
257 * @param array $template_args The given template args
258 *
259 * @return string
260 */
261 $points_awards_heading = apply_filters( 'gamipress_points_awards_heading', $points_awards_heading, $points_awards, $user_id, $template_args );
262 $a['heading_size'] = gamipress_sanitize_title_size_option( $a['heading_size'] );
263
264 $output .= '<' . $a['heading_size'] . ' class="gamipress-points-awards-heading">' . $points_awards_heading . '</' . $a['heading_size'] . '>';
265
266 }
267
268 $output .= '<ul class="gamipress-points-awards">';
269
270 // Concatenate our output
271 foreach ( $points_awards as $points_award ) {
272
273 if( $user_id === 0 ) {
274 $earned_status = 'user-has-not-earned';
275 } else {
276 // Check if user can earn this points award and add the earned class
277 $can_earn = gamipress_can_user_earn_requirement( $points_award->ID, $user_id );
278 $earned_status = $can_earn ? 'user-has-not-earned' : 'user-has-earned';
279 }
280
281 $title = $points_award->post_title;
282
283 // If points award doesn't have a title, then try to build one
284 if( empty( $title ) ) {
285 $title = gamipress_build_requirement_title( $points_award->ID );
286 }
287
288 /**
289 * Filters the points award CSS class
290 *
291 * @since 1.0.0
292 *
293 * @param string $class CSS class based on earned status ('user-has-earned' | 'user-has-not-earned')
294 * @param stdClass $points_award Requirement object
295 * @param int $user_id User's ID
296 * @param array $template_args The given template args
297 *
298 * @return string
299 */
300 $class = apply_filters( 'gamipress_points_award_class', $earned_status, $points_award, $user_id, $template_args );
301
302 /**
303 * Filters the points award HTML title to display
304 *
305 * @since 1.0.0
306 *
307 * @param string $title Title to display
308 * @param stdClass $points_award Requirement object
309 * @param int $user_id User's ID
310 * @param array $template_args The given template args
311 *
312 * @return string
313 */
314 $title = apply_filters( 'gamipress_points_award_title_display', $title, $points_award, $user_id, $template_args );
315
316 $output .= '<li class="'. esc_attr( $class ) .'">'. $title . '</li>';
317 }
318
319 $output .= '</ul><!-- .gamipress-points-awards -->';
320
321 // Return our output
322 return $output;
323
324 }
325
326 /**
327 * Generate HTML markup for an points type's points deducts
328 *
329 * @since 1.3.7
330 *
331 * @param array $points_deducts An points type's points deducts
332 * @param int $user_id The given user's ID
333 * @param array $template_args The given template args
334 *
335 * @return string The markup for our list
336 */
337 function gamipress_get_points_deducts_for_points_types_list_markup( $points_deducts = array(), $user_id = 0, $template_args = array() ) {
338
339 // If we don't have any points deducts, or our points deducts aren't an array, return nothing
340 if ( ! $points_deducts || ! is_array( $points_deducts ) ) {
341 return null;
342 }
343
344 $count = count( $points_deducts );
345
346 // If we have no points deducts, return nothing
347 if ( ! $count ) {
348 return null;
349 }
350
351 // Grab the current user's ID if none was specifed
352 if ( ! $user_id ) {
353 $user_id = get_current_user_id();
354 }
355
356 $a = wp_parse_args( $template_args, gamipress_points_types_shortcode_defaults() );
357
358 // Setup our variables
359 $output = '';
360
361 if( $a['heading'] === 'yes' ) {
362
363 $points_type = gamipress_get_points_deduct_points_type( $points_deducts[0]->ID );
364
365 if( $points_type ) {
366 $plural_name = gamipress_get_post_meta( '_gamipress_plural_name', $points_type->ID );
367
368 if( ! $plural_name ) {
369 $plural_name = $points_type->post_title;
370 }
371
372 $points_deducts_heading = sprintf( '%1$d %2$s %3$s', $count, $plural_name, _n( 'Deduction', 'Deductions', $count, 'gamipress' ) ); // 2 Credits Deducts
373 } else {
374 $points_deducts_heading = sprintf( '%1$d %2$s', $count, _n( 'Deduction', 'Deductions', $count, 'gamipress' ) ); // 2 Deductions
375 }
376
377 /**
378 * Filters the points deduct heading text
379 *
380 * @since 1.3.7
381 *
382 * @param string $points_deducts_heading The heading text (eg: 2 Points Deductions)
383 * @param array $points_deducts The points deducts
384 * @param int $user_id The user's ID
385 * @param array $template_args The given template args
386 *
387 * @return string
388 */
389 $points_deducts_heading = apply_filters( 'gamipress_points_deducts_heading', $points_deducts_heading, $points_deducts, $user_id, $template_args );
390 $a['heading_size'] = gamipress_sanitize_title_size_option( $a['heading_size'] );
391
392 $output .= '<' . $a['heading_size'] . ' class="gamipress-points-deducts-heading">' . $points_deducts_heading . '</' . $a['heading_size'] . '>';
393
394 }
395
396 $output .= '<ul class="gamipress-points-deducts">';
397
398 // Concatenate our output
399 foreach ( $points_deducts as $points_deduct ) {
400
401 if( $user_id === 0 ) {
402 $earned_status = 'user-has-not-earned';
403 } else {
404 // Check if user can earn this points deduct and add the earned class
405 $can_earn = gamipress_can_user_earn_requirement( $points_deduct->ID, $user_id );
406 $earned_status = $can_earn ? 'user-has-not-earned' : 'user-has-earned';
407 }
408
409 $title = $points_deduct->post_title;
410
411 // If points deduct doesn't have a title, then try to build one
412 if( empty( $title ) ) {
413 $title = gamipress_build_requirement_title( $points_deduct->ID );
414 }
415
416 /**
417 * Filters the points deduct CSS class
418 *
419 * @since 1.3.7
420 *
421 * @param string $class CSS class based on earned status ('user-has-earned' | 'user-has-not-earned')
422 * @param stdClass $points_deduct Requirement object
423 * @param int $user_id User's ID
424 * @param array $template_args The given template args
425 *
426 * @return string
427 */
428 $class = apply_filters( 'gamipress_points_deduct_class', $earned_status, $points_deduct, $user_id, $template_args );
429
430 /**
431 * Filters the points deduct HTML title to display
432 *
433 * @since 1.3.7
434 *
435 * @param string $title Title to display
436 * @param stdClass $points_deduct Requirement object
437 * @param int $user_id User's ID
438 * @param array $template_args The given template args
439 *
440 * @return string
441 */
442 $title = apply_filters( 'gamipress_points_deduct_title_display', $title, $points_deduct, $user_id, $template_args );
443
444 $output .= '<li class="'. esc_attr( $class ) .'">'. $title . '</li>';
445 }
446
447 $output .= '</ul><!-- .gamipress-points-deducts -->';
448
449 // Return our output
450 return $output;
451
452 }
453
454 /**
455 * Gets achievement's required steps and returns HTML markup for these steps
456 *
457 * @since 1.0.0
458 * @param int $achievement_id The given achievement's post ID
459 * @param int $user_id A given user's ID
460 *
461 * @return string The markup for our list
462 */
463 function gamipress_get_required_achievements_for_achievement_list( $achievement_id = 0, $user_id = 0 ) {
464
465 // Grab the current post ID if no achievement_id was specified
466 if ( ! $achievement_id ) {
467 global $post;
468 $achievement_id = $post->ID;
469 }
470
471 // Grab the current user's ID if none was specifed
472 if ( ! $user_id )
473 $user_id = wp_get_current_user()->ID;
474
475 // Grab our achievement's required steps
476 $steps = gamipress_get_achievement_steps( $achievement_id );
477
478 // Return our markup output
479 return gamipress_get_required_achievements_for_achievement_list_markup( $steps, $user_id );
480
481 }
482
483 /**
484 * Generate HTML markup for an achievement's required steps
485 *
486 * This will generate an unorderd list (<ul>) if steps are non-sequential
487 * and an ordered list (<ol>) if steps require sequentiality.
488 *
489 * @since 1.0.0
490 *
491 * @param array $steps An achievement's required steps
492 * @param int $achievement_id The given achievement's ID
493 * @param int $user_id The given user's ID
494 * @param array $template_args The given template args
495 *
496 * @return string The markup for our list
497 */
498 function gamipress_get_required_achievements_for_achievement_list_markup( $steps = array(), $achievement_id = 0, $user_id = 0, $template_args = array() ) {
499
500 // If we don't have any steps, or our steps aren't an array, return nothing
501 if ( ! $steps || ! is_array( $steps ) )
502 return null;
503
504 // Grab the current post ID if no achievement_id was specified
505 if ( ! $achievement_id ) {
506 global $post;
507 $achievement_id = $post->ID;
508 }
509
510 $count = count( $steps );
511
512 // If we have no steps, return nothing
513 if ( ! $count )
514 return null;
515
516 // Grab the current user's ID if none was specified
517 if ( ! $user_id )
518 $user_id = get_current_user_id();
519
520 $a = wp_parse_args( $template_args, gamipress_achievement_shortcode_defaults() );
521
522 // Setup our variables
523 $output = '';
524 $container = gamipress_is_achievement_sequential() ? 'ol' : 'ul';
525
526 if( $a['heading'] === 'yes' ) {
527
528 $steps_heading = sprintf( '%1$d %2$s', $count, _n( 'Step', 'Steps', $count, 'gamipress' ) );
529
530 /**
531 * Filters the steps heading text
532 *
533 * @since 1.0.0
534 *
535 * @param string $steps_heading The heading text (eg: 2 Steps)
536 * @param array $steps The achievement steps
537 * @param int $user_id The user's ID
538 * @param array $template_args The given template args
539 *
540 * @return string
541 */
542 $steps_heading = apply_filters( 'gamipress_steps_heading', $steps_heading, $steps, $user_id, $template_args );
543 $a['heading_size'] = gamipress_sanitize_title_size_option( $a['heading_size'] );
544
545 $output .= '<' . $a['heading_size'] . ' class="gamipress-achievement-steps-heading">' . $steps_heading . '</' . $a['heading_size'] . '>';
546
547 }
548
549 $output .= '<' . $container .' class="gamipress-achievement-steps gamipress-required-achievements">';
550 $credential = gamipress_get_the_credential();
551
552 // Concatenate our output
553 foreach ( $steps as $step ) {
554
555 $earned_status = 'user-has-not-earned';
556
557 if( ! $credential ) {
558
559 $can_earn = true;
560
561 if( $user_id === 0 ) {
562 $earned_status = 'user-has-not-earned';
563 } else {
564 // Check if user can earn this step and add the earned class
565 $can_earn = gamipress_can_user_earn_requirement( $step->ID, $user_id );
566 $earned_status = $can_earn ? 'user-has-not-earned' : 'user-has-earned';
567 }
568
569 // Force earned class if user can't earn this step but has earned it in the past
570 if( ! $can_earn && gamipress_has_user_earned_achievement( $step->ID, $user_id ) ) {
571 $earned_status = 'user-has-earned';
572 }
573
574 }
575
576 $title = $step->post_title;
577
578 // If step doesn't have a title, then try to build one
579 if( empty( $title ) ) {
580 $title = gamipress_build_requirement_title( $step->ID );
581 }
582
583 /**
584 * Filters the step CSS class
585 *
586 * @since 1.0.0
587 *
588 * @param string $class CSS class based on earned status ('user-has-earned' | 'user-has-not-earned')
589 * @param stdClass $step Requirement object
590 * @param int $user_id User's ID
591 * @param array $template_args The given template args
592 *
593 * @return string
594 */
595 $class = apply_filters( 'gamipress_step_class', $earned_status, $step, $user_id, $template_args );
596
597 /**
598 * Filters the step HTML title to display
599 *
600 * @since 1.0.0
601 *
602 * @param string $title Title to display
603 * @param stdClass $step Requirement object
604 * @param int $user_id User's ID
605 * @param array $template_args The given template args
606 *
607 * @return string
608 */
609 $title = apply_filters( 'gamipress_step_title_display', $title, $step, $user_id, $template_args );
610
611 $output .= '<li class="'. esc_attr( $class ) .'">'. $title . '</li>';
612 }
613
614 $output .= '</'. $container .'><!-- .gamipress-required-achievements -->';
615
616 // Return our output
617 return $output;
618
619 }
620
621 /**
622 * Filter requirements titles to link to assigned post
623 *
624 * @since 1.0.0
625 * @updated 1.5.0 Improved checks to get correct post permalink and centralize all requirements link functions to this
626 * @updated 1.8.7 Added permalink to the 'earn-rank' trigger
627 *
628 * @param string $title The requirement title
629 * @param object $requirement The requirement object
630 *
631 * @return string Our potentially updated title
632 */
633 function gamipress_format_requirement_title_with_post_link( $title = '', $requirement = null ) {
634
635 // Grab our step requirements
636 $requirement = gamipress_get_requirement_object( $requirement->ID );
637
638 $url = $requirement['url'];
639
640 if( empty( $url ) ) {
641
642 $trigger = $requirement['trigger_type'];
643 $post_id = 0;
644 $site_id = get_current_blog_id();
645
646 if ( in_array( $trigger, array( 'earn-rank', 'revoke-rank' ) ) && ! empty( $requirement['rank_required'] ) ) {
647
648 // Set the post ID for the rank required to reach
649 $post_id = $requirement['rank_required'];
650 $site_id = ( gamipress_is_network_wide_active() ? get_main_site_id() : get_current_blog_id() );
651
652 } else if ( ! empty( $requirement['achievement_post'] ) ) {
653
654 // Set the post ID for the post assigned
655 $post_id = $requirement['achievement_post'];
656 $site_id = $requirement['achievement_post_site_id'];
657
658 }
659
660 // Set the URL to link to a specific post
661 $url = gamipress_get_specific_activity_trigger_permalink( $post_id, $trigger, $site_id );
662
663 }
664
665 // If we have a URL, update the title to link to it
666 if ( ! empty( $url ) ) {
667 $title = '<a href="' . esc_url( $url ) . '">' . $title . '</a>';
668 }
669
670 return $title;
671
672 }
673 add_filter( 'gamipress_step_title_display', 'gamipress_format_requirement_title_with_post_link', 10, 2 );
674 add_filter( 'gamipress_points_award_title_display', 'gamipress_format_requirement_title_with_post_link', 10, 2 );
675 add_filter( 'gamipress_points_deduct_title_display', 'gamipress_format_requirement_title_with_post_link', 10, 2 );
676 add_filter( 'gamipress_rank_requirement_title_display', 'gamipress_format_requirement_title_with_post_link', 10, 2 );
677
678 /**
679 * Generate markup for an achievement's times earned output
680 *
681 * @since 1.5.9
682 *
683 * @param int $achievement_id The given achievement's ID
684 * @param array $template_args Achievement template args
685 *
686 * @return string The HTML markup for our times earned output
687 */
688 function gamipress_achievement_times_earned_markup( $achievement_id = 0, $template_args = array() ) {
689
690 // Grab the current post ID if no achievement_id was specified
691 if ( ! $achievement_id ) {
692 global $post;
693 $achievement_id = $post->ID;
694 }
695
696 if( ! isset( $template_args['user_id'] ) ) {
697 $template_args['user_id'] = get_current_user_id();
698 }
699
700 $user_id = absint( $template_args['user_id'] );
701
702 // Guest not supported yet (basically because they has not earned this achievement)
703 if( $user_id === 0 ) {
704 return '';
705 }
706
707 $maximum_earnings = absint( gamipress_get_post_meta( $achievement_id, '_gamipress_maximum_earnings' ) );
708
709 // Return if maximum earnings configured is 1
710 if( $maximum_earnings === 1 ) {
711 return '';
712 }
713
714 $earned_times = gamipress_get_earnings_count( array( 'user_id' => $user_id, 'post_id' => $achievement_id ) );
715
716 /**
717 * Filter to override the minimum times required to show the achievement times earned text, by default 1
718 *
719 * @since 2.0.0
720 *
721 * @param int $minimum_earned_times Minimum times required to show the achievement times earned text, by default 1
722 * @param int $achievement_id The given achievement's ID
723 * @param int $user_id The user's ID
724 * @param int $earned_times The user's times earned this achievement
725 * @param int $maximum_earnings The achievement's maximum times to be earned
726 * @param array $template_args Achievement template args
727 */
728 $minimum_earned_times = apply_filters( 'gamipress_achievement_times_earned_minimum_times_to_show', 1, $achievement_id, $user_id, $earned_times, $maximum_earnings, $template_args );
729
730 // Return if user hasn't earned this achievement the minimum times required to show
731 if( $earned_times <= $minimum_earned_times ) {
732 return '';
733 }
734
735 // Setup the times earned text based on if achievements has unlimited times to be earned
736 if( $maximum_earnings === 0 ) {
737 $times_earned_pattern = __( '%d times earned', 'gamipress' );
738
739 $times_earned_text = sprintf( $times_earned_pattern, $earned_times );
740 } else {
741 $times_earned_pattern = __( '%d of %d times earned', 'gamipress' );
742
743 $times_earned_text = sprintf( $times_earned_pattern, $earned_times, $maximum_earnings );
744 }
745
746 /**
747 * Filter to override the achievement times earned text
748 *
749 * @since 1.5.9
750 *
751 * @param string $times_earned_text Times earned text, by default "X times earned"
752 * @param int $achievement_id The given achievement's ID
753 * @param int $user_id The user's ID
754 * @param int $earned_times The user's times earned this achievement
755 * @param int $maximum_earnings The achievement's maximum times to be earned
756 * @param array $template_args Achievement template args
757 */
758 $times_earned_text = apply_filters( 'gamipress_achievement_times_earned_text', $times_earned_text, $achievement_id, $user_id, $earned_times, $maximum_earnings, $template_args );
759
760 // The time earned markup
761 $output = '<div class="gamipress-achievement-times-earned">' . $times_earned_text . '</div>';
762
763 /**
764 * Filter to override the achievement times earned markup
765 *
766 * @since 1.5.9
767 *
768 * @param string $output Times earned markup
769 * @param int $achievement_id The given achievement's ID
770 * @param int $user_id The user's ID
771 * @param int $earned_times The user's times earned this achievement
772 * @param int $maximum_earnings The achievement's maximum times to be earned
773 * @param array $template_args Achievement template args
774 */
775 return apply_filters( 'gamipress_achievement_times_earned_markup', $output, $achievement_id, $user_id, $earned_times, $maximum_earnings, $template_args );
776
777 }
778
779 /**
780 * Generate markup for an achievement's times earned by all users output
781 *
782 * @since 2.0.0
783 *
784 * @param int $achievement_id The given achievement's ID
785 * @param array $template_args Achievement template args
786 *
787 * @return string The HTML markup for our times earned output
788 */
789 function gamipress_achievement_global_times_earned_markup( $achievement_id = 0, $template_args = array() ) {
790
791 global $wpdb;
792
793 // Grab the current post ID if no achievement_id was specified
794 if ( ! $achievement_id ) {
795 global $post;
796 $achievement_id = $post->ID;
797 }
798
799 $maximum_earnings = absint( gamipress_get_post_meta( $achievement_id, '_gamipress_global_maximum_earnings' ) );
800
801 $user_earnings = GamiPress()->db->user_earnings;
802
803 $earned_times = absint( $wpdb->get_var( $wpdb->prepare(
804 "SELECT COUNT( DISTINCT ue.user_id ) FROM {$user_earnings} AS ue WHERE ue.post_id = %d",
805 absint( $achievement_id )
806 ) ) );
807
808 /**
809 * Filter to override the minimum times required to show the achievement times earned by all users text, by default 1
810 *
811 * @since 2.0.0
812 *
813 * @param int $minimum_earned_times Minimum times required to show the achievement times earned text, by default 1
814 * @param int $achievement_id The given achievement's ID
815 * @param int $earned_times The user's times earned this achievement
816 * @param int $maximum_earnings The achievement's global maximum times to be earned
817 * @param array $template_args Achievement template args
818 */
819 $minimum_earned_times = apply_filters( 'gamipress_achievement_global_times_earned_minimum_times_to_show', 1, $achievement_id, $earned_times, $maximum_earnings, $template_args );
820
821 // Return if user hasn't earned this achievement the minimum times required to show
822 if( $earned_times <= $minimum_earned_times ) {
823 return '';
824 }
825
826 $post_type = gamipress_get_post_type( $achievement_id );
827 $achievement_type_singular = gamipress_get_achievement_type_singular( $post_type );
828
829 // Set up the times earned text based on if achievements has unlimited times to be earned
830 if( $maximum_earnings === 0 ) {
831 $times_earned_text = sprintf( __( '%d users have earned this %s', 'gamipress' ),
832 $earned_times,
833 $achievement_type_singular
834 );
835 } else {
836 $times_earned_text = sprintf( __( '%d of %d users have earned this %s', 'gamipress' ),
837 $earned_times,
838 $maximum_earnings,
839 $achievement_type_singular
840 );
841 }
842
843 /**
844 * Filter to override the achievement times earned by all users text
845 *
846 * @since 1.5.9
847 *
848 * @param string $times_earned_text Times earned text, by default "X users have earned this Y"
849 * @param int $achievement_id The given achievement's ID
850 * @param int $earned_times The user's times earned this achievement
851 * @param int $maximum_earnings The achievement's maximum times to be earned
852 * @param array $template_args Achievement template args
853 */
854 $times_earned_text = apply_filters( 'gamipress_achievement_global_times_earned_text', $times_earned_text, $achievement_id, $earned_times, $maximum_earnings, $template_args );
855
856 // The time earned markup
857 $output = '<div class="gamipress-achievement-global-times-earned">' . $times_earned_text . '</div>';
858
859 /**
860 * Filter to override the achievement times earned by all users markup
861 *
862 * @since 1.5.9
863 *
864 * @param string $output Times earned markup
865 * @param int $achievement_id The given achievement's ID
866 * @param int $earned_times The user's times earned this achievement
867 * @param int $maximum_earnings The achievement's maximum times to be earned
868 * @param array $template_args Achievement template args
869 */
870 return apply_filters( 'gamipress_achievement_global_times_earned_markup', $output, $achievement_id, $earned_times, $maximum_earnings, $template_args );
871
872 }
873
874 /**
875 * Generate markup for an achievement's points output
876 *
877 * @since 1.0.0
878 * @updated 1.5.9 Added $template_args parameter
879 *
880 * @param int $achievement_id The given achievement's ID
881 * @param array $template_args Achievement template args
882 *
883 * @return string The HTML markup for our points
884 */
885 function gamipress_achievement_points_markup( $achievement_id = 0, $template_args = array() ) {
886
887 // Grab the current post ID if no achievement_id was specified
888 if ( ! $achievement_id ) {
889 global $post;
890 $achievement_id = $post->ID;
891 }
892
893 $points = absint( gamipress_get_post_meta( $achievement_id, '_gamipress_points' ) );
894
895 // Return if no points configured
896 if( $points === 0 ) {
897 return '';
898 }
899
900 $points_type = gamipress_get_post_meta( $achievement_id, '_gamipress_points_type' );
901
902 // Set the default value for the points awarded thumbnail
903 if( ! isset( $template_args['points_awarded_thumbnail'] ) ) {
904 $template_args['points_awarded_thumbnail'] = 'yes';
905 }
906
907 $output = '<div class="gamipress-achievement-points gamipress-achievement-points-type-' . $points_type . '">'
908 . ( $template_args['points_awarded_thumbnail'] === 'yes' ? gamipress_get_points_type_thumbnail( $points_type ) . ' ' : '' )
909 . gamipress_format_points( $points, $points_type )
910 . '</div>';
911
912 // Return the points awarded output
913 return apply_filters( 'gamipress_achievement_points_markup', $output, $achievement_id, $points, $points_type, $template_args );
914
915 }
916
917 /**
918 * Generate markup for an achievement's unlock with points output
919 *
920 * @since 1.3.7
921 *
922 * @param int $achievement_id The given achievement's ID
923 * @param array $template_args Achievement template args
924 *
925 * @return string The HTML markup for our points
926 */
927 function gamipress_achievement_unlock_with_points_markup( $achievement_id = 0, $template_args = array() ) {
928
929 // Grab the current post ID if no achievement_id was specified
930 if ( ! $achievement_id ) {
931 $achievement_id = get_the_ID();
932 }
933
934 $user_id = get_current_user_id();
935
936 // Guest not supported yet (basically because they have no points)
937 if( $user_id === 0 ) {
938 return '';
939 }
940
941 if( ! isset( $template_args['user_id'] ) ) {
942 $template_args['user_id'] = get_current_user_id();
943 }
944
945 // Return if user is displaying achievements of another user
946 if( $user_id !== absint( $template_args['user_id'] ) ) {
947 return '';
948 }
949
950 // Return if this option not was enabled
951 if( ! (bool) gamipress_get_post_meta( $achievement_id, '_gamipress_unlock_with_points' ) ) {
952 return '';
953 }
954
955 $points = absint( gamipress_get_post_meta( $achievement_id, '_gamipress_points_to_unlock' ) );
956
957 // Return if no points configured
958 if( $points === 0 ) {
959 return '';
960 }
961
962 $earned = gamipress_achievement_user_exceeded_max_earnings( $user_id, $achievement_id );
963
964 // Return if user has completely earned this achievement
965 if( $earned ) {
966 return '';
967 }
968
969 // Setup vars
970 $points_type = gamipress_get_post_meta( $achievement_id, '_gamipress_points_type_to_unlock' );
971
972 // Template vars
973 $achievement_title = gamipress_get_post_field( 'post_title', $achievement_id );
974 $points_formatted = gamipress_format_points( $points, $points_type );
975
976 /**
977 * Filters if achievement unlock with points requires confirmation, by default true
978 *
979 * @since 1.7.8.1
980 *
981 * @param bool $confirmation If the given achievement's ID requires confirmation on unlock using points
982 * @param int $achievement_id The given achievement's ID
983 * @param int $user_id The user's ID
984 * @param int $points Points amount to unlock
985 * @param string $points_type Points type of points amount to unlock
986 * @param array $template_args Achievement template args
987 *
988 * @return bool Whatever if achievement requires confirmation or not
989 */
990 $confirmation = apply_filters( 'gamipress_achievement_unlock_with_points_confirmation', true, $achievement_id, $user_id, $points, $points_type, $template_args );
991
992 $button_text = sprintf( __( 'Unlock using %s', 'gamipress' ), $points_formatted );
993
994 /**
995 * Filters the achievement unlock with points button text
996 *
997 * @since 1.8.6
998 *
999 * @param string $button_text The button text, by default "Unlock using 100 points"
1000 * @param int $achievement_id The given achievement's ID
1001 * @param int $user_id The user's ID
1002 * @param int $points Points amount to unlock
1003 * @param string $points_type Points type of points amount to unlock
1004 * @param array $template_args Achievement template args
1005 *
1006 * @return string Whatever if achievement requires confirmation or not
1007 */
1008 $button_text = apply_filters( 'gamipress_achievement_unlock_with_points_button_text', $button_text, $achievement_id, $user_id, $points, $points_type, $template_args );
1009
1010 ob_start(); ?>
1011 <div class="gamipress-achievement-unlock-with-points" data-id="<?php echo $achievement_id; ?>">
1012 <button type="button" class="gamipress-achievement-unlock-with-points-button"><?php echo $button_text; ?></button>
1013 <?php if( $confirmation ) : ?>
1014 <div class="gamipress-achievement-unlock-with-points-confirmation" style="display: none;">
1015 <p><?php echo sprintf( __( 'Do you want to unlock %s using %s?', 'gamipress' ), $achievement_title, $points_formatted ); ?></p>
1016 <button type="button" class="gamipress-achievement-unlock-with-points-confirm-button"><?php echo __( 'Yes', 'gamipress' ); ?></button>
1017 <button type="button" class="gamipress-achievement-unlock-with-points-cancel-button"><?php echo __( 'No', 'gamipress' ); ?></button>
1018 </div>
1019 <?php endif; ?>
1020 <div class="gamipress-spinner" style="display: none;"></div>
1021 </div>
1022 <?php $output = ob_get_clean();
1023
1024 /**
1025 * Filters the achievement unlock with points markup
1026 *
1027 * @since 1.3.7
1028 *
1029 * @param string $output The HTML markup for our points
1030 * @param int $achievement_id The given achievement's ID
1031 * @param int $user_id The user's ID
1032 * @param int $points Points amount to unlock
1033 * @param string $points_type Points type of points amount to unlock
1034 * @param array $template_args Achievement template args
1035 *
1036 * @return string The HTML markup for our points
1037 */
1038 $output = apply_filters( 'gamipress_achievement_unlock_with_points_markup', $output, $achievement_id, $user_id, $points, $points_type, $template_args );
1039
1040 // Return the unlock with points output
1041 return $output;
1042
1043 }
1044
1045 /**
1046 * Generate markup for an rank's unlock with points output
1047 *
1048 * @since 1.3.7
1049 *
1050 * @param int $rank_id The given rank's ID
1051 * @param array $template_args Rank template args
1052 *
1053 * @return string The HTML markup for our points
1054 */
1055 function gamipress_rank_unlock_with_points_markup( $rank_id = 0, $template_args = array() ) {
1056
1057 // Grab the current post ID if no rank_id was specified
1058 if ( ! $rank_id ) {
1059 $rank_id = get_the_ID();
1060 }
1061
1062 $rank_types = gamipress_get_rank_types();
1063 $rank_type = gamipress_get_post_type( $rank_id );
1064
1065 if( ! isset( $rank_types[$rank_type] ) ) {
1066 return '';
1067 }
1068
1069 $user_id = get_current_user_id();
1070
1071 // Guest not supported yet (basically because they have no points)
1072 if( $user_id === 0 ) {
1073 return '';
1074 }
1075
1076 if( ! isset( $template_args['user_id'] ) ) {
1077 $template_args['user_id'] = get_current_user_id();
1078 }
1079
1080 // Return if user is displaying ranks of another user
1081 if( $user_id !== absint( $template_args['user_id'] ) ) {
1082 return '';
1083 }
1084
1085 // Return if this option not was enabled
1086 if( ! (bool) gamipress_get_post_meta( $rank_id, '_gamipress_unlock_with_points' ) ) {
1087 return '';
1088 }
1089
1090 $points = absint( gamipress_get_post_meta( $rank_id, '_gamipress_points_to_unlock' ) );
1091
1092 // Return if no points configured
1093 if( $points === 0 ) {
1094 return '';
1095 }
1096
1097 // Bail if not is the next rank to unlock
1098 if( gamipress_get_next_user_rank_id( $user_id, $rank_type ) !== $rank_id ) {
1099 return '';
1100 }
1101
1102 $user_rank = gamipress_get_user_rank( $user_id, $rank_type );
1103
1104 // Return if user is in a higher rank
1105 if( gamipress_get_rank_priority( $rank_id ) <= gamipress_get_rank_priority( $user_rank ) ) {
1106 return '';
1107 }
1108
1109 // Setup vars
1110 $points_type = gamipress_get_post_meta( $rank_id, '_gamipress_points_type_to_unlock' );
1111
1112 // Template vars
1113 $rank_title = gamipress_get_post_field( 'post_title', $rank_id );
1114 $points_formatted = gamipress_format_points( $points, $points_type );
1115
1116 /**
1117 * Filters if rank unlock with points requires confirmation, by default true
1118 *
1119 * @since 1.7.8.1
1120 *
1121 * @param bool $confirmation If the given rank's ID requires confirmation on unlock using points
1122 * @param int $rank_id The given rank's ID
1123 * @param int $user_id The user's ID
1124 * @param int $points Points amount to unlock
1125 * @param string $points_type Points type of points amount to unlock
1126 * @param array $template_args Achievement template args
1127 *
1128 * @return bool Whatever if achievement requires confirmation or not
1129 */
1130 $confirmation = apply_filters( 'gamipress_rank_unlock_with_points_confirmation', true, $rank_id, $user_id, $points, $points_type, $template_args );
1131
1132 $button_text = sprintf( __( 'Unlock using %s', 'gamipress' ), $points_formatted );
1133
1134 /**
1135 * Filters the rank unlock with points button text
1136 *
1137 * @since 1.8.6
1138 *
1139 * @param string $button_text The button text, by default "Unlock using 100 points"
1140 * @param int $rank_id The given rank's ID
1141 * @param int $user_id The user's ID
1142 * @param int $points Points amount to unlock
1143 * @param string $points_type Points type of points amount to unlock
1144 * @param array $template_args Achievement template args
1145 *
1146 * @return string Whatever if achievement requires confirmation or not
1147 */
1148 $button_text = apply_filters( 'gamipress_rank_unlock_with_points_button_text', $button_text, $rank_id, $user_id, $points, $points_type, $template_args );
1149
1150 ob_start(); ?>
1151 <div class="gamipress-rank-unlock-with-points" data-id="<?php echo $rank_id; ?>">
1152 <button type="button" class="gamipress-rank-unlock-with-points-button"><?php echo $button_text; ?></button>
1153 <?php if( $confirmation ) : ?>
1154 <div class="gamipress-rank-unlock-with-points-confirmation" style="display: none;">
1155 <p><?php echo sprintf( __( 'Do you want to unlock %s using %s?', 'gamipress' ), $rank_title, $points_formatted ); ?></p>
1156 <button type="button" class="gamipress-rank-unlock-with-points-confirm-button"><?php echo __( 'Yes', 'gamipress' ); ?></button>
1157 <button type="button" class="gamipress-rank-unlock-with-points-cancel-button"><?php echo __( 'No', 'gamipress' ); ?></button>
1158 </div>
1159 <?php endif; ?>
1160 <div class="gamipress-spinner" style="display: none;"></div>
1161 </div>
1162 <?php $output = ob_get_clean();
1163
1164 /**
1165 * Filters the achievement unlock with points markup
1166 *
1167 * @since 1.3.7
1168 *
1169 * @param string $output The HTML markup for our points
1170 * @param int $rank_id The given rank's ID
1171 * @param int $user_id The user's ID
1172 * @param int $points Points amount to unlock
1173 * @param string $points_type Points type of points amount to unlock
1174 * @param array $template_args Achievement template args
1175 *
1176 * @return string The HTML markup for our points
1177 */
1178 $output = apply_filters( 'gamipress_rank_unlock_with_points_markup', $output, $rank_id, $user_id, $points, $points_type, $template_args );
1179
1180 // Return our markup
1181 return $output;
1182
1183 }
1184
1185 /**
1186 * Checks if should render open graph meta tags
1187 *
1188 * @since 1.8.6
1189 */
1190 function gamipress_maybe_render_open_graph_meta_tags() {
1191
1192 $allowed_types = array_merge( gamipress_get_achievement_types_slugs(), gamipress_get_rank_types_slugs() );
1193
1194 // Bail if not is a singular achievement type or rank type
1195 if( ! is_singular( $allowed_types ) ) {
1196 return;
1197 }
1198
1199 $enable_open_graph = (bool) gamipress_get_option( 'enable_open_graph_tags', false );
1200
1201 // Bail if open graph meta tags option is not enabled
1202 if( ! $enable_open_graph ) {
1203 return;
1204 }
1205
1206 gamipress_render_open_graph_meta_tags( get_the_ID() );
1207
1208 }
1209 add_action( 'wp_head', 'gamipress_maybe_render_open_graph_meta_tags' );
1210
1211
1212 /**
1213 * Render open graph meta tags for the received post ID
1214 *
1215 * @since 1.8.6
1216 *
1217 * @param int $post_id
1218 */
1219 function gamipress_render_open_graph_meta_tags( $post_id ) {
1220
1221 $post = get_post( $post_id );
1222
1223 // Get the post information
1224 $url = get_permalink( $post );
1225 $title = $post->post_title;
1226 $description = $post->post_content;
1227 $image = get_the_post_thumbnail_url( $post );
1228
1229 // Process the description
1230 $description = apply_filters( 'the_content', $description );
1231 $description = trim( strip_tags( wp_kses_no_null( $description ) ) );
1232 ?>
1233 <meta property="og:url" content="<?php echo esc_url( $url ); ?>"/>
1234 <meta property="og:title" content="<?php echo esc_attr( $title ); ?>"/>
1235 <meta property="og:description" content="<?php echo esc_attr( $description ); ?>"/>
1236 <meta property="og:image" content="<?php echo esc_url( $image ); ?>"/>
1237 <?php
1238 }
1239
1240 /**
1241 * Generate markup for share an achievement's output
1242 *
1243 * @since 1.8.6
1244 *
1245 * @param int $achievement_id The given achievement's ID
1246 * @param array $template_args Achievement template args
1247 *
1248 * @return string The HTML markup for our points
1249 */
1250 function gamipress_achievement_share_markup( $achievement_id = 0, $template_args = array() ) {
1251
1252 // Grab the current post ID if no achievement_id was specified
1253 if ( ! $achievement_id ) {
1254 $achievement_id = get_the_ID();
1255 }
1256
1257 $user_id = get_current_user_id();
1258
1259 // Guest not allowed (basically because they have not earned this)
1260 if( $user_id === 0 ) {
1261 return '';
1262 }
1263
1264 if( ! isset( $template_args['user_id'] ) ) {
1265 $template_args['user_id'] = get_current_user_id();
1266 }
1267
1268 // Return if user is displaying achievements of another user
1269 if( $user_id !== absint( $template_args['user_id'] ) ) {
1270 return '';
1271 }
1272
1273 // Bail if share is not enable
1274 if( ! (bool) gamipress_get_option( 'enable_share', false ) ) {
1275 return '';
1276 }
1277
1278 $social_networks = gamipress_get_option( 'social_networks', false );
1279
1280 // Bail if no social networks enabled
1281 if( empty( $social_networks ) ) {
1282 return '';
1283 }
1284
1285 // Check if user has earned this achievement
1286 $earned = gamipress_has_user_earned_achievement( $achievement_id, $user_id );
1287
1288 if( ! $earned ) {
1289 return '';
1290 }
1291
1292 $button_style = gamipress_get_option( 'social_button_style', 'square' );
1293
1294 $titles = array(
1295 'facebook' => __( 'Share on Facebook', 'gamipress' ),
1296 'twitter' => __( 'Share on Twitter', 'gamipress' ),
1297 'linkedin' => __( 'Share on LinkedIn', 'gamipress' ),
1298 'pinterest' => __( 'Share on Pinterest', 'gamipress' ),
1299 );
1300
1301 $names = array(
1302 'facebook' => __( 'Facebook', 'gamipress' ),
1303 'twitter' => __( 'Twitter', 'gamipress' ),
1304 'linkedin' => __( 'LinkedIn', 'gamipress' ),
1305 'pinterest' => __( 'Pinterest', 'gamipress' ),
1306 );
1307
1308 // Setup vars
1309 $url = gamipress_get_credential_url( $achievement_id, $user_id );
1310 $title = get_the_title( $achievement_id );
1311 $image = get_the_post_thumbnail_url( $achievement_id );
1312
1313 // Get the achievement twitter text
1314 $twitter_text = gamipress_get_option( 'twitter_achievement_text', __( 'I earned the {achievement_type} {achievement_title} on {site_title}', 'gamipress' ) );
1315
1316 // Parse the text
1317 $twitter_text = gamipress_parse_tags( 'achievement_earned', $achievement_id, $user_id, $twitter_text );
1318
1319 ob_start(); ?>
1320
1321 <p class="gamipress-share-buttons-label"><?php _e( 'Share:', 'gamipress' ); ?></p>
1322
1323 <div class="gamipress-share-buttons"
1324 data-url="<?php echo esc_attr( $url ); ?>"
1325 data-title="<?php echo esc_attr( $title ); ?>"
1326 data-image="<?php echo esc_attr( $image ); ?>"
1327 data-twitter-text="<?php echo esc_attr( $twitter_text ); ?>">
1328
1329 <?php
1330 /**
1331 * Action at top of the share buttons
1332 *
1333 * @since 1.8.6
1334 *
1335 * @param int $achievement_id The given achievement's ID
1336 * @param int $user_id The user's ID
1337 * @param array $template_args Achievement template args
1338 */
1339 do_action( 'gamipress_achievement_share_buttons_top', $achievement_id, $user_id, $template_args ) ?>
1340
1341 <?php foreach( $social_networks as $social_network ) : ?>
1342 <a href="#"
1343 title="<?php echo ( isset( $titles[$social_network] ) ? $titles[$social_network] : '' ); ?>"
1344 class="gamipress-share-button gamipress-share-button-<?php echo $button_style; ?> gamipress-share-button-<?php echo $social_network; ?>"
1345 data-network="<?php echo $social_network; ?>">
1346 <span><?php echo ( isset( $names[$social_network] ) ? $names[$social_network] : '' ); ?></span>
1347 </a>
1348 <?php endforeach; ?>
1349
1350 <?php
1351 /**
1352 * Action at bottom of the share buttons
1353 *
1354 * @since 1.8.6
1355 *
1356 * @param int $achievement_id The given achievement's ID
1357 * @param int $user_id The user's ID
1358 * @param array $template_args Achievement template args
1359 */
1360 do_action( 'gamipress_achievement_share_buttons_bottom', $achievement_id, $user_id, $template_args ) ?>
1361
1362 </div>
1363
1364 <?php $output = ob_get_clean();
1365
1366 /**
1367 * Filters the achievement share markup
1368 *
1369 * @since 1.8.6
1370 *
1371 * @param string $output The HTML markup for social sharing
1372 * @param int $achievement_id The given achievement's ID
1373 * @param int $user_id The user's ID
1374 * @param array $template_args Achievement template args
1375 *
1376 * @return string The HTML markup for our points
1377 */
1378 $output = apply_filters( 'gamipress_achievement_share_markup', $output, $achievement_id, $user_id, $template_args );
1379
1380 return $output;
1381
1382 }
1383
1384 /**
1385 * Generate markup for share an rank's output
1386 *
1387 * @since 1.8.6
1388 *
1389 * @param int $rank_id The given rank's ID
1390 * @param array $template_args Rank template args
1391 *
1392 * @return string The HTML markup for our points
1393 */
1394 function gamipress_rank_share_markup( $rank_id = 0, $template_args = array() ) {
1395
1396 // Grab the current post ID if no rank_id was specified
1397 if ( ! $rank_id ) {
1398 $rank_id = get_the_ID();
1399 }
1400
1401 $user_id = get_current_user_id();
1402
1403 // Guest not supported yet (basically because they has not earned this)
1404 if( $user_id === 0 ) {
1405 return '';
1406 }
1407
1408 if( ! isset( $template_args['user_id'] ) ) {
1409 $template_args['user_id'] = get_current_user_id();
1410 }
1411
1412 // Return if user is displaying ranks of another user
1413 if( $user_id !== absint( $template_args['user_id'] ) ) {
1414 return '';
1415 }
1416
1417 // Bail if share is not enable
1418 if( ! (bool) gamipress_get_option( 'enable_share', false ) ) {
1419 return '';
1420 }
1421
1422 $social_networks = gamipress_get_option( 'social_networks', false );
1423
1424 // Bail if not social networks enabled
1425 if( empty( $social_networks ) ) {
1426 return '';
1427 }
1428
1429 // Check if user has earned this achievement
1430 $earned = gamipress_has_user_earned_achievement( $rank_id, $user_id );
1431
1432 if( ! $earned ) {
1433 return '';
1434 }
1435
1436 $button_style = gamipress_get_option( 'social_button_style', 'square' );
1437
1438 $titles = array(
1439 'facebook' => __( 'Share on Facebook', 'gamipress' ),
1440 'twitter' => __( 'Share on Twitter', 'gamipress' ),
1441 'linkedin' => __( 'Share on LinkedIn', 'gamipress' ),
1442 'pinterest' => __( 'Share on Pinterest', 'gamipress' ),
1443 );
1444
1445 $names = array(
1446 'facebook' => __( 'Facebook', 'gamipress' ),
1447 'twitter' => __( 'Twitter', 'gamipress' ),
1448 'linkedin' => __( 'LinkedIn', 'gamipress' ),
1449 'pinterest' => __( 'Pinterest', 'gamipress' ),
1450 );
1451
1452 // Setup vars
1453 $url = gamipress_get_credential_url( $rank_id, $user_id );
1454 $title = get_the_title( $rank_id );
1455 $image = get_the_post_thumbnail_url( $rank_id );
1456
1457 // Get the rank twitter text
1458 $twitter_text = gamipress_get_option( 'twitter_rank_text', __( 'I reached the {rank_type} {rank_title} on {site_title}', 'gamipress' ) );
1459
1460 // Parse the text
1461 $twitter_text = gamipress_parse_tags( 'rank_earned', $rank_id, $user_id, $twitter_text );
1462
1463 ob_start(); ?>
1464
1465 <p class="gamipress-share-buttons-label"><?php _e( 'Share:', 'gamipress' ); ?></p>
1466
1467 <div class="gamipress-share-buttons"
1468 data-url="<?php echo esc_attr( $url ); ?>"
1469 data-title="<?php echo esc_attr( $title ); ?>"
1470 data-image="<?php echo esc_attr( $image ); ?>"
1471 data-twitter-text="<?php echo esc_attr( $twitter_text ); ?>">
1472
1473 <?php
1474 /**
1475 * Action at top of the share buttons
1476 *
1477 * @since 1.8.6
1478 *
1479 * @param int $rank_id The given rank's ID
1480 * @param int $user_id The user's ID
1481 * @param array $template_args Rank template args
1482 */
1483 do_action( 'gamipress_rank_share_buttons_top', $rank_id, $user_id, $template_args ) ?>
1484
1485 <?php foreach( $social_networks as $social_network ) : ?>
1486 <a href="#"
1487 title="<?php echo ( isset( $titles[$social_network] ) ? $titles[$social_network] : '' ); ?>"
1488 class="gamipress-share-button gamipress-share-button-<?php echo $button_style; ?> gamipress-share-button-<?php echo $social_network; ?>"
1489 data-network="<?php echo $social_network; ?>">
1490 <span><?php echo ( isset( $names[$social_network] ) ? $names[$social_network] : '' ); ?></span>
1491 </a>
1492 <?php endforeach; ?>
1493
1494 <?php
1495 /**
1496 * Action at bottom of the share buttons
1497 *
1498 * @since 1.8.6
1499 *
1500 * @param int $rank_id The given rank's ID
1501 * @param int $user_id The user's ID
1502 * @param array $template_args Rank template args
1503 */
1504 do_action( 'gamipress_rank_share_buttons_bottom', $rank_id, $user_id, $template_args ) ?>
1505
1506 </div>
1507
1508 <?php $output = ob_get_clean();
1509
1510 /**
1511 * Filters the rank share markup
1512 *
1513 * @since 1.8.6
1514 *
1515 * @param string $output The HTML markup for social sharing
1516 * @param int $rank_id The given rank's ID
1517 * @param int $user_id The user's ID
1518 * @param array $template_args Rank template args
1519 *
1520 * @return string The HTML markup for our points
1521 */
1522 $output = apply_filters( 'gamipress_rank_share_markup', $output, $rank_id, $user_id, $template_args );
1523
1524 return $output;
1525
1526 }
1527
1528 /**
1529 * Adds "earned"/"not earned" post_class based on viewer's status
1530 *
1531 * @param array $classes Post classes
1532 *
1533 * @return array Updated post classes
1534 */
1535 function gamipress_add_earned_class_single( $classes = array() ) {
1536
1537 if( is_singular( gamipress_get_achievement_types_slugs() ) ) {
1538 // Single Achievement
1539
1540 // Check if current user has earned the achievement they're viewing
1541 $classes[] =gamipress_has_user_earned_achievement( get_the_ID(), get_current_user_id() ) ? 'user-has-earned' : 'user-has-not-earned';
1542
1543 } else if( is_singular( gamipress_get_rank_types_slugs() ) ) {
1544 // Single Rank
1545
1546 // Check if current user has earned the rank they're viewing, rank is earned by default if is the lowest priority of this type
1547 if( gamipress_is_lowest_priority_rank( get_the_ID() ) ) {
1548 $earned = true;
1549 } else {
1550 $earned = gamipress_has_user_earned_achievement( get_the_ID(), get_current_user_id() );
1551 }
1552
1553 $classes[] = $earned ? 'user-has-earned' : 'user-has-not-earned';
1554
1555 }
1556
1557 return $classes;
1558
1559 }
1560 add_filter( 'post_class', 'gamipress_add_earned_class_single' );
1561
1562 /**
1563 * Returns a message if user has earned the achievement.
1564 *
1565 * @since 1.0.0
1566 *
1567 * @param int $achievement_id Achievement ID.
1568 * @param int $user_id User ID.
1569 *
1570 * @return string HTML Markup.
1571 */
1572 function gamipress_render_earned_achievement_text( $achievement_id = 0, $user_id = 0 ) {
1573
1574 $earned_message = '';
1575
1576 if ( gamipress_has_user_earned_achievement( $achievement_id, $user_id ) ) {
1577
1578 $earned_message .= '<div class="gamipress-achievement-earned"><p>'
1579 . sprintf( __( 'You have earned this %s!', 'gamipress' ), gamipress_get_achievement_type_singular( gamipress_get_post_type( $achievement_id ), true ) )
1580 . '</p></div>';
1581
1582 if ( $congrats_text = gamipress_get_post_meta( $achievement_id, '_gamipress_congratulations_text' ) ) {
1583 $earned_message .= '<div class="gamipress-achievement-congratulations">' . wpautop( $congrats_text ) . '</div>';
1584 }
1585 }
1586
1587 /**
1588 * Available filter to override the message if user has earned the achievement
1589 *
1590 * @since 1.0.0
1591 *
1592 * @param string $earned_message The earned message HTML markup.
1593 * @param int $achievement_id Achievement ID.
1594 * @param int $user_id User ID.
1595 *
1596 * @return string HTML Markup.
1597 */
1598 return apply_filters( 'gamipress_earned_achievement_message', $earned_message, $achievement_id, $user_id );
1599 }
1600
1601 /**
1602 * Check if user has earned a given achievement.
1603 *
1604 * @since 1.0.0
1605 *
1606 * @param int $achievement_id Achievement ID.
1607 * @param int $user_id User ID.
1608 *
1609 * @return bool True if user has earned the achievement, otherwise false.
1610 */
1611 function gamipress_has_user_earned_achievement( $achievement_id = 0, $user_id = 0 ) {
1612
1613 $user_id = absint( $user_id );
1614 $achievement_id = absint( $achievement_id );
1615
1616 if( $user_id === 0 ) $user_id = get_current_user_id();
1617 if( $user_id === 0 ) return false;
1618
1619 $cache = gamipress_get_cache( 'has_user_earned_achievement', array(), false );
1620
1621 if( isset( $cache[$user_id] ) && isset( $cache[$user_id][$achievement_id] ) ) {
1622 // If result already cached, use it
1623 $earned = $cache[$user_id][$achievement_id];
1624 } else {
1625 // Not cached result
1626 $earned = gamipress_get_earnings_count( array( 'user_id' => $user_id, 'post_id' => $achievement_id ) );
1627 $earned = $earned > 0;
1628
1629 // Update the cache
1630 if( ! isset( $cache[$user_id] ) ) $cache[$user_id] = array();
1631 $cache[$user_id][$achievement_id] = $earned;
1632
1633 gamipress_set_cache( 'has_user_earned_achievement', $cache );
1634 }
1635
1636 /**
1637 * Available filter to override the has user earned achievement result.
1638 *
1639 * @since 1.0.0
1640 *
1641 * @param bool $earned Whatever if user has earned this achievement or not.
1642 * @param int $achievement_id Achievement ID.
1643 * @param int $user_id User ID.
1644 *
1645 * @return bool True if user has earned the achievement, otherwise false.
1646 */
1647 return apply_filters( 'gamipress_has_user_earned_achievement', $earned, $achievement_id, $user_id );
1648
1649 }
1650
1651
1652 /**
1653 * Hide the hidden achievement post link from next and previous post link
1654 *
1655 * @since 1.0.0
1656 *
1657 * @param string $output The adjacent post link.
1658 * @param string $format Link anchor format.
1659 * @param string $link Link permalink format.
1660 * @param WP_Post $post The adjacent post.
1661 * @param string $adjacent Whether the post is previous or next.
1662 *
1663 * @return string
1664 */
1665 function gamipress_hide_next_previous_hidden_achievement_link( $output, $format, $link, $post, $adjacent ) {
1666
1667 $post = get_post();
1668
1669 if( $post && gamipress_is_achievement( $post ) && $output ) {
1670
1671 // Get post link, without hidden achievement
1672 $output = gamipress_get_post_link_without_hidden_achievement( $post->ID, $adjacent );
1673
1674 }
1675
1676 return $output;
1677
1678 }
1679 add_filter( 'next_post_link', 'gamipress_hide_next_previous_hidden_achievement_link', 10, 5 );
1680 add_filter( 'previous_post_link', 'gamipress_hide_next_previous_hidden_achievement_link', 10, 5 );
1681
1682
1683 /**
1684 * Get post link without hidden achievement link
1685 *
1686 * @since 1.0.0
1687 *
1688 * @param int $achievement_id The achievement ID
1689 * @param string $rel 'next'|'previous'
1690 *
1691 * @return string
1692 */
1693 function gamipress_get_post_link_without_hidden_achievement( $achievement_id, $rel ) {
1694
1695 // Check if is an achievement
1696 if( ! gamipress_is_achievement( $achievement_id ) ) {
1697 return '';
1698 }
1699
1700 $link = '';
1701
1702 // Get next post id without hidden achievement id
1703 $next_post_id = gamipress_get_next_previous_achievement_id( $achievement_id, $rel );
1704
1705 if ( $next_post_id ) {
1706 // Generate post link
1707 $link = gamipress_generate_post_link_by_post_id( $next_post_id, $rel );
1708 }
1709
1710 return $link;
1711
1712 }
1713
1714 /**
1715 * Get next or previous post id , without hidden achievement id
1716 *
1717 * @since 1.0.0
1718 *
1719 * @param int $achievement_id The achievement ID
1720 * @param string $rel 'next'|'previous'
1721 *
1722 * @return int|bool
1723 */
1724 function gamipress_get_next_previous_achievement_id( $achievement_id , $rel ) {
1725
1726 global $wpdb;
1727
1728 $posts = GamiPress()->db->posts;
1729
1730 // Redirecting user page based on achievements
1731 $post = gamipress_get_post( absint( $achievement_id ));
1732
1733 //Get hidden achievements ids
1734 $hidden = gamipress_get_hidden_achievement_ids( $post->post_type );
1735
1736 $operator = ( $rel === 'next' ? '>' : '<' );
1737 $order = ( $rel === 'next' ? 'ASC' : 'DESC' );
1738 $hidden_where = ( count( $hidden ) ? "AND ID NOT IN ( " . implode( ', ', $hidden ) . " )" : '' );
1739
1740 $next_id = absint( $wpdb->get_var( $wpdb->prepare(
1741 "SELECT ID
1742 FROM {$posts}
1743 WHERE post_type = %s
1744 AND post_status = %s
1745 {$hidden_where}
1746 AND ID {$operator} %d
1747 ORDER BY ID {$order}
1748 LIMIT 1",
1749 $post->post_type,
1750 'publish',
1751 $post->ID
1752 ) ) );
1753
1754 // Return next or previous achievement preventing hidden achievements
1755 return ( $next_id !== absint( $post->ID ) ? $next_id : false );
1756
1757 }
1758
1759 /**
1760 * Generate the post link based on custom post object
1761 *
1762 * @since 1.0.0
1763 *
1764 * @param int $post_id
1765 * @param string $rel
1766 *
1767 * @return string
1768 */
1769 function gamipress_generate_post_link_by_post_id( $post_id, $rel ) {
1770
1771 $post = gamipress_get_post( $post_id );
1772
1773 if( ! $post ) return '';
1774
1775 // Title of the post
1776 $title = get_the_title( $post->ID );
1777
1778 if ( empty( $post->post_title ) ) {
1779 $title = ( $rel === 'next' ) ? __( 'Next Post' ) : __( 'Previous Post' );
1780 }
1781
1782 $nav = ($rel == 'next') ? '%s <span class="meta-nav">→</span>' : '<span class="meta-nav">←</span> %s';
1783
1784 // Build link
1785 $link = '<a href="' . get_permalink( $post ) . '" rel="'.$rel.'">' . sprintf( $nav, $title ) . '</a>';
1786
1787 return $link;
1788
1789 }
1790
1791 /**
1792 * Filters the log title.
1793 *
1794 * @param string $title The log title.
1795 * @param int $id The log ID.
1796 *
1797 * @return string The formatted title
1798 */
1799 function gamipress_log_title_format( $title, $id = null ) {
1800
1801 if( $id === null ) return $title;
1802
1803 if( empty( $title ) ) $title = gamipress_get_parsed_log( $id );
1804
1805 return $title;
1806 }
1807 add_filter( 'gamipress_render_log_title', 'gamipress_log_title_format', 10, 2 );
1808
1809 /**
1810 * Gets rank's required steps and returns HTML markup for these steps
1811 *
1812 * @since 1.0.0
1813 * @param int $rank_id The given rank's post ID
1814 * @param int $user_id A given user's ID
1815 *
1816 * @return string The markup for our list
1817 */
1818 function gamipress_get_rank_requirements_list( $rank_id = 0, $user_id = 0 ) {
1819
1820 // Grab the current post ID if no rank_id was specified
1821 if ( ! $rank_id ) {
1822 global $post;
1823 $rank_id = $post->ID;
1824 }
1825
1826 // Grab the current user's ID if none was specifed
1827 if ( ! $user_id )
1828 $user_id = wp_get_current_user()->ID;
1829
1830 // Grab our rank's required requirements
1831 $requirements = gamipress_get_rank_requirements( $rank_id );
1832
1833 // Return our markup output
1834 return gamipress_get_rank_requirements_list_markup( $requirements, $user_id );
1835
1836 }
1837
1838 /**
1839 * Generate HTML markup for an achievement's required steps
1840 *
1841 * This will generate an unorderd list (<ul>) if steps are non-sequential
1842 * and an ordered list (<ol>) if steps require sequentiality.
1843 *
1844 * @since 1.3.1
1845 *
1846 * @param array $requirements An rank's required requirements
1847 * @param int $rank_id The given rank's ID
1848 * @param int $user_id The given user's ID
1849 * @param array $template_args The given template args
1850 *
1851 * @return string The markup for our list
1852 */
1853 function gamipress_get_rank_requirements_list_markup( $requirements = array(), $rank_id = 0, $user_id = 0, $template_args = array() ) {
1854
1855 // If we don't have any steps, or our steps aren't an array, return nothing
1856 if ( ! $requirements || ! is_array( $requirements ) ) {
1857 return null;
1858 }
1859
1860 // Grab the current post ID if no achievement_id was specified
1861 if ( ! $rank_id ) {
1862 global $post;
1863 $rank_id = $post->ID;
1864 }
1865
1866 $count = count( $requirements );
1867
1868 // If we have no steps, return nothing
1869 if ( ! $count ) {
1870 return null;
1871 }
1872
1873 // Grab the current user's ID if none was specified
1874 if ( ! $user_id ) {
1875 $user_id = get_current_user_id();
1876 }
1877
1878 $a = wp_parse_args( $template_args, gamipress_rank_shortcode_defaults() );
1879
1880 // Setup our variables
1881 $output = '';
1882 $container = gamipress_is_achievement_sequential() ? 'ol' : 'ul';
1883
1884 if( $a['heading'] === 'yes' ) {
1885
1886 $requirements_heading = sprintf( '%1$d %2$s', $count, _n( 'Requirement', 'Requirements', $count, 'gamipress' ) );;
1887
1888 /**
1889 * Filters the steps heading text
1890 *
1891 * @since 1.0.0
1892 *
1893 * @param string $requirements_heading The heading text (eg: 2 Requirements)
1894 * @param array $requirements The rank requirements
1895 * @param int $user_id The user's ID
1896 * @param array $template_args The given template args
1897 *
1898 * @return string
1899 */
1900 $requirements_heading = apply_filters( 'gamipress_rank_requirements_heading', $requirements_heading, $requirements, $user_id, $template_args );
1901 $a['heading_size'] = gamipress_sanitize_title_size_option( $a['heading_size'] );
1902
1903 $output .= '<' . $a['heading_size'] . ' class="gamipress-rank-requirements-heading">' . $requirements_heading . '</' . $a['heading_size'] . '>';
1904
1905 }
1906
1907 $output .= '<' . $container .' class="gamipress-rank-requirements gamipress-required-requirements">';
1908 $credential = gamipress_get_the_credential();
1909
1910 // Concatenate our output
1911 foreach ( $requirements as $requirement ) {
1912 $earned_status = 'user-has-not-earned';
1913
1914 if( ! $credential ) {
1915 if( $user_id === 0 ) {
1916 $earned_status = 'user-has-not-earned';
1917 } else {
1918 // Check if user can earn this requirement and add the earned class
1919 $can_earn = gamipress_can_user_earn_requirement( $requirement->ID, $user_id );
1920 $earned_status = $can_earn ? 'user-has-not-earned' : 'user-has-earned';
1921 }
1922 }
1923
1924 $title = $requirement->post_title;
1925
1926 // If step doesn't have a title, then try to build one
1927 if( empty( $title ) ) {
1928 $title = gamipress_build_requirement_title( $requirement->ID );
1929 }
1930
1931 /**
1932 * Filters the rank requirement CSS class
1933 *
1934 * @since 1.3.1
1935 *
1936 * @param string $class CSS class based on earned status ('user-has-earned' | 'user-has-not-earned')
1937 * @param stdClass $requirement Requirement object
1938 * @param int $user_id User's ID
1939 * @param array $template_args The given template args
1940 *
1941 * @return string
1942 */
1943 $class = apply_filters( 'gamipress_rank_requirement_class', $earned_status, $requirement, $user_id, $template_args );
1944
1945 /**
1946 * Filters the rank requirement HTML title to display
1947 *
1948 * @since 1.3.1
1949 *
1950 * @param string $title Title to display
1951 * @param stdClass $requirement Requirement object
1952 * @param int $user_id User's ID
1953 * @param array $template_args The given template args
1954 *
1955 * @return string
1956 */
1957 $title = apply_filters( 'gamipress_rank_requirement_title_display', $title, $requirement, $user_id, $template_args );
1958
1959 $output .= '<li class="'. esc_attr( $class ) .'">'. $title . '</li>';
1960 }
1961
1962 $output .= '</'. $container .'><!-- .gamipress-requirements -->';
1963
1964 // Return our output
1965 return $output;
1966
1967 }
1968
1969 /**
1970 * Helper function tests that we're in the main loop
1971 *
1972 * @since 1.3.1
1973 *
1974 * @param bool|integer $id The page id
1975 *
1976 * @return boolean A boolean determining if the function is in the main loop
1977 */
1978 function gamipress_is_single_rank( $id = false ) {
1979
1980 $slugs = gamipress_get_rank_types_slugs();
1981
1982 // only run our filters on the rank singular page
1983 if ( is_admin() || empty( $slugs ) || ! is_singular( $slugs ) )
1984 return false;
1985 // w/o id, we're only checking template context
1986 if ( ! $id )
1987 return true;
1988
1989 // Checks several variables to be sure we're in the main loop (and won't effect things like post pagination titles)
1990 return ( ( $GLOBALS['post']->ID == $id ) && in_the_loop() && empty( $GLOBALS['gamipress_reformat_content'] ) );
1991
1992 }
1993
1994 /**
1995 * Returns a message if user has earned the rank.
1996 *
1997 * @since 1.3.1
1998 *
1999 * @param int $rank_id Rank ID.
2000 * @param int $user_id User ID.
2001 *
2002 * @return string HTML Markup.
2003 */
2004 function gamipress_render_earned_rank_text( $rank_id = 0, $user_id = 0 ) {
2005
2006 $earned_message = '';
2007
2008 if ( gamipress_has_user_earned_rank( $rank_id, $user_id ) ) {
2009
2010 $earned_message .= '<div class="gamipress-rank-earned"><p>'
2011 . sprintf( __( 'You have reached this %s!', 'gamipress' ), gamipress_get_rank_type_singular( gamipress_get_post_type( $rank_id ), true ) )
2012 . '</p></div>';
2013
2014 if ( $congrats_text = gamipress_get_post_meta( $rank_id, '_gamipress_congratulations_text' ) ) {
2015 $earned_message .= '<div class="gamipress-rank-congratulations">' . wpautop( $congrats_text ) . '</div>';
2016 }
2017 }
2018
2019 /**
2020 * Available filter to override the message if user has earned the rank
2021 *
2022 * @since 1.0.0
2023 *
2024 * @param string $earned_message The earned message HTML markup.
2025 * @param int $rank_id Rank ID.
2026 * @param int $user_id User ID.
2027 *
2028 * @return string HTML Markup.
2029 */
2030 return apply_filters( 'gamipress_earned_rank_message', $earned_message, $rank_id, $user_id );
2031
2032 }
2033
2034 /**
2035 * Check if user has earned a given achievement.
2036 *
2037 * @since 1.3.1
2038 *
2039 * @param int $rank_id Rank ID.
2040 * @param int $user_id User ID.
2041 *
2042 * @return bool True if user has earned the rank, otherwise false.
2043 */
2044 function gamipress_has_user_earned_rank( $rank_id = 0, $user_id = 0 ) {
2045
2046 $user_id = absint( $user_id );
2047 $rank_id = absint( $rank_id );
2048
2049 if( $user_id === 0 ) {
2050 $user_id = get_current_user_id();
2051 }
2052
2053 if( $user_id === 0 ) {
2054 return false;
2055 }
2056
2057 $earned = gamipress_get_earnings_count( array( 'user_id' => $user_id, 'post_id' => $rank_id ) );
2058 $earned = $earned > 0;
2059
2060 /**
2061 * Available filter to override the has user earned rank result.
2062 *
2063 * @since 1.0.0
2064 *
2065 * @param bool $earned Whatever if user has earned this rank or not.
2066 * @param int $rank_id Rank ID.
2067 * @param int $user_id User ID.
2068 *
2069 * @return bool True if user has earned the rank, otherwise false.
2070 */
2071 return apply_filters( 'gamipress_has_user_earned_rank', $earned, $rank_id, $user_id );
2072
2073 }
2074
2075 /**
2076 * Auto flush permalinks wth a soft flush when a 404 error is detected on an GamiPress page
2077 *
2078 * Taken from Easy Digital Downloads
2079 *
2080 * @since 1.3.3
2081 * @return string
2082 */
2083 function gamipress_refresh_permalinks_on_bad_404() {
2084
2085 global $wp;
2086
2087 if( ! is_404() ) {
2088 return;
2089 }
2090
2091 if( isset( $_GET['gamipress-flush'] ) ) {
2092 return;
2093 }
2094
2095 if( false === get_transient( 'gamipress_refresh_404_permalinks' ) ) {
2096
2097 $gamipress_slugs = array();
2098
2099 $gamipress_slugs = array_merge( $gamipress_slugs, gamipress_get_achievement_types() );
2100 $gamipress_slugs = array_merge( $gamipress_slugs, gamipress_get_points_types() );
2101 $gamipress_slugs = array_merge( $gamipress_slugs, gamipress_get_rank_types() );
2102
2103 $parts = explode( '/', $wp->request );
2104
2105 $is_a_gamipress_page = false;
2106
2107 foreach( $parts as $part ) {
2108
2109 if( isset( $gamipress_slugs[$part] ) ) {
2110 $is_a_gamipress_page = true;
2111 break;
2112 }
2113
2114 }
2115
2116 if( ! $is_a_gamipress_page ) {
2117 return;
2118 }
2119
2120 flush_rewrite_rules( false );
2121
2122 set_transient( 'gamipress_refresh_404_permalinks', 1, HOUR_IN_SECONDS * 12 );
2123
2124 wp_redirect( home_url( add_query_arg( array( 'gamipress-flush' => 1 ), $wp->request ) ) ); exit;
2125
2126 }
2127 }
2128 add_action( 'template_redirect', 'gamipress_refresh_permalinks_on_bad_404' );
2129
2130 /**
2131 * Render earnings column
2132 *
2133 * @since 1.0.0
2134 *
2135 * @param string $column_output Default column output
2136 * @param string $column_name The column name
2137 * @param stdClass $user_earning The column name
2138 * @param array $template_args Template received arguments
2139 *
2140 * @return string
2141 */
2142 function gamipress_earnings_render_column( $column_output, $column_name, $user_earning, $template_args ) {
2143
2144 // Setup vars
2145 $requirement_types = gamipress_get_requirement_types();
2146 $points_types = gamipress_get_points_types();
2147 $achievement_types = gamipress_get_achievement_types();
2148 $rank_types = gamipress_get_rank_types();
2149
2150 switch( $column_name ) {
2151 case 'user':
2152
2153 $user = get_userdata( $user_earning->user_id );
2154
2155 if( $user ) {
2156 $column_output = get_avatar( $user_earning->user_id ) . $user->display_name;
2157 }
2158
2159 break;
2160 case 'thumbnail':
2161
2162 if( in_array( $user_earning->post_type, gamipress_get_requirement_types_slugs() ) ) {
2163
2164 if( $user_earning->post_type === 'step' && $achievement = gamipress_get_step_achievement( $user_earning->post_id ) ) {
2165 // Step
2166
2167 // Get the achievement thumbnail and build a link to the achievement
2168 $column_output = gamipress_get_achievement_post_thumbnail( $achievement->ID );
2169
2170 } else if( ( $user_earning->post_type === 'points-award' || $user_earning->post_type === 'points-deduct' ) && $points_type = gamipress_get_points_award_points_type( $user_earning->post_id ) ) {
2171 // Points Award and Deduction
2172
2173 // Get the points type thumbnail
2174 $column_output = gamipress_get_points_type_thumbnail( $points_type->ID );
2175
2176 } else if( $user_earning->post_type === 'rank-requirement' && $rank = gamipress_get_rank_requirement_rank( $user_earning->post_id ) ) {
2177 // Rank requirement
2178
2179 // Get the rank thumbnail
2180 $column_output = gamipress_get_rank_post_thumbnail( $rank->ID );
2181 }
2182
2183 } else if( in_array( $user_earning->post_type, gamipress_get_achievement_types_slugs() ) ) {
2184 // Achievement
2185
2186 // Get the achievement thumbnail
2187 $column_output = gamipress_get_achievement_post_thumbnail( $user_earning->post_id );
2188
2189 } else if( in_array( $user_earning->post_type, gamipress_get_rank_types_slugs() ) ) {
2190 // Rank
2191
2192 // Get the rank thumbnail
2193 $column_output = gamipress_get_rank_post_thumbnail( $user_earning->post_id );
2194
2195 } else {
2196 // Default
2197
2198 // Get the points type thumbnail
2199 $column_output = gamipress_get_points_type_thumbnail( $user_earning->post_id );
2200 }
2201
2202 break;
2203 case 'description':
2204
2205 $earning_title = $user_earning->title;
2206 $earning_description = '';
2207
2208 if( in_array( $user_earning->post_type, gamipress_get_requirement_types_slugs() ) ) {
2209
2210 $earning_description = '';
2211
2212 if( $user_earning->post_type === 'step' && $achievement = gamipress_get_step_achievement( $user_earning->post_id ) ) {
2213 // Step
2214
2215 // Build a link to the achievement
2216 $earning_description = sprintf( '%s %s: <a href="%s">%s</a>',
2217 $achievement_types[$achievement->post_type]['singular_name'],
2218 __( 'Step', 'gamipress' ),
2219 get_post_permalink( $achievement->ID ),
2220 $user_earning->title
2221 );
2222
2223 } else if( ( $user_earning->post_type === 'points-award' || $user_earning->post_type === 'points-deduct' ) && $points_type = gamipress_get_points_award_points_type( $user_earning->post_id ) ) {
2224 // Points Award and Deduction
2225
2226 $earning_description = sprintf( '%s %s',
2227 $points_types[$points_type->post_name]['plural_name'],
2228 ( $user_earning->post_type === 'points-award' ? __( 'Award', 'gamipress' ) : __( 'Deduction', 'gamipress' ) )
2229 );
2230
2231 } else if( $user_earning->post_type === 'rank-requirement' && $rank = gamipress_get_rank_requirement_rank( $user_earning->post_id ) ) {
2232 // Rank requirement
2233
2234 // Build a link to the rank
2235 $earning_description = sprintf( '%s %s: <a href="%s">%s</a>',
2236 $rank_types[$rank->post_type]['singular_name'],
2237 __( 'Requirement', 'gamipress' ),
2238 get_post_permalink( $rank->ID ),
2239 $user_earning->title
2240 );
2241 }
2242
2243 } else if( in_array( $user_earning->post_type, gamipress_get_achievement_types_slugs() ) ) {
2244 // Achievement
2245
2246 // Build a link to the achievement
2247 $earning_title = sprintf( '<a href="%s">%s</a>',
2248 get_post_permalink( $user_earning->post_id ),
2249 gamipress_get_post_field( 'post_title', $user_earning->post_id )
2250 );
2251 $earning_description = $achievement_types[$user_earning->post_type]['singular_name'];
2252
2253 } else if( in_array( $user_earning->post_type, gamipress_get_rank_types_slugs() ) ) {
2254 // Rank
2255
2256 // Build a link to the rank
2257 $earning_title = sprintf( '<a href="%s">%s</a>',
2258 get_post_permalink( $user_earning->post_id ),
2259 gamipress_get_post_field( 'post_title', $user_earning->post_id )
2260 );
2261 $earning_description = $rank_types[$user_earning->post_type]['singular_name'];
2262
2263 }
2264
2265 // Default description for custom user earnings with points assigned
2266 if( empty( $earning_description ) ) {
2267
2268 $points = (int) $user_earning->points;
2269
2270 if( $points !== 0 && isset( $points_types[$user_earning->points_type] ) ) {
2271
2272 $earning_description = sprintf( '%s %s',
2273 $points_types[$user_earning->points_type]['plural_name'],
2274 ( $points > 0 ? __( 'Award', 'gamipress' ) : __( 'Deduction', 'gamipress' ) )
2275 );
2276
2277 }
2278
2279 }
2280
2281 $column_output = sprintf( '<strong class="gamipress-earning-title">%s</strong>'
2282 . '<br>'
2283 . '<span class="gamipress-earning-description">%s</span>',
2284 $earning_title,
2285 $earning_description
2286 );
2287
2288 break;
2289 case 'points':
2290
2291 $points = (int) $user_earning->points;
2292
2293 if( $points !== 0 && isset( $points_types[$user_earning->points_type] ) ) {
2294
2295 // Setup the output as %d point(s)
2296 $column_output = gamipress_format_points( $points, $user_earning->points_type );
2297
2298 // For points deducts turn amount to negative
2299 if( $user_earning->post_type === 'points-deduct' && $points > 0 ) {
2300 $negative_points = $points * -1;
2301 $column_output = gamipress_format_points( $negative_points, $user_earning->points_type );;
2302 }
2303
2304 }
2305
2306 break;
2307 case 'date':
2308
2309 $column_output = date_i18n( get_option( 'date_format' ), strtotime( $user_earning->date ) );
2310
2311 break;
2312 case 'actions':
2313
2314 $render_credential = ( gamipress_is_achievement( $user_earning->post_type ) || gamipress_is_rank( $user_earning->post_type ) );
2315
2316 $column_output .= $render_credential ? gamipress_get_credential_link( $user_earning ) : '';
2317
2318 break;
2319 }
2320
2321 return $column_output;
2322
2323 }
2324 add_action( 'gamipress_earnings_render_column', 'gamipress_earnings_render_column', 10, 4 );