/** * Delete a user's progress for an achievement. Essentially, un-reward the achievement for this user. * * @param int $achievement_id Achievement ID * @param int $user_id User ID * @since Achievements (3.0) */ function dpa_delete_achievement_progress($achievement_id, $user_id) { $achievement_id = dpa_get_achievement_id($achievement_id); if (empty($achievement_id) || !dpa_is_achievement($achievement_id)) { return; } $progress_id = dpa_get_progress(array('author' => $user_id, 'fields' => 'ids', 'no_found_rows' => true, 'nopaging' => true, 'numberposts' => 1, 'post_parent' => $achievement_id)); if (empty($progress_id)) { return; } $progress_id = apply_filters('dpa_delete_achievement_progress', array_pop($progress_id), $achievement_id, $user_id); do_action('dpa_before_delete_achievement_progress', $progress_id, $achievement_id, $user_id); wp_delete_post($progress_id, true); // Check that the delete achievement isn't in the user's pending notifications $notifications = dpa_get_user_notifications($user_id); if (isset($notifications[$achievement_id])) { unset($notifications[$achievement_id]); } // Update the user's notifications in case we cleared any above dpa_update_user_notifications($notifications, $user_id); // Decrease user unlocked count dpa_update_user_unlocked_count($user_id, dpa_get_user_unlocked_count($user_id) - 1); /** * If the progress was linked to an achievement that is the same achievement that is stored in * this user's "last unlocked" meta, then clear the "last unlocked" meta, too. */ if ((int) dpa_get_user_last_unlocked($user_id) === $achievement_id) { dpa_update_user_last_unlocked($user_id, 0); } do_action('dpa_after_delete_achievement_progress', $progress_id, $achievement_id, $user_id); }
/** * Display the contents of a specific achievement ID in an output buffer * and return to ensure that post/page contents are displayed first. * * @param array $attr * @param string $content Optional * @return string Contents of output buffer * @since Achievements (3.0) */ public function display_achievement($attr, $content = '') { // Sanity check required info if (!empty($content) || (empty($attr['id']) || !is_numeric($attr['id']))) { return $content; } $this->unset_globals(); // Set passed attribute to $achievement_id for clarity $achievement_id = achievements()->current_achievement_id = absint($attr['id']); // Bail if ID passed is not an achievement if (!dpa_is_achievement($achievement_id)) { return $content; } // If not in theme compat, reset necessary achievement_query attributes for achievements loop to function if (!dpa_is_theme_compat_active()) { achievements()->achievement_query->query_vars['post_type'] = dpa_get_achievement_post_type(); achievements()->achievement_query->in_the_loop = true; achievements()->achievement_query->post = get_post($achievement_id); } $this->start('dpa_single_achievement'); dpa_get_template_part('content-single-achievement'); return $this->end(); }
/** * Has a specific user unlocked a specific achievement? * * @param int $user_id * @param int $achievement_id * @return bool True if user has unlocked the achievement * @since Achievements (3.4) */ function dpa_has_user_unlocked_achievement($user_id, $achievement_id) { if (!dpa_is_user_active($user_id)) { return false; } $achievement_id = dpa_get_achievement_id($achievement_id); if (empty($achievement_id) || !dpa_is_achievement($achievement_id)) { return false; } // Try to fetched an unlocked progress item for this user pair/achievement pair $progress = dpa_get_progress(array('author' => $user_id, 'fields' => 'ids', 'no_found_rows' => true, 'nopaging' => true, 'numberposts' => 1, 'post_parent' => $achievement_id, 'post_status' => dpa_get_unlocked_status_id())); return apply_filters('dpa_has_user_unlocked_achievement', !empty($progress), $progress, $user_id, $achievement_id); }