Ejemplo n.º 1
0
/**
 * The Progress post type loop.
 *
 * @param array|string $args All the arguments supported by {@link WP_Query}, and some more.
 * @return bool Returns true if the query has any results to loop over
 * @since Achievements (3.0)
 */
function dpa_has_progress($args = array())
{
    // 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);
    }
    $defaults = array('ignore_sticky_posts' => true, 'max_num_pages' => false, 'order' => 'DESC', 'orderby' => 'date', 'paged' => dpa_get_paged(), 'post_status' => dpa_get_unlocked_status_id(), 'post_type' => dpa_get_progress_post_type(), 's' => '', 'author' => dpa_is_single_user_achievements() ? dpa_get_displayed_user_id() : null, 'post_parent' => dpa_is_single_achievement() ? dpa_get_achievement_id() : null, 'posts_per_page' => -1, 'ach_populate_achievements' => dpa_is_single_user_achievements() && is_a(achievements()->achievement_query, 'WP_Query') && empty(achievements()->achievement_query->request));
    $args = dpa_parse_args($args, $defaults, 'has_progress');
    // Run the query
    achievements()->progress_query = new WP_Query($args);
    // If no limit to posts per page, set it to the current post_count
    if (-1 === (int) $args['posts_per_page']) {
        $args['posts_per_page'] = achievements()->progress_query->post_count;
    }
    // Add pagination values to query object
    achievements()->progress_query->posts_per_page = $args['posts_per_page'];
    achievements()->progress_query->paged = $args['paged'];
    // Only add pagination if query returned results
    if (((int) achievements()->progress_query->post_count || (int) achievements()->progress_query->found_posts) && (int) achievements()->progress_query->posts_per_page) {
        // Limit the number of achievements shown based on maximum allowed pages
        if (!empty($args['max_num_pages']) && achievements()->progress_query->found_posts > achievements()->progress_query->max_num_pages * achievements()->progress_query->post_count) {
            achievements()->progress_query->found_posts = achievements()->progress_query->max_num_pages * achievements()->progress_query->post_count;
        }
        // If pretty permalinks are enabled, make our pagination pretty
        if ($GLOBALS['wp_rewrite']->using_permalinks()) {
            // Page or single post
            if (is_page() || is_single()) {
                $base = get_permalink();
            } elseif (dpa_is_single_user_achievements()) {
                $base = dpa_get_user_avatar_link(array('type' => 'url', 'user_id' => dpa_get_displayed_user_id()));
            } else {
                $base = get_permalink($args['post_parent']);
            }
            // Use pagination base
            $base = trailingslashit($base) . user_trailingslashit($GLOBALS['wp_rewrite']->pagination_base . '/%#%/');
            // Unpretty pagination
        } else {
            $base = add_query_arg('paged', '%#%');
        }
        // Pagination settings with filter
        $progress_pagination = apply_filters('dpa_progress_pagination', array('base' => $base, 'current' => (int) achievements()->progress_query->paged, 'format' => '', 'mid_size' => 1, 'next_text' => is_rtl() ? '←' : '→', 'prev_text' => is_rtl() ? '→' : '←', 'total' => $args['posts_per_page'] == achievements()->progress_query->found_posts ? 1 : ceil((int) achievements()->progress_query->found_posts / (int) $args['posts_per_page'])));
        // Add pagination to query object
        achievements()->progress_query->pagination_links = paginate_links($progress_pagination);
        // Remove first page from pagination
        achievements()->progress_query->pagination_links = str_replace($GLOBALS['wp_rewrite']->pagination_base . "/1/'", "'", achievements()->progress_query->pagination_links);
    }
    // If on a user's achievements page, we need to fetch the achievements
    if ($args['ach_populate_achievements'] && achievements()->progress_query->have_posts()) {
        $achievement_ids = wp_list_pluck((array) achievements()->progress_query->posts, 'post_parent');
        $achievement_args = array('order' => $args['order'], 'orderby' => $args['orderby'], 'post__in' => $achievement_ids, 'posts_per_page' => -1);
        // Run the query
        dpa_has_achievements($achievement_args);
    }
    // If multisite and running network-wide, undo the switch_to_blog
    if (is_multisite() && dpa_is_running_networkwide()) {
        restore_current_blog();
    }
    return apply_filters('dpa_has_progress', achievements()->progress_query->have_posts());
}
 /**
  * Constructor
  * 
  * @param array $args An associative array with information about the current table
  * @since Achievements (3.0)
  */
 public function __construct($args = array())
 {
     parent::__construct($args);
     // Override the WP_Users_List_Table's opinion of whether to show network users or not.
     $this->is_site_users = dpa_is_running_networkwide();
     if ($this->is_site_users) {
         $this->site_id = isset($_REQUEST['id']) ? absint($_REQUEST['id']) : 0;
     }
 }
