| @@ -1,0 +1,270 @@ | ||
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Users Functions | |
| 4 | + * | |
| 5 | + * @package GamiPress\Users_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 | +/** | |
| 13 | + * Register user's meta | |
| 14 | + * | |
| 15 | + * @since 1.8.0 | |
| 16 | + */ | |
| 17 | +function gamipress_register_users_metas() { | |
| 18 | + | |
| 19 | + // Points types | |
| 20 | + foreach( gamipress_get_points_types() as $points_type => $data ) { | |
| 21 | + $meta_args = array( | |
| 22 | + 'type' => 'integer', | |
| 23 | + 'description' => sprintf( __( '%s balance', 'gamipress' ), $data['plural_name'] ), | |
| 24 | + 'single' => true, | |
| 25 | + 'show_in_rest' => true, | |
| 26 | + 'sanitize_callback' => 'absint', | |
| 27 | + 'auth_callback' => '__return_true' | |
| 28 | + ); | |
| 29 | + | |
| 30 | + /** | |
| 31 | + * Filters the points type meta arguments | |
| 32 | + * | |
| 33 | + * @since 1.8.0 | |
| 34 | + * | |
| 35 | + * @param array $meta_args Meta arguments that will be passed to register_meta() function | |
| 36 | + * @param string $points_type Points type's slug | |
| 37 | + * @param array $data Points type's data | |
| 38 | + */ | |
| 39 | + apply_filters( "gamipress_register_{$points_type}_meta_args", $meta_args, $points_type, $data ); | |
| 40 | + | |
| 41 | + register_meta( 'user', "_gamipress_{$points_type}_points", $meta_args ); | |
| 42 | + } | |
| 43 | + | |
| 44 | + // Rank types | |
| 45 | + foreach( gamipress_get_rank_types() as $rank_type => $data ) { | |
| 46 | + $meta_args = array( | |
| 47 | + 'type' => 'integer', | |
| 48 | + 'description' => sprintf( __( 'Current %s', 'gamipress' ), $data['singular_name'] ), | |
| 49 | + 'single' => true, | |
| 50 | + 'show_in_rest' => true, | |
| 51 | + 'sanitize_callback' => 'absint', | |
| 52 | + 'auth_callback' => '__return_true' | |
| 53 | + ); | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * Filters the rank type meta arguments | |
| 57 | + * | |
| 58 | + * @since 1.8.0 | |
| 59 | + * | |
| 60 | + * @param array $meta_args Meta arguments that will be passed to register_meta() function | |
| 61 | + * @param string $rank_type Rank type's slug | |
| 62 | + * @param array $data Rank type's data | |
| 63 | + */ | |
| 64 | + apply_filters( "gamipress_register_{$rank_type}_meta_args", $meta_args, $rank_type, $data ); | |
| 65 | + | |
| 66 | + register_meta( 'user', "_gamipress_{$rank_type}_rank", $meta_args ); | |
| 67 | + } | |
| 68 | + | |
| 69 | +} | |
| 70 | +add_action( 'init', 'gamipress_register_users_metas' ); | |
| 71 | + | |
| 72 | +/** | |
| 73 | + * Remove all user logs and earnings when is deleted from the database. | |
| 74 | + * | |
| 75 | + * @since 1.8.0 | |
| 76 | + * | |
| 77 | + * @param int $id ID of the user to delete. | |
| 78 | + * @param int|null $reassign ID of the user to reassign posts and links to (Default null, for no reassignment). | |
| 79 | + */ | |
| 80 | +function gamipress_on_delete_user( $id, $reassign ) { | |
| 81 | + | |
| 82 | + global $wpdb; | |
| 83 | + | |
| 84 | + $user_earnings = GamiPress()->db->user_earnings; | |
| 85 | + $user_earnings_meta = GamiPress()->db->user_earnings_meta; | |
| 86 | + $logs = GamiPress()->db->logs; | |
| 87 | + $logs_meta = GamiPress()->db->logs_meta; | |
| 88 | + | |
| 89 | + // Delete all user's earnings | |
| 90 | + $wpdb->query( "DELETE ue FROM {$user_earnings} AS ue WHERE ue.user_id = {$id}" ); | |
| 91 | + // Delete orphaned user earnings metas | |
| 92 | + $wpdb->query( "DELETE uem FROM {$user_earnings_meta} uem INNER JOIN {$user_earnings} ue ON ue.user_earning_id = uem.user_earning_id WHERE ue.user_earning_id IS NULL" ); | |
| 93 | + | |
| 94 | + // Delete all user's logs | |
| 95 | + $wpdb->query( "DELETE l FROM {$logs} AS l WHERE l.user_id = {$id}" ); | |
| 96 | + // Delete orphaned logs metas | |
| 97 | + $wpdb->query( "DELETE lm FROM {$logs_meta} lm INNER JOIN {$logs} l ON l.log_id = lm.log_id WHERE l.log_id IS NULL" ); | |
| 98 | + | |
| 99 | +} | |
| 100 | +add_action( 'delete_user', 'gamipress_on_delete_user', 10, 2 ); | |
| 101 | + | |
| 102 | +/** | |
| 103 | + * Get user's achievements | |
| 104 | + * | |
| 105 | + * @since 1.0.0 | |
| 106 | + * @updated 1.6.3 Return an empty array if not user provided or current user is not logged in | |
| 107 | + * | |
| 108 | + * @param array $args An array of all our relevant arguments | |
| 109 | + * | |
| 110 | + * @return array An array of all the achievement objects that matched our parameters, or empty if none | |
| 111 | + */ | |
| 112 | +function gamipress_get_user_achievements( $args = array() ) { | |
| 113 | + | |
| 114 | + // Setup our default args | |
| 115 | + $defaults = array( | |
| 116 | + 'user_id' => 0, // The given user's ID | |
| 117 | + 'site_id' => get_current_blog_id(), // The given site's ID | |
| 118 | + 'achievement_id' => false, // A specific achievement's post ID | |
| 119 | + 'achievement_type' => false, // A specific achievement type | |
| 120 | + 'since' => 0, // A specific timestamp to use in place of $limit_in_days | |
| 121 | + 'limit' => -1, // Limit of achievements to return | |
| 122 | + 'groupby' => false, // Group by clause, setting it to 'post_id' or 'achievement_id' will prevent duplicated achievements | |
| 123 | + ); | |
| 124 | + | |
| 125 | + $args = wp_parse_args( $args, $defaults ); | |
| 126 | + | |
| 127 | + // Use current user's ID if none specified | |
| 128 | + if ( ! $args['user_id'] ) { | |
| 129 | + $args['user_id'] = get_current_user_id(); | |
| 130 | + } | |
| 131 | + | |
| 132 | + // Bail if not user provided or current user is not logged in | |
| 133 | + if( absint( $args['user_id'] ) === 0 ) { | |
| 134 | + return array(); | |
| 135 | + } | |
| 136 | + | |
| 137 | + // Setup CT object | |
| 138 | + $ct_table = ct_setup_table( 'gamipress_user_earnings' ); | |
| 139 | + | |
| 140 | + // Bail if table not yet created | |
| 141 | + if( ! is_object( $ct_table ) ) { | |
| 142 | + return array(); | |
| 143 | + } | |
| 144 | + | |
| 145 | + // Setup query args | |
| 146 | + $query_args = array( | |
| 147 | + 'user_id' => $args['user_id'], | |
| 148 | + 'items_per_page' => $args['limit'], | |
| 149 | + ); | |
| 150 | + | |
| 151 | + if( $args['limit'] === -1 ) { | |
| 152 | + $query_args['nopaging'] = true; | |
| 153 | + } | |
| 154 | + | |
| 155 | + if( $args['achievement_id'] !== false ) { | |
| 156 | + $query_args['post_id'] = $args['achievement_id']; | |
| 157 | + } | |
| 158 | + | |
| 159 | + if( $args['achievement_type'] !== false ) { | |
| 160 | + $query_args['post_type'] = $args['achievement_type']; | |
| 161 | + } | |
| 162 | + | |
| 163 | + if( $args['groupby'] !== false ) { | |
| 164 | + $query_args['groupby'] = $args['groupby']; | |
| 165 | + | |
| 166 | + // achievement_id is allowed | |
| 167 | + if( $args['groupby'] === 'achievement_id' ) { | |
| 168 | + $query_args['groupby'] = 'post_id'; | |
| 169 | + } | |
| 170 | + } | |
| 171 | + | |
| 172 | + if( $args['since'] !== 0 ) { | |
| 173 | + $query_args['since'] = $args['since']; | |
| 174 | + } | |
| 175 | + | |
| 176 | + $ct_query = new CT_Query( $query_args ); | |
| 177 | + | |
| 178 | + $results = $ct_query->get_results(); | |
| 179 | + | |
| 180 | + $achievements = array(); | |
| 181 | + | |
| 182 | + foreach ( $results as $key => $achievement ) { | |
| 183 | + | |
| 184 | + // Unset if achievement is NULL | |
| 185 | + if( is_null( $achievement ) ) { | |
| 186 | + unset( $results[$key] ); | |
| 187 | + continue; | |
| 188 | + } | |
| 189 | + | |
| 190 | + // Update object for backward compatibility for usages previously to 1.2.7 | |
| 191 | + $achievement->ID = $achievement->post_id; | |
| 192 | + $achievement->date_earned = strtotime( $achievement->date ); | |
| 193 | + | |
| 194 | + // If achievements earned will be displayed, then need to pass some filters | |
| 195 | + if( isset( $args['display'] ) && $args['display'] ) { | |
| 196 | + | |
| 197 | + // If not existent achievements | |
| 198 | + if( ! gamipress_post_exists( $achievement->post_id ) ) { | |
| 199 | + continue; | |
| 200 | + } | |
| 201 | + | |
| 202 | + // If not published achievements | |
| 203 | + if( gamipress_get_post_field( 'post_status', $achievement->post_id ) !== 'publish' ) { | |
| 204 | + continue; | |
| 205 | + } | |
| 206 | + | |
| 207 | + // If hidden achievements on display context | |
| 208 | + if( gamipress_is_achievement_hidden( $achievement->post_id ) ) { | |
| 209 | + continue; | |
| 210 | + } | |
| 211 | + | |
| 212 | + } | |
| 213 | + | |
| 214 | + $achievements[$key] = $achievement; | |
| 215 | + | |
| 216 | + } | |
| 217 | + | |
| 218 | + ct_reset_setup_table(); | |
| 219 | + | |
| 220 | + return $achievements; | |
| 221 | + | |
| 222 | +} | |
| 223 | + | |
| 224 | +/** | |
| 225 | + * Updates the user's earned achievements | |
| 226 | + * | |
| 227 | + * @since 1.0.0 | |
| 228 | + * | |
| 229 | + * @param array $args An array containing all our relevant arguments | |
| 230 | + * | |
| 231 | + * @return bool The updated umeta ID on success, false on failure | |
| 232 | + */ | |
| 233 | +function gamipress_update_user_achievements( $args = array() ) { | |
| 234 | + | |
| 235 | + // Setup our default args | |
| 236 | + $defaults = array( | |
| 237 | + 'user_id' => 0, // The given user's ID | |
| 238 | + 'site_id' => get_current_blog_id(), // The given site's ID | |
| 239 | + 'new_achievements' => false, // An array of NEW achievements earned by the user | |
| 240 | + ); | |
| 241 | + | |
| 242 | + $args = wp_parse_args( $args, $defaults ); | |
| 243 | + | |
| 244 | + // Use current user's ID if none specified | |
| 245 | + if ( ! $args['user_id'] ) | |
| 246 | + $args['user_id'] = get_current_user_id(); | |
| 247 | + | |
| 248 | + // Lets to append the new achievements array | |
| 249 | + if ( is_array( $args['new_achievements'] ) && ! empty( $args['new_achievements'] ) ) { | |
| 250 | + | |
| 251 | + foreach( $args['new_achievements'] as $new_achievement ) { | |
| 252 | + | |
| 253 | + $user_earning_data = array( | |
| 254 | + 'title' => gamipress_get_post_field( 'post_title', $new_achievement->ID ), | |
| 255 | + 'post_id' => $new_achievement->ID, | |
| 256 | + 'post_type' => $new_achievement->post_type, | |
| 257 | + 'points' => absint( $new_achievement->points ), | |
| 258 | + 'points_type' => $new_achievement->points_type, | |
| 259 | + 'date' => date( 'Y-m-d H:i:s', $new_achievement->date_earned ) | |
| 260 | + ); | |
| 261 | + | |
| 262 | + gamipress_insert_user_earning( absint( $args['user_id'] ), $user_earning_data ); | |
| 263 | + | |
| 264 | + } | |
| 265 | + | |
| 266 | + } | |
| 267 | + | |
| 268 | + return true; | |
| 269 | + | |
| 270 | +} | |