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 / filters.php

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

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