Ejemplo n.º 3
0
/**
 * If multisite and running network-wide, clear custom caches when something
 * is added, removed, or updated in the Events taxonomy.
 *
 * @param int|array $ids Single or list of term IDs
 * @param string $taxonomy Taxonomy
 * @see dpa_register_events()
 * @since Achievements (3.0)
 */
function dpa_clear_events_tax_cache($ids, $taxonomy)
{
    if (dpa_get_event_tax_id() !== $taxonomy) {
        return;
    }
    // If multisite and running network-wide, clear the registered events cache for the events taxonomy.
    if (is_multisite() && dpa_is_running_networkwide()) {
        wp_cache_delete('dpa_registered_events', 'achievements_events');
    }
}
Ejemplo n.º 4
0
/**
 * The leaderboard template loop.
 *
 * Doesn't use WP_Query, but the template loop and its data are structured in a vaguely similar
 * way to the dpa_has_achievements() and dpa_has_progress() loops (which do use WP_Query).
 *
 * @param array $args Optional. Associative array of optional arguments. See function for details.
 * @return bool Returns true if the query had any results to loop over
 * @since Achievements (3.4)
 */
function dpa_has_leaderboard($args = array())
{
    // 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);
    }
    $defaults = array('paged' => dpa_get_leaderboard_paged(), 'posts_per_page' => dpa_get_leaderboard_items_per_page(), 'user_ids' => array());
    $args = dpa_parse_args($args, $defaults, 'has_leaderboard');
    // Run the query
    achievements()->leaderboard_query = dpa_get_leaderboard($args);
    // Only add pagination if query returned results
    if ((count(achievements()->leaderboard_query['results']) || achievements()->leaderboard_query['total']) && $args['posts_per_page']) {
        // If a top-level /leaderboard/ rewrite is ever added, we can make this use pretty pagination. Also see dpa_get_leaderboard_paged().
        $base = add_query_arg('leaderboard-page', '%#%');
        // Pagination settings with filter
        $leaderboard_pagination = apply_filters('dpa_leaderboard_pagination', array('base' => $base, 'current' => $args['paged'], 'format' => '', 'mid_size' => 1, 'next_text' => is_rtl() ? '←' : '→', 'prev_text' => is_rtl() ? '→' : '←', 'total' => (int) $args['posts_per_page'] === achievements()->leaderboard_query['total'] ? 1 : ceil(achievements()->leaderboard_query['total'] / (int) $args['posts_per_page'])));
        achievements()->leaderboard_query['paged'] = (int) $args['paged'];
        achievements()->leaderboard_query['pagination_links'] = paginate_links($leaderboard_pagination);
        achievements()->leaderboard_query['posts_per_page'] = (int) $args['posts_per_page'];
    }
    // If multisite and running network-wide, undo the switch_to_blog
    if (is_multisite() && dpa_is_running_networkwide()) {
        restore_current_blog();
    }
    return apply_filters('dpa_has_leaderboard', !empty(achievements()->leaderboard_query['results']));
}
Ejemplo n.º 5
0
/**
 * Handles the redeem achievement form submission.
 * 
 * Finds any achievements with the specific redemption code, and if the user hasn't already unlocked
 * that achievement, it's awarded to the user.
 *
 * @param string $action Optional. If 'dpa-redeem-achievement', handle the form submission.
 * @since Achievements (3.1)
 */
