PluginProbe
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI / 8.0.5
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI v8.0.5
8.0.5 8.0.4 8.0.3 8.0.1 8.0.2 8.0.0 7.9.9.7 7.9.9.6 7.9.9.5 7.9.9.4 7.9.9.3 7.9.9.2 7.9.9.1 7.9.9 7.9.8 7.9.7 7.9.6 7.9.5 7.9.4 7.9.3 7.9.2 7.9.1 7.9.0 7.8.9 7.8.8 All 47 releases
← All changes | includes/functions.php +1094 -0 7.8.9 → 8.0.5 View file →
@@ -1,0 +1,1094 @@
1 +<?php
2 +/**
3 + * Functions
4 + *
5 + * @package GamiPress\Functions
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 +// Functions includes
13 +require_once GAMIPRESS_DIR . 'includes/functions/achievement-types.php';
14 +require_once GAMIPRESS_DIR . 'includes/functions/points-types.php';
15 +require_once GAMIPRESS_DIR . 'includes/functions/rank-types.php';
16 +require_once GAMIPRESS_DIR . 'includes/functions/achievements.php';
17 +require_once GAMIPRESS_DIR . 'includes/functions/points.php';
18 +require_once GAMIPRESS_DIR . 'includes/functions/ranks.php';
19 +require_once GAMIPRESS_DIR . 'includes/functions/requirements.php';
20 +require_once GAMIPRESS_DIR . 'includes/functions/logs.php';
21 +require_once GAMIPRESS_DIR . 'includes/functions/user-earnings.php';
22 +require_once GAMIPRESS_DIR . 'includes/functions/attachments.php';
23 +require_once GAMIPRESS_DIR . 'includes/functions/date.php';
24 +require_once GAMIPRESS_DIR . 'includes/functions/html.php';
25 +require_once GAMIPRESS_DIR . 'includes/functions/helpers.php';
26 +
27 +/**
28 + * Helper function to get an option value.
29 + *
30 + * @since 1.0.1
31 + *
32 + * @param string $option_name
33 + * @param bool $default
34 + *
35 + * @return mixed Option value or default parameter value if not exists.
36 + */
37 +function gamipress_get_option( $option_name, $default = false ) {
38 +
39 + if( GamiPress()->settings === null ) {
40 +
41 + // If GamiPress is installed network wide, get settings from network options
42 + if( gamipress_is_network_wide_active() ) {
43 + GamiPress()->settings = get_site_option( 'gamipress_settings' );
44 + } else {
45 + GamiPress()->settings = get_option( 'gamipress_settings' );
46 + }
47 +
48 + }
49 +
50 + return isset( GamiPress()->settings[ $option_name ] ) ? GamiPress()->settings[ $option_name ] : $default;
51 +
52 +}
53 +
54 +/**
55 + * Helper function to get a transient value.
56 + *
57 + * @since 1.4.0
58 + *
59 + * @param string $transient
60 + *
61 + * @return mixed Value of transient.
62 + */
63 +function gamipress_get_transient( $transient ) {
64 +
65 + // If GamiPress is installed network wide, get transient from network
66 + if( gamipress_is_network_wide_active() ) {
67 + return get_site_transient( $transient );
68 + } else {
69 + return get_transient( $transient );
70 + }
71 +
72 +}
73 +
74 +/**
75 + * Helper function to set a transient value.
76 + *
77 + * @since 1.4.0
78 + *
79 + * @param string $transient
80 + * @param mixed $value
81 + * @param integer $expiration
82 + */
83 +function gamipress_set_transient( $transient, $value, $expiration = 0 ) {
84 +
85 + // If GamiPress is installed network wide, get transient from network
86 + if( gamipress_is_network_wide_active() ) {
87 + set_site_transient( $transient, $value, $expiration );
88 + } else {
89 + set_transient( $transient, $value, $expiration );
90 + }
91 +
92 +}
93 +
94 +/**
95 + * Helper function to delete a transient value.
96 + *
97 + * @since 1.4.0
98 + *
99 + * @param string $transient
100 + *
101 + * @return bool True if successful, false otherwise.
102 + */
103 +function gamipress_delete_transient( $transient ) {
104 +
105 + // If GamiPress is installed network wide, get transient from network
106 + if( gamipress_is_network_wide_active() ) {
107 + return delete_site_transient( $transient );
108 + } else {
109 + return delete_transient( $transient );
110 + }
111 +
112 +}
113 +
114 +/**
115 + * Helper function to get a list of users based in the current site if multisite is active.
116 + *
117 + * @since 2.1.5
118 + *
119 + * @param array $query_args Query parameters.
120 + * @param string $output Optional. Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants.
121 + *
122 + * @return array|null An array of users.
123 + */
124 +function gamipress_get_users( $query_args = array(), $output = OBJECT ) {
125 +
126 + global $wpdb;
127 +
128 + $query_args = wp_parse_args( $query_args, array(
129 + 'orderby' => 'u.ID ASC',
130 + 'offset' => 0,
131 + 'limit' => -1,
132 + ) );
133 +
134 + // FROM
135 + $from = "FROM {$wpdb->users} AS u ";
136 +
137 + // WHERE
138 + $where = '';
139 +
140 + // ORDER BY
141 + $orderby = $query_args['orderby'];
142 +
143 + if( ! empty( $orderby ) ) {
144 + $orderby = "ORDER BY {$orderby}";
145 + } else {
146 + $orderby = '';
147 + }
148 +
149 + // LIMIT
150 + $offset = $query_args['offset'];
151 + $limit = $query_args['limit'];
152 +
153 + if( $limit != -1 ) {
154 + $limit = "LIMIT {$offset}, {$limit}";
155 + } else {
156 + $limit = '';
157 + }
158 +
159 + // Multisite check
160 + if( is_multisite() ) {
161 + $from .= "LEFT JOIN {$wpdb->usermeta} AS umcap ON ( umcap.user_id = u.ID ) ";
162 +
163 + // Check if where have been initialized or not
164 + if( empty( $where ) ) {
165 + $where = "WHERE ";
166 + } else {
167 + $where .= "AND ";
168 + }
169 +
170 + $where .= "umcap.meta_key = '" . $wpdb->get_blog_prefix() . "capabilities' ";
171 + }
172 +
173 + // Get the stored users
174 + $users = $wpdb->get_results(
175 + "SELECT *
176 + {$from}
177 + {$where}
178 + {$orderby}
179 + {$limit}",
180 + $output
181 + );
182 +
183 + return $users;
184 +
185 +}
186 +
187 +/**
188 + * Helper function to get a count of users based in the current site if multisite is active.
189 + *
190 + * @since 2.1.5
191 + *
192 + * @param array $query_args Query parameters.
193 + *
194 + * @return int The number of users.
195 + */
196 +function gamipress_get_users_count( $query_args = array() ) {
197 +
198 + global $wpdb;
199 +
200 + // FROM
201 + $from = "FROM {$wpdb->users} AS u ";
202 +
203 + // WHERE
204 + $where = '';
205 +
206 + // Multisite check
207 + if( is_multisite() ) {
208 + $from .= "LEFT JOIN {$wpdb->usermeta} AS umcap ON ( umcap.user_id = u.ID ) ";
209 +
210 + // Check if where have been initialized or not
211 + if( empty( $where ) ) {
212 + $where = "WHERE ";
213 + } else {
214 + $where .= "AND ";
215 + }
216 +
217 + $where .= "umcap.meta_key = '" . $wpdb->get_blog_prefix() . "capabilities' ";
218 + }
219 +
220 + // Get the users count
221 + $users_count = absint( $wpdb->get_var(
222 + "SELECT COUNT(*)
223 + {$from}
224 + {$where}"
225 + ) );
226 +
227 + return $users_count;
228 +
229 +}
230 +
231 +/**
232 + * Helper function to get a user meta.
233 + *
234 + * @since 1.4.0
235 + *
236 + * @param int $user_id User ID.
237 + * @param string $meta_key Optional. The meta key to retrieve. By default, returns data for all keys.
238 + * @param bool $single Whether to return a single value.
239 + *
240 + * @return mixed Will be an array if $single is false. Will be value of meta data field if $single is true.
241 + */
242 +function gamipress_get_user_meta( $user_id, $meta_key = '', $single = true ) {
243 +
244 + if( is_multisite() ) {
245 + $global = gamipress_is_network_wide_active();
246 + return gamipress_get_user_option( $meta_key, $user_id, $global );
247 + } else {
248 + return get_user_meta( $user_id, $meta_key, $single );
249 + }
250 +
251 +}
252 +
253 +/**
254 + * Helper function to update a user meta.
255 + *
256 + * @since 1.4.0
257 + *
258 + * @param int $user_id User ID.
259 + * @param string $meta_key Metadata key.
260 + * @param mixed $meta_value Metadata value.
261 + * @param mixed $prev_value Optional. Previous value to check before removing.
262 + *
263 + * @return integer|bool Meta ID if the key didn't exist, true on successful update, false on failure.
264 + */
265 +function gamipress_update_user_meta( $user_id, $meta_key, $meta_value, $prev_value = '' ) {
266 +
267 + if( is_multisite() ) {
268 + $global = gamipress_is_network_wide_active();
269 + return update_user_option( $user_id, $meta_key, $meta_value, $global );
270 + } else {
271 + return update_user_meta( $user_id, $meta_key, $meta_value, $prev_value );
272 + }
273 +
274 +}
275 +
276 +/**
277 + * Helper function to delete a user meta.
278 + *
279 + * @since 1.4.0
280 + *
281 + * @param int $user_id User ID.
282 + * @param string $meta_key Metadata key.
283 + * @param mixed $meta_value Metadata value.
284 + *
285 + * @return bool True on success, false on failure.
286 + */
287 +function gamipress_delete_user_meta( $user_id, $meta_key, $meta_value = '' ) {
288 +
289 + if( is_multisite() ) {
290 + $global = gamipress_is_network_wide_active();
291 + return delete_user_option( $user_id, $meta_key, $global );
292 + } else {
293 + return delete_user_meta( $user_id, $meta_key, $meta_value );
294 + }
295 +
296 +}
297 +
298 +/**
299 + * Retrieves user option that can be either per Site or per Network.
300 + *
301 + * @since 2.0.0
302 + *
303 + * @global wpdb $wpdb WordPress database abstraction object.
304 + *
305 + * @param string $option User option name.
306 + * @param int $user_id Optional. User ID.
307 + * @param bool $global Optional. Whether option name is global or blog specific. Default false (blog specific).
308 + *
309 + * @return mixed User option value on success, false on failure.
310 + */
311 +function gamipress_get_user_option( $option, $user_id = 0, $global = false ) {
312 + global $wpdb;
313 +
314 + if ( empty( $user_id ) ) {
315 + return false;
316 + }
317 +
318 + $user = get_userdata( $user_id );
319 + if ( ! $user ) {
320 + return false;
321 + }
322 +
323 + $result = false;
324 +
325 + if( $global ) {
326 + if ( $user->has_prop( $option ) ) { // User-specific and cross-blog.
327 + $result = $user->get( $option );
328 + }
329 + } else {
330 + $prefix = $wpdb->get_blog_prefix();
331 +
332 + if ( $user->has_prop( $prefix . $option ) ) { // Blog-specific.
333 + $result = $user->get( $prefix . $option );
334 + }
335 + }
336 +
337 + /**
338 + * Filters a specific user option value.
339 + *
340 + * The dynamic portion of the hook name, `$option`, refers to the user option name.
341 + *
342 + * @since 2.5.0
343 + *
344 + * @param mixed $result Value for the user's option.
345 + * @param string $option Name of the option being retrieved.
346 + * @param WP_User $user WP_User object of the user whose option is being retrieved.
347 + */
348 + return apply_filters( "get_user_option_{$option}", $result, $option, $user );
349 +}
350 +
351 +/**
352 + * Helper function to get a post meta.
353 + *
354 + * Important: On network wide installs, this function will return the post meta from main site, so use only for points, achievements and ranks metas
355 + *
356 + * @since 1.4.0
357 + *
358 + * @param int $post_id Post ID.
359 + * @param string $meta_key Optional. The meta key to retrieve. By default, returns data for all keys.
360 + * @param bool $single Whether to return a single value.
361 + *
362 + * @return mixed Will be an array if $single is false. Will be value of meta data field if $single is true.
363 + */
364 +function gamipress_get_post_meta( $post_id, $meta_key = '', $single = true ) {
365 +
366 + if( gamipress_is_network_wide_active() && ! is_main_site() ) {
367 +
368 + // Switch to main site
369 + switch_to_blog( get_main_site_id() );
370 +
371 + // Get the post meta
372 + $value = get_post_meta( $post_id, $meta_key, $single );
373 +
374 + // Restore current site
375 + restore_current_blog();
376 +
377 + return $value;
378 +
379 + } else {
380 +
381 + return get_post_meta( $post_id, $meta_key, $single );
382 +
383 + }
384 +
385 +}
386 +
387 +/**
388 + * Helper function to update a post meta.
389 + *
390 + * Important: On network wide installs, this function will update the post meta from main site, so use only for points, achievements and ranks metas
391 + *
392 + * @since 1.4.0
393 + *
394 + * @param int $post_id Post ID.
395 + * @param string $meta_key Metadata key.
396 + * @param mixed $meta_value Metadata value.
397 + * @param mixed $prev_value Optional. Previous value to check before removing.
398 + *
399 + * @return integer|bool Meta ID if the key didn't exist, true on successful update, false on failure.
400 + */
401 +function gamipress_update_post_meta( $post_id, $meta_key, $meta_value, $prev_value = '' ) {
402 +
403 + if( gamipress_is_network_wide_active() && ! is_main_site() ) {
404 +
405 + // Switch to main site
406 + switch_to_blog( get_main_site_id() );
407 +
408 + $result = update_post_meta( $post_id, $meta_key, $meta_value, $prev_value );
409 +
410 + // Restore current site
411 + restore_current_blog();
412 +
413 + return $result;
414 +
415 + } else {
416 +
417 + return update_post_meta( $post_id, $meta_key, $meta_value, $prev_value );
418 +
419 + }
420 +
421 +}
422 +
423 +/**
424 + * Helper function to delete a post meta.
425 + *
426 + * Important: On network wide installs, this function will delete the post meta from main site, so use only for points, achievements and ranks metas
427 + *
428 + * @since 1.4.0
429 + *
430 + * @param int $post_id Post ID.
431 + * @param string $meta_key Metadata key.
432 + * @param mixed $meta_value Metadata value.
433 + *
434 + * @return bool True on success, false on failure.
435 + */
436 +function gamipress_delete_post_meta( $post_id, $meta_key, $meta_value = '' ) {
437 +
438 + if( gamipress_is_network_wide_active() && ! is_main_site() ) {
439 +
440 + // Switch to main site
441 + switch_to_blog( get_main_site_id() );
442 +
443 + $result = delete_post_meta( $post_id, $meta_key, $meta_value );
444 +
445 + // Restore current site
446 + restore_current_blog();
447 +
448 + return $result;
449 +
450 + } else {
451 + return delete_post_meta( $post_id, $meta_key, $meta_value );
452 + }
453 +
454 +}
455 +
456 +/**
457 + * Helper function to get a post.
458 + *
459 + * Important: On network wide installs, this function will return the post from main site, so use only for points, achievements and ranks posts
460 + *
461 + * @since 1.4.0
462 + * @updated 1.7.7 Make use of GamiPress cache feature to get network posts from cache
463 + *
464 + * @param int $post_id Post ID.
465 + *
466 + * @return false|WP_Post Post object on success, false on failure.
467 + */
468 +function gamipress_get_post( $post_id ) {
469 +
470 + // if we got a post object, then return their field
471 + if ( $post_id instanceof WP_Post ) {
472 + return $post_id;
473 + }
474 +
475 + global $wpdb;
476 +
477 + if( gamipress_is_network_wide_active() && ! is_main_site() ) {
478 +
479 + $cache = gamipress_get_cache( 'posts', array(), false );
480 +
481 + // If result already cached, return it
482 + if( isset( $cache[absint( $post_id )] ) ) {
483 + return $cache[absint( $post_id )];
484 + }
485 +
486 + // GamiPress post are stored on main site, so if we are not on main site, then we need to get their fields from global table
487 + $posts = GamiPress()->db->posts;
488 +
489 + $post = $wpdb->get_row( $wpdb->prepare(
490 + "SELECT * FROM {$posts} WHERE ID = %d",
491 + absint( $post_id )
492 + ) );
493 +
494 + // Cache network posts
495 + $cache[absint( $post_id )] = $post;
496 + gamipress_set_cache( 'posts', $cache );
497 +
498 + return $post;
499 +
500 + } else {
501 + return get_post( $post_id );
502 + }
503 +
504 +}
505 +
506 +/**
507 + * Helper function to get a post status.
508 + *
509 + * Important: On network wide installs, this function will return the post status from main site, so use only for points, achievements and ranks post status
510 + *
511 + * @since 1.4.0
512 + *
513 + * @param int $post_id Post ID.
514 + *
515 + * @return false|string Post status on success, false on failure.
516 + */
517 +function gamipress_get_post_status( $post_id = null ) {
518 + return gamipress_get_post_field( 'post_status', $post_id );
519 +}
520 +
521 +/**
522 + * Helper function to get a post type.
523 + *
524 + * Important: On network wide installs, this function will return the post type from main site, so use only for points, achievements and ranks post type
525 + *
526 + * @since 1.4.0
527 + *
528 + * @param int $post_id Post ID.
529 + *
530 + * @return false|string Post status on success, false on failure.
531 + */
532 +function gamipress_get_post_type( $post_id = null ) {
533 + return gamipress_get_post_field( 'post_type', $post_id );
534 +}
535 +
536 +/**
537 + * Helper function to get a post date.
538 + *
539 + * Important: On network wide installs, this function will return the post date from main site, so use only for points, achievements and ranks post date
540 + *
541 + * @since 1.4.0
542 + *
543 + * @param int $post_id Post ID.
544 + *
545 + * @return false|string Post status on success, false on failure.
546 + */
547 +function gamipress_get_post_date( $post_id = null ) {
548 + return gamipress_get_post_field( 'post_date', $post_id );
549 +}
550 +
551 +/**
552 + * Helper function to get a post field.
553 + *
554 + * Important: On network wide installs, this function will return the post field from main site, so use only for points, achievements and ranks posts fields
555 + *
556 + * @since 1.4.0
557 + * @updated 1.7.7 Make use of gamipress_get_post() function to get network posts fields from cache
558 + *
559 + * @param string $field The post field.
560 + * @param integer|WP_Post|null $post_id Post ID.
561 + *
562 + * @return false|string Post field on success, false on failure.
563 + */
564 +function gamipress_get_post_field( $field, $post_id = null ) {
565 +
566 + if ( empty( $post_id ) && isset( $GLOBALS['post'] ) )
567 + $post_id = $GLOBALS['post'];
568 +
569 + // if we got a post object, then return their field
570 + if ( $post_id instanceof WP_Post ) {
571 + return $post_id->$field;
572 + } else if( is_object( $post_id ) ) {
573 + return $post_id->$field;
574 + }
575 +
576 + if( gamipress_is_network_wide_active() && ! is_main_site() ) {
577 +
578 + $post = gamipress_get_post( $post_id );
579 +
580 + return ( $post ? $post->$field : null );
581 + } else {
582 + return get_post_field( $field, $post_id );
583 + }
584 +
585 +}
586 +
587 +/**
588 + * Helper function to check if a post exists.
589 + *
590 + * Important: On network wide installs, this function will check the post from main site, so use only for points, achievements and ranks posts
591 + *
592 + * @since 1.4.2
593 + *
594 + * @param integer $post_id Post ID.
595 + *
596 + * @return bool True if exists, false if not.
597 + */
598 +function gamipress_post_exists( $post_id ) {
599 +
600 + $post_id = absint( $post_id );
601 +
602 + if( $post_id === 0 )
603 + return false;
604 +
605 + $blog_id = get_current_blog_id();
606 +
607 + $cache = gamipress_get_cache( 'posts_exists_' . $blog_id, array(), false );
608 +
609 + // If result already cached, return it
610 + if( isset( $cache[$post_id] ) ) {
611 + return $cache[$post_id];
612 + }
613 +
614 + global $wpdb;
615 +
616 + // GamiPress post are stored on main site, so if we are not on main site, then we need to get their fields from global table
617 + $posts = GamiPress()->db->posts;
618 +
619 + $found = $wpdb->get_var( $wpdb->prepare(
620 + "SELECT ID FROM {$posts} WHERE ID = %d",
621 + $post_id
622 + ) );
623 +
624 + // Cache function result
625 + $cache[$post_id] = absint( $found ) === $post_id;
626 +
627 + gamipress_set_cache( 'posts_exists_' . $blog_id, $cache );
628 +
629 + return absint( $found ) === $post_id;
630 +}
631 +
632 +/**
633 + * Register GamiPress types and flush rewrite rules.
634 + *
635 + * @since 1.0.0
636 + */
637 +function gamipress_flush_rewrite_rules() {
638 + gamipress_register_post_types();
639 + gamipress_register_points_types();
640 + gamipress_register_achievement_types();
641 + gamipress_register_rank_types();
642 +
643 + flush_rewrite_rules();
644 +}
645 +
646 +/**
647 + * Utility to execute a shortcode passing an array of args
648 + *
649 + * @since 1.0.0
650 + * @updated 1.4.6 Added $content parameter
651 + * @updated 1.6.2 Sanitize attribute's value to avoid double quotes
652 + *
653 + * @param string $shortcode The shortcode to execute
654 + * @param array $args The args to pass to the shortcode
655 + * @param string $content Content to pass to the shortcode (optional)
656 + *
657 + * @return string $output Output from the shortcode execution with the given args
658 + */
659 +function gamipress_do_shortcode( $shortcode, $args, $content = '' ) {
660 +
661 + $shortcode_args = '';
662 +
663 + foreach( $args as $arg => $value ) {
664 +
665 + if( is_array( $value ) ) {
666 +
667 + if( array_keys( $value ) !== range( 0, count($value) - 1 ) ) {
668 +
669 + // Turn associative arrays into json to keep keys
670 + $value = str_replace( '"', '\'', json_encode( $value ) );
671 + $value = str_replace( '[', '{', $value );
672 + $value = str_replace( ']', '}', $value );
673 +
674 + } else {
675 +
676 + $is_multidimensional = false;
677 +
678 + foreach ($value as $value_items) {
679 + if ( is_array($value_items) ) {
680 + $is_multidimensional = true;
681 + break;
682 + }
683 + }
684 +
685 + if( $is_multidimensional ) {
686 + // Turn multidimensional arrays into json to keep inherit arrays
687 + $value = str_replace( '"', '\'', json_encode( $value ) );
688 + $value = str_replace( '[', '{', $value );
689 + $value = str_replace( ']', '}', $value );
690 + } else {
691 + // non associative and non multidimensional arrays, set a string of comma separated values
692 + $value = implode( ',', $value );
693 + }
694 +
695 + }
696 + }
697 +
698 + // Prevent attribute's value to have double quotes
699 + $value = str_replace( '"', '\'', $value );
700 +
701 + $shortcode_args .= sprintf( ' %s="%s"', $arg, $value);
702 + }
703 +
704 + if( ! empty( $content ) ) {
705 +
706 + // If content passed, then execute shortcode as [shortcode]content[/shortcode]
707 + return do_shortcode( sprintf( '[%s %s]%s[/%s]',
708 + $shortcode,
709 + $shortcode_args,
710 + $content,
711 + $shortcode
712 + ) );
713 +
714 + }
715 +
716 + return do_shortcode( sprintf( '[%s %s]', $shortcode, $shortcode_args ) );
717 +
718 +}
719 +
720 +/**
721 + * Sanitize given slug.
722 + *
723 + * @since 1.3.9.8
724 + *
725 + * @param string $slug Slug to sanitize.
726 + *
727 + * @return string Sanitized slug.
728 + */
729 +function gamipress_sanitize_slug( $slug ) {
730 +
731 + // Sanitize slug
732 + $slug = sanitize_key( $slug );
733 +
734 + // Check slug length
735 + if( strlen( $slug ) > 20 ) {
736 + $slug = substr( $slug, 0, 20 );
737 + }
738 +
739 + return $slug;
740 +
741 +}
742 +
743 +/**
744 + * Check if a specific action or filter has been hooked
745 + *
746 + * @since 1.4.3
747 + *
748 + * @param string $filter
749 + *
750 + * @return bool
751 + */
752 +function gamipress_has_filters( $filter ) {
753 +
754 + global $wp_filter;
755 +
756 + return (bool) ( isset( $wp_filter[$filter] ) && count( $wp_filter[$filter] ) > 0 );
757 +
758 +}
759 +
760 +/**
761 + * Sum all user meta values of a given meta key
762 + *
763 + * @since 1.5.9
764 + *
765 + * @param string $meta_key
766 + *
767 + * @return integer
768 + */
769 +function gamipress_get_user_meta_sum( $meta_key ) {
770 +
771 + global $wpdb;
772 +
773 + $sum = $wpdb->get_var( $wpdb->prepare(
774 + "SELECT SUM( meta_value )
775 + FROM {$wpdb->usermeta}
776 + WHERE meta_key = %s",
777 + $meta_key
778 + ) );
779 +
780 + return absint( $sum );
781 +
782 +}
783 +
784 +/**
785 + * Gets registered time periods
786 + *
787 + * @since 1.6.9
788 + *
789 + * @return array
790 + */
791 +function gamipress_get_time_periods() {
792 +
793 + /**
794 + * Filter registered time periods
795 + *
796 + * @since 1.6.9
797 + *
798 + * @param array $time_periods
799 + *
800 + * @return array
801 + */
802 + return apply_filters( 'gamipress_get_time_periods', array(
803 + '' => __( 'None', 'gamipress' ),
804 + 'today' => __( 'Today', 'gamipress' ),
805 + 'yesterday' => __( 'Yesterday', 'gamipress' ),
806 + 'this-week' => __( 'Current Week', 'gamipress' ),
807 + 'past-week' => __( 'Past Week', 'gamipress' ),
808 + 'this-month' => __( 'Current Month', 'gamipress' ),
809 + 'past-month' => __( 'Past Month', 'gamipress' ),
810 + 'this-year' => __( 'Current Year', 'gamipress' ),
811 + 'past-year' => __( 'Past Year', 'gamipress' ),
812 + 'custom' => __( 'Custom', 'gamipress' ),
813 + ) );
814 +
815 +}
816 +
817 +/**
818 + * Gets reserved terms
819 + *
820 + * @see https://codex.wordpress.org/Reserved_Terms
821 + *
822 + * @since 1.7.4
823 + *
824 + * @return array
825 + */
826 +function gamipress_get_reserved_terms() {
827 +
828 + $reserved_terms = array(
829 + 'attachment',
830 + 'attachment_id',
831 + 'author',
832 + 'author_name',
833 + 'calendar',
834 + 'cat',
835 + 'category',
836 + 'category__and',
837 + 'category__in',
838 + 'category__not_in',
839 + 'category_name',
840 + 'comments_per_page',
841 + 'comments_popup',
842 + 'cpage',
843 + 'day',
844 + 'debug',
845 + 'error',
846 + 'exact',
847 + 'feed',
848 + 'hour',
849 + 'link_category',
850 + 'm',
851 + 'minute',
852 + 'monthnum',
853 + 'more',
854 + 'name',
855 + 'nav_menu',
856 + 'nopaging',
857 + 'offset',
858 + 'order',
859 + 'orderby',
860 + 'p',
861 + 'page',
862 + 'page_id',
863 + 'paged',
864 + 'pagename',
865 + 'pb',
866 + 'perm',
867 + 'post',
868 + 'post__in',
869 + 'post__not_in',
870 + 'post_format',
871 + 'post_mime_type',
872 + 'post_status',
873 + 'post_tag',
874 + 'post_type',
875 + 'posts',
876 + 'posts_per_archive_page',
877 + 'posts_per_page',
878 + 'preview',
879 + 'robots',
880 + 's',
881 + 'search',
882 + 'second',
883 + 'sentence',
884 + 'showposts',
885 + 'static',
886 + 'subpost',
887 + 'subpost_id',
888 + 'tag',
889 + 'tag__and',
890 + 'tag__in',
891 + 'tag__not_in',
892 + 'tag_id',
893 + 'tag_slug__and',
894 + 'tag_slug__in',
895 + 'taxonomy',
896 + 'tb',
897 + 'term',
898 + 'type',
899 + 'w',
900 + 'withcomments',
901 + 'withoutcomments',
902 + 'year',
903 + );
904 +
905 + /**
906 + * Filter reserved terms
907 + *
908 + * @since 1.7.4
909 + *
910 + * @param array $reserved_terms
911 + *
912 + * @return array
913 + */
914 + return apply_filters( 'gamipress_get_reserved_terms', $reserved_terms );
915 +
916 +}
917 +
918 +/**
919 + * Get registered layout options
920 + *
921 + * @since 2.0.0
922 + *
923 + * @return array
924 + */
925 +function gamipress_get_layout_options() {
926 +
927 + /**
928 + * Filter registered layout options
929 + *
930 + * @since 2.0.0
931 + *
932 + * @param array $layout_options
933 + *
934 + * @return array
935 + */
936 + return apply_filters( 'gamipress_layout_options', array(
937 + 'left' => '<img src="' . GAMIPRESS_URL . 'assets/img/layout-left.svg">' . __( 'Left', 'gamipress' ),
938 + 'top' => '<img src="' . GAMIPRESS_URL . 'assets/img/layout-top.svg">' . __( 'Top', 'gamipress' ),
939 + 'right' => '<img src="' . GAMIPRESS_URL . 'assets/img/layout-right.svg">' . __( 'Right', 'gamipress' ),
940 + 'bottom' => '<img src="' . GAMIPRESS_URL . 'assets/img/layout-bottom.svg">' . __( 'Bottom', 'gamipress' ),
941 + 'none' => '<img src="' . GAMIPRESS_URL . 'assets/img/layout-none.svg">' . __( 'None', 'gamipress' ),
942 + ) );
943 +
944 +}
945 +
946 +/**
947 + * Get registered alignment options
948 + *
949 + * @since 2.0.0
950 + *
951 + * @return array
952 + */
953 +function gamipress_get_alignment_options() {
954 +
955 + /**
956 + * Filter registered layout options
957 + *
958 + * @since 2.0.0
959 + *
960 + * @param array $layout_options
961 + *
962 + * @return array
963 + */
964 + return apply_filters( 'gamipress_alignment_options', array(
965 + 'none' => '<img src="' . GAMIPRESS_URL . 'assets/img/align-' . ( is_rtl() ? 'right' : 'left' ) . '.svg">' . __( 'None', 'gamipress' ),
966 + 'left' => '<img src="' . GAMIPRESS_URL . 'assets/img/align-left.svg">' . __( 'Left', 'gamipress' ),
967 + 'center' => '<img src="' . GAMIPRESS_URL . 'assets/img/align-center.svg">' . __( 'Center', 'gamipress' ),
968 + 'right' => '<img src="' . GAMIPRESS_URL . 'assets/img/align-right.svg">' . __( 'Right', 'gamipress' ),
969 + 'justify' => '<img src="' . GAMIPRESS_URL . 'assets/img/align-justify.svg">' . __( 'Justify', 'gamipress' ),
970 +
971 + ) );
972 +
973 +}
974 +
975 +/**
976 + * Sanitize achievement types for shortcodes
977 + *
978 + * @since 6.0.0
979 + *
980 + * @param array $achievement_types
981 + *
982 + * @return array
983 + */
984 +function gamipress_sanitize_achievement_types_slugs_array( $achievement_types ) {
985 +
986 + $sanitize_achievement_types = array();
987 +
988 + foreach ( $achievement_types as $index => $achievement_type ){
989 +
990 + if ( !in_array( $achievement_type, gamipress_get_achievement_types_slugs(), true ) ){
991 + unset( $achievement_types[$index] );
992 + }
993 + }
994 + $sanitize_achievement_types = array_merge( $sanitize_achievement_types, $achievement_types );
995 +
996 + return $sanitize_achievement_types;
997 +
998 +}
999 +
1000 +/**
1001 + * Sanitize rank types for shortcodes
1002 + *
1003 + * @since 6.0.0
1004 + *
1005 + * @param array $rank_types
1006 + *
1007 + * @return array
1008 + */
1009 +function gamipress_sanitize_rank_types_slugs_array( $rank_types ) {
1010 +
1011 + $sanitize_rank_types = array();
1012 +
1013 + foreach ( $rank_types as $index => $rank_type ){
1014 +
1015 + if ( !in_array( $rank_type, gamipress_get_rank_types_slugs(), true ) ){
1016 + unset( $rank_types[$index] );
1017 + }
1018 + }
1019 + $sanitize_rank_types = array_merge( $sanitize_rank_types, $rank_types );
1020 +
1021 + return $sanitize_rank_types;
1022 +
1023 +}
1024 +
1025 +/**
1026 + * Sanitize point types for shortcodes
1027 + *
1028 + * @since 6.0.0
1029 + *
1030 + * @param array $point_types
1031 + *
1032 + * @return array
1033 + */
1034 +function gamipress_sanitize_point_types_slugs_array( $point_types ) {
1035 +
1036 + $sanitize_point_types = array();
1037 +
1038 + foreach ( $point_types as $index => $point_type ){
1039 +
1040 + if ( !in_array( $point_type, gamipress_get_points_types_slugs(), true ) ){
1041 + unset( $point_types[$index] );
1042 + }
1043 + }
1044 + $sanitize_point_types = array_merge( $sanitize_point_types, $point_types );
1045 +
1046 + return $sanitize_point_types;
1047 +
1048 +}
1049 +
1050 +/**
1051 + * Registered title sizes for shortcodes
1052 + *
1053 + * @since 6.0.0
1054 + *
1055 + * @param array $point_types
1056 + *
1057 + * @return array
1058 + */
1059 +function gamipress_title_size_options() {
1060 +
1061 + $options = array(
1062 + 'h1' => __( 'Heading 1', 'gamipress' ),
1063 + 'h2' => __( 'Heading 2', 'gamipress' ),
1064 + 'h3' => __( 'Heading 3', 'gamipress' ),
1065 + 'h4' => __( 'Heading 4', 'gamipress' ),
1066 + 'h5' => __( 'Heading 5', 'gamipress' ),
1067 + 'h6' => __( 'Heading 6', 'gamipress' ),
1068 + 'p' => __( 'Paragraph', 'gamipress' ),
1069 + );
1070 +
1071 + return apply_filters( 'gamipress_title_size_options', $options );
1072 +
1073 +}
1074 +
1075 +/**
1076 + * Sanitize title size for shortcodes
1077 + *
1078 + * @since 6.0.0
1079 + *
1080 + * @param array $point_types
1081 + *
1082 + * @return array
1083 + */
1084 +function gamipress_sanitize_title_size_option( $option ) {
1085 +
1086 + $options = gamipress_title_size_options();
1087 +
1088 + if( ! isset( $options[$option] ) ) {
1089 + return 'h2';
1090 + }
1091 +
1092 + return $option;
1093 +
1094 +}