/** * Implements the Achievement actions and unlocks if criteria met. * * @see dpa_register_events() * @since Achievements (3.0) */ function dpa_handle_event() { // Look at the current_filter to find out what action has occured $event_name = current_filter(); $func_args = func_get_args(); // Let other plugins do things before anything happens do_action('dpa_before_handle_event', $event_name, $func_args); // Allow other plugins to change the name of the event being processed, or to bail out early $event_name = apply_filters('dpa_handle_event_name', $event_name, $func_args); if (false === $event_name) { return; } /** * Extensions using the DPA_CPT_Extension base class may not capture their generic CPT * actions if that same action was used with by another extension with a different post * type. As no achievement will ever be associated with a generic action, if we're about * to query for a generic action, bail out. */ foreach (achievements()->extensions as $extension) { if (!is_a($extension, 'DPA_CPT_Extension')) { continue; } // Is $event_name a generic CPT action? if (in_array($event_name, $extension->get_generic_cpt_actions(array()))) { return; } } // This filter allows the user ID to be updated (e.g. for draft posts which are then published by someone else) $user_id = absint(apply_filters('dpa_handle_event_user_id', get_current_user_id(), $event_name, $func_args)); if (!$user_id) { return; } // Only proceed if the specified user is active (logged in and not a spammer) if (!dpa_is_user_active($user_id)) { return; } // Only proceed if the specified user can create progress posts if (!user_can($user_id, 'publish_achievement_progresses')) { return; } // Find achievements that are associated with the $event_name taxonomy $args = array('ach_event' => $event_name, 'ach_populate_progress' => $user_id, 'no_found_rows' => true, 'nopaging' => true, 'post_status' => 'any', 'posts_per_page' => -1, 's' => ''); // If multisite and running network-wide, switch_to_blog to the data store site if (is_multisite() && dpa_is_running_networkwide()) { switch_to_blog(DPA_DATA_STORE); } // Loop through achievements found if (dpa_has_achievements($args)) { while (dpa_achievements()) { dpa_the_achievement(); // Check that the post status is published or privately published // We need to check this here to work around WP_Query not // constructing the query correctly with private if (!in_array($GLOBALS['post']->post_status, array('publish', 'private'))) { continue; } // Let other plugins do things before we maybe_unlock_achievement do_action('dpa_handle_event', $event_name, $func_args, $user_id, $args); // Allow plugins to stop any more processing for this achievement if (false === apply_filters('dpa_handle_event_maybe_unlock_achievement', true, $event_name, $func_args, $user_id, $args)) { continue; } // Look in the progress posts and match against a post_parent which is the same as the current achievement. $progress = wp_filter_object_list(achievements()->progress_query->posts, array('post_parent' => dpa_get_the_achievement_ID())); $progress = array_shift($progress); // If the achievement hasn't already been unlocked, maybe_unlock_achievement. if (empty($progress) || dpa_get_unlocked_status_id() !== $progress->post_status) { dpa_maybe_unlock_achievement($user_id, false, $progress); } } } // If multisite and running network-wide, undo the switch_to_blog if (is_multisite() && dpa_is_running_networkwide()) { restore_current_blog(); } achievements()->achievement_query = new WP_Query(); achievements()->leaderboard_query = new ArrayObject(); achievements()->progress_query = new WP_Query(); // Everything's done. Let other plugins do things. do_action('dpa_after_handle_event', $event_name, $func_args, $user_id, $args); }
/** * Add the 'User Points' box to Edit User page, and a list of the user's current achievements. * * @param WP_User $user * @since Achievements (3.0) */ public function add_profile_fields(WP_User $user) { if (!is_super_admin()) { return; } ?> <h3><?php _e('Achievements Settings', 'achievements'); ?> </h3> <table class="form-table"> <tr> <th><label for="dpa_achievements"><?php _ex('Total Points', "User’s total points from unlocked Achievements", 'achievements'); ?> </label></th> <td><input type="number" name="dpa_achievements" id="dpa_achievements" value="<?php echo (int) dpa_get_user_points($user->ID); ?> " class="regular-text" /> </td> </tr> <?php if (dpa_has_achievements(array('ach_populate_progress' => $user->ID, 'ach_progress_status' => dpa_get_unlocked_status_id(), 'posts_per_page' => -1))) { ?> <tr> <th scope="row"><?php _e('Unlocked Achievements', 'achievements'); ?> </th> <td> <fieldset> <legend class="screen-reader-text"><?php _e('Assign or remove achievements from this user', 'achievements'); ?> </legend> <?php while (dpa_achievements()) { ?> <?php dpa_the_achievement(); ?> <label><input type="checkbox" name="dpa_user_achievements[]" value="<?php echo absint(dpa_get_the_achievement_ID()); ?> " <?php checked(dpa_is_achievement_unlocked(), true); ?> > <?php dpa_achievement_title(); ?> </label><br> <?php } ?> </fieldset> </td> </tr> <?php } ?> </table> <?php }