function dpa_form_redeem_achievement($action = '')
{
    if ('dpa-redeem-achievement' !== $action || !dpa_is_user_active()) {
        return;
    }
    // Check required form values are present
    $redemption_code = isset($_POST['dpa_code']) ? sanitize_text_field(stripslashes($_POST['dpa_code'])) : '';
    $redemption_code = apply_filters('dpa_form_redeem_achievement_code', $redemption_code);
    if (empty($redemption_code) || !dpa_verify_nonce_request('dpa-redeem-achievement')) {
        return;
    }
    // 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);
    }
    // Find achievements that match the same redemption code
    $achievements = dpa_get_achievements(array('meta_key' => '_dpa_redemption_code', 'meta_value' => $redemption_code));
    // Bail out early if no achievements found
    if (empty($achievements)) {
        dpa_add_error('dpa_redeem_achievement_nonce', __('That code was invalid. Try again!', 'achievements'));
        // If multisite and running network-wide, undo the switch_to_blog
        if (is_multisite() && dpa_is_running_networkwide()) {
            restore_current_blog();
        }
        return;
    }
    $existing_progress = dpa_get_progress(array('author' => get_current_user_id()));
    foreach ($achievements as $achievement_obj) {
        $progress_obj = array();
        // If we have existing progress, pass that to dpa_maybe_unlock_achievement().
        foreach ($existing_progress as $progress) {
            if ($achievement_obj->ID === $progress->post_parent) {
                // If the user has already unlocked this achievement, don't give it to them again.
                if (dpa_get_unlocked_status_id() === $progress->post_status) {
                    $progress_obj = false;
                } else {
                    $progress_obj = $progress;
                }
                break;
            }
        }
        if (false !== $progress_obj) {
            dpa_maybe_unlock_achievement(get_current_user_id(), 'skip_validation', $progress_obj, $achievement_obj);
        }
    }
    // If multisite and running network-wide, undo the switch_to_blog
    if (is_multisite() && dpa_is_running_networkwide()) {
        restore_current_blog();
    }
}
Ejemplo n.º 6
0
/**
 * Update the _dpa_extension_versions option.
 *
 * @param array $new_value
 * @return array
 * @see dpa_get_extension_versions()
 * @since Achievements (3.0)
 */
function dpa_update_extension_versions($new_value)
{
    // If running network-wide, use the site options table
    if (is_multisite() && dpa_is_running_networkwide()) {
        update_site_option('_dpa_extension_versions', $new_value);
    } else {
        update_option('_dpa_extension_versions', $new_value);
    }
}
Ejemplo n.º 7
0
/**
 * The achievement post type loop.
 *
 * Most of the values that $args can accept are documented in {@link WP_Query}. The custom
 * values added by Achievements are as follows:
 *
 * 'ach_event'             - string   - Loads achievements for a specific event. Matches a slug from the dpa_event tax. Default is empty.
 * 'ach_populate_progress' - bool|int - Populate a user/users' progress for the results.
 *                                    - bool: True - uses the logged in user (default). False - don't fetch progress.
 *                                    - int: pass a user ID (single user).
 * 'ach_progress_status'   - array    - array: Post status IDs for the Progress post type.
 *
 * @param array|string $args All the arguments supported by {@link WP_Query}, and some more.
 * @return bool Returns true if the query has any results to loop over
 * @since Achievements (1.0)
 */
function dpa_has_achievements($args = array())
{
    // 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);
    }
    $default_post_parent = dpa_is_single_achievement() ? dpa_get_achievement_id() : 'any';
    $default_progress_status = dpa_is_single_user_achievements() ? array(dpa_get_unlocked_status_id()) : array(dpa_get_locked_status_id(), dpa_get_unlocked_status_id());
    $defaults = array('ignore_sticky_posts' => true, 'order' => 'ASC', 'orderby' => 'title', 'max_num_pages' => false, 'paged' => dpa_get_paged(), 'perm' => 'readable', 'post_parent' => $default_post_parent, 'post_type' => dpa_get_achievement_post_type(), 'posts_per_page' => dpa_get_achievements_per_page(), 'ach_progress_status' => $default_progress_status, 's' => !empty($_GET['achievements']) ? wp_unslash($_GET['achievements']) : '', 'ach_event' => '', 'ach_populate_progress' => false);
    // Load achievements for a specific event
    if (!empty($args['ach_event'])) {
        $args['tax_query'] = array(array('field' => 'slug', 'taxonomy' => dpa_get_event_tax_id(), 'terms' => $args['ach_event']));
        unset($args['ach_event']);
    }
    $args = dpa_parse_args($args, $defaults, 'has_achievements');
    extract($args);
    // Run the query
    achievements()->achievement_query = new WP_Query($args);
    // User to popular progress for
    $progress_user_ids = false;
    if (isset($args['ach_populate_progress'])) {
        if (true === $args['ach_populate_progress']) {
            if (dpa_is_single_user_achievements()) {
                $progress_user_ids = dpa_get_displayed_user_id();
            } elseif (is_user_logged_in()) {
                $progress_user_ids = get_current_user_id();
            }
        } else {
            $progress_user_ids = (int) $args['ach_populate_progress'];
        }
    }
    // If no limit to posts per page, set it to the current post_count
    if (-1 === $posts_per_page) {
        $posts_per_page = achievements()->achievement_query->post_count;
    }
    // Add pagination values to query object
    achievements()->achievement_query->posts_per_page = $posts_per_page;
    achievements()->achievement_query->paged = $paged;
    // Only add pagination if query returned results
    if (((int) achievements()->achievement_query->post_count || (int) achievements()->achievement_query->found_posts) && (int) achievements()->achievement_query->posts_per_page) {
        // Limit the number of achievements shown based on maximum allowed pages
        if (!empty($max_num_pages) && achievements()->achievement_query->found_posts > achievements()->achievement_query->max_num_pages * achievements()->achievement_query->post_count) {
            achievements()->achievement_query->found_posts = achievements()->achievement_query->max_num_pages * achievements()->achievement_query->post_count;
        }
        // If pretty permalinks are enabled, make our pagination pretty
        if ($GLOBALS['wp_rewrite']->using_permalinks()) {
            // Page or single post
            if (is_page() || is_single()) {
                $base = get_permalink();
            } elseif (dpa_is_achievement_archive()) {
                $base = dpa_get_achievements_url();
            } else {
                $base = get_permalink($post_parent);
            }
            // Use pagination base
            $base = trailingslashit($base) . user_trailingslashit($GLOBALS['wp_rewrite']->pagination_base . '/%#%/');
            // Unpretty pagination
        } else {
            $base = add_query_arg('paged', '%#%');
        }
        // Pagination settings with filter
        $achievement_pagination = apply_filters('dpa_achievement_pagination', array('base' => $base, 'current' => (int) achievements()->achievement_query->paged, 'format' => '', 'mid_size' => 1, 'next_text' => is_rtl() ? '←' : '→', 'prev_text' => is_rtl() ? '→' : '←', 'total' => $posts_per_page == achievements()->achievement_query->found_posts ? 1 : ceil((int) achievements()->achievement_query->found_posts / (int) $posts_per_page)));
        // Add pagination to query object
        achievements()->achievement_query->pagination_links = paginate_links($achievement_pagination);
        // Remove first page from pagination
        achievements()->achievement_query->pagination_links = str_replace($GLOBALS['wp_rewrite']->pagination_base . "/1/'", "'", achievements()->achievement_query->pagination_links);
    }
    // Populate extra progress information for the achievements
    if (!empty($progress_user_ids) && achievements()->achievement_query->have_posts()) {
        $progress_post_ids = wp_list_pluck((array) achievements()->achievement_query->posts, 'ID');
        // Args for progress query
        $progress_args = array('author' => $progress_user_ids, 'no_found_rows' => true, 'post_parent' => $progress_post_ids, 'post_status' => $args['ach_progress_status'], 'posts_per_page' => -1);
        // Run the query
        dpa_has_progress($progress_args);
    }
    // If multisite and running network-wide, undo the switch_to_blog
    if (is_multisite() && dpa_is_running_networkwide()) {
        restore_current_blog();
    }
    return apply_filters('dpa_has_achievements', achievements()->achievement_query->have_posts());
}
Ejemplo n.º 8
0
/**
 * 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);
}
 /**
  * The PHP side of Achievements' live notifications system using WordPress 3.6's heartbeat API; we grab the image,
  * post ID, permalink, and title of all achievements that have recently been unlocked, and send that back using
  * WordPress' heartbeat_recieved filter.
  *
  * The heartbeat JS makes periodic AJAX connections back to WordPress. WordPress sees those requests, and fires the
  * heartbeat_recieved filter. The filter allows plugins to change the server's response before it's sent back to
  * the originating user's browser.
  *
  * @param array $response The data we want to send back to user whose heart beat.
  * @param array $data An array of $_POST data received from the originating AJAX request.
  * @return array The data we want to send back to user.
  * @since Achievements (3.5)
  */
 public static function notifications_heartbeat_response($response, $data)
 {
     // Bail if user is not active, or $data isn't in the expected format
     if (!dpa_is_user_active() || !isset($data['achievements']) || !is_array($data['achievements'])) {
         return $response;
     }
     $ids = array_keys(dpa_get_user_notifications());
     if (empty($ids)) {
         return $response;
     }
     // 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);
     }
     $achievements = dpa_get_achievements(array('no_found_rows' => true, 'nopaging' => true, 'post__in' => $ids, 'post_status' => 'any'));
     $new_response = array();
     foreach ($achievements as $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 post statuses.
          */
         if (!in_array($achievement->post_status, array('publish', 'private'))) {
             continue;
         }
         $item = array();
         $item['ID'] = $achievement->ID;
         $item['title'] = esc_html(apply_filters('dpa_get_achievement_title', $achievement->post_title, $achievement->ID));
         $item['permalink'] = esc_url_raw(home_url('/?p=' . $achievement->ID));
         // Thumbnail is optional and may not be set
         $thumbnail = get_post_thumbnail_id($achievement->ID);
         if (!empty($thumbnail)) {
             $thumbnail = wp_get_attachment_image_src($thumbnail, 'medium');
             if ($thumbnail) {
                 $item['image_url'] = esc_url_raw($thumbnail[0]);
                 $item['image_width'] = (int) $thumbnail[1];
             }
         }
         // Achievements 3.5+ supports showing multiple unlock notifications at the same time
         $new_response[] = $item;
     }
     // If multisite and running network-wide, undo the switch_to_blog
     if (is_multisite() && dpa_is_running_networkwide()) {
         restore_current_blog();
     }
     // Clear all pending notifications
     dpa_update_user_notifications();
     $new_response = array_merge($response, array('achievements' => $new_response));
     return apply_filters('dpa_theme_compat_notifications_heartbeat_response', $new_response, $ids, $response, $data);
 }
Ejemplo n.º 10
0
/**
 * Update the ID of the last achievement this user unlocked
 *
 * @param int $user_id Optional. User ID to update. Optional, defaults to current logged in user.
 * @param int $new_value Optional. The new value.
 * @return bool False if no user or failure, true if successful
 * @since Achievements (3.0)
 */
function dpa_update_user_last_unlocked($user_id = 0, $new_value = 0)
{
    // Default to current user
    if (empty($user_id) && is_user_logged_in()) {
        $user_id = get_current_user_id();
    }
    // No user, bail out
    if (empty($user_id)) {
        return false;
    }
    // As Achievements can run independently (as well as sitewide) on a multisite, decide where to store the user option
    $store_global = is_multisite() && dpa_is_running_networkwide();
    $new_value = apply_filters('dpa_update_user_last_unlocked', $new_value, $user_id);
    return update_user_option($user_id, '_dpa_last_unlocked', (int) $new_value, $store_global);
}
Ejemplo n.º 11
0
 /**
  * Update the user's "User Points" meta information when the Edit User page has been saved,
  * and modify the user's current achievements as appropriate.
  *
  * The action that this function is hooked to is only executed on a succesful update,
  * which is behind a nonce and capability check (see wp-admin/user-edit.php).
  *
  * @param int $user_id
  * @since Achievements (3.0)
  */
 public function save_profile_fields($user_id)
 {
     if (!isset($_POST['dpa_achievements']) || !is_super_admin()) {
         return;
     }
     if (!isset($_POST['dpa_user_achievements'])) {
         $_POST['dpa_user_achievements'] = array();
     }
     // 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);
     }
     // Update user's points
     dpa_update_user_points((int) $_POST['dpa_achievements'], $user_id);
     // Get unlocked achievements
     $unlocked_achievements = dpa_get_progress(array('author' => $user_id, 'post_status' => dpa_get_unlocked_status_id()));
     $old_unlocked_achievements = wp_list_pluck($unlocked_achievements, 'post_parent');
     $new_unlocked_achievements = array_filter(wp_parse_id_list($_POST['dpa_user_achievements']));
     // Figure out which achievements to add or remove
     $achievements_to_add = array_diff($new_unlocked_achievements, $old_unlocked_achievements);
     $achievements_to_remove = array_diff($old_unlocked_achievements, $new_unlocked_achievements);
     // Remove achievements :(
     if (!empty($achievements_to_remove)) {
         foreach ($achievements_to_remove as $achievement_id) {
             dpa_delete_achievement_progress($achievement_id, $user_id);
         }
     }
     // Award achievements! :D
     if (!empty($achievements_to_add)) {
         // Get achievements to add
         $new_achievements = dpa_get_achievements(array('post__in' => $achievements_to_add, 'posts_per_page' => count($achievements_to_add)));
         // Get any still-locked progress for this user
         $existing_progress = dpa_get_progress(array('author' => $user_id, 'post_status' => dpa_get_locked_status_id()));
         foreach ($new_achievements as $achievement_obj) {
             $progress_obj = array();
             // If we have existing progress, pass that to dpa_maybe_unlock_achievement().
             foreach ($existing_progress as $progress) {
                 if ($achievement_obj->ID === $progress->post_parent) {
                     $progress_obj = $progress;
                     break;
                 }
             }
             dpa_maybe_unlock_achievement($user_id, 'skip_validation', $progress_obj, $achievement_obj);
         }
     }
     // If multisite and running network-wide, undo the switch_to_blog
     if (is_multisite() && dpa_is_running_networkwide()) {
         restore_current_blog();
     }
 }
Ejemplo n.º 12
0
 /**
  * Set up the post types for: achievement, achievement_progress
  *
  * @since Achievements (3.0)
  */
 public function register_post_types()
 {
     $cpt = $labels = $rewrite = $supports = array();
     /**
      * If the plugin's been activated network-wide, only allow the normal access and behaviour on the DPA_DATA_STORE site.
      * This prevents the admin controls showing up on the wrong site's wp-admin, as well as the overhead of unused rewrite rules.
      *
      * The problem with this is that the post type needs to be registered all on sites in a multisite all the time, otherwise
      * achievements can't be awarded. See _update_blog_date_on_post_publish() which tries to create (in our case) a
      * "dpa-progress" post.
      *
      * The solution to this is $post_type_is_public. If it's false, the post type is registered, but it's hidden from the admin,
      * isn't publicly queryable, doesn't create rewrite rules, and so on. If it's set to true, the post type behaves as normal.
      */
     $post_type_is_public = is_multisite() && dpa_is_running_networkwide() && get_current_blog_id() !== DPA_DATA_STORE ? false : true;
     // CPT labels
     $labels['achievement'] = array('add_new' => _x('Add New', 'achievement', 'achievements'), 'add_new_item' => __('Add New Achievement', 'achievements'), 'all_items' => __('All Achievements', 'achievements'), 'edit' => _x('Edit', 'achievement', 'achievements'), 'edit_item' => __('Edit Achievement', 'achievements'), 'menu_name' => __('Achievements', 'achievements'), 'name' => __('Achievements', 'achievements'), 'new_item' => __('New Achievement', 'achievements'), 'not_found' => __('No achievements found.', 'achievements'), 'not_found_in_trash' => __('No achievements found in Trash.', 'achievements'), 'search_items' => __('Search Achievements', 'achievements'), 'singular_name' => __('Achievement', 'achievements'), 'view' => __('View Achievement', 'achievements'), 'view_item' => __('View Achievement', 'achievements'));
     // CPT rewrite
     $rewrite['achievement'] = array('ep_mask' => 0, 'feed' => false, 'feeds' => false, 'pages' => true, 'slug' => dpa_get_singular_root_slug(), 'with_front' => false);
     // CPT supports
     $supports['achievement'] = array('editor', 'excerpt', 'revisions', 'thumbnail', 'title');
     $supports['achievement_progress'] = array('author');
     // CPT filter
     $cpt['achievement'] = apply_filters('dpa_register_post_type_achievement', array('capabilities' => dpa_get_achievement_caps(), 'capability_type' => array('achievement', 'achievements'), 'delete_with_user' => false, 'description' => _x('Achievements types (e.g. new post, new site, new user)', 'Achievement post type description', 'achievements'), 'has_archive' => $post_type_is_public ? dpa_get_root_slug() : false, 'labels' => $labels['achievement'], 'public' => $post_type_is_public, 'rewrite' => $rewrite['achievement'], 'register_meta_box_cb' => 'dpa_admin_setup_metaboxes', 'show_in_menu' => $post_type_is_public, 'show_ui' => dpa_current_user_can_see(dpa_get_achievement_post_type()), 'supports' => $supports['achievement'], 'taxonomies' => array('category')));
     $cpt['achievement_progress'] = apply_filters('dpa_register_post_type_achievement_progress', array('capabilities' => dpa_get_achievement_progress_caps(), 'capability_type' => array('achievement_progress', 'achievement_progresses'), 'delete_with_user' => true, 'description' => _x('Achievement Progress (e.g. unlocked achievements for a user, progress on an achievement for a user)', 'Achievement Progress post type description', 'achievements'), 'public' => false, 'query_var' => false, 'rewrite' => false, 'supports' => $supports['achievement_progress']));
     // Register Achievement post type
     register_post_type(dpa_get_achievement_post_type(), $cpt['achievement']);
     // Register Achievement Progress post type
     register_post_type(dpa_get_progress_post_type(), $cpt['achievement_progress']);
 }