Beispiel #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());
}
 /**
  * List all unlocked achievements for the specified user
  *
  * @since Achievements (3.3)
  * @subcommand list
  * @synopsis --user_id=<id> [--format=<table|csv|json>]
  */
 public function _list($args, $assoc_args)
 {
     global $wpdb;
     $defaults = array('format' => 'table');
     $assoc_args = array_merge($defaults, $assoc_args);
     if (!$assoc_args['user_id'] || !($user = get_userdata($assoc_args['user_id']))) {
         WP_CLI::error('Invalid User ID specified.');
     }
     // Get the progress for this user
     $achievement_ids = $wpdb->get_col($wpdb->prepare("SELECT post_parent FROM {$wpdb->posts} WHERE post_type = %s AND post_author = %d", dpa_get_progress_post_type(), $user->ID));
     if (empty($achievement_ids)) {
         WP_CLI::error(sprintf('User ID %d has not unlocked any achievements.', $user->ID));
     }
     $achievement_ids = wp_parse_id_list($achievement_ids);
     $achievement_count = count($achievement_ids);
     $achievement_ids = implode(',', $achievement_ids);
     // Get the achievements
     $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title FROM {$wpdb->posts} WHERE ID in ({$achievement_ids}) AND post_type = %s AND post_status = %s ORDER BY post_title ASC", dpa_get_achievement_post_type(), 'publish'));
     if (empty($posts)) {
         WP_CLI::error(sprintf("No achievements unlocked by User ID %d have been found. This shouldn't happen.", $user->ID));
     }
     WP_CLI::success(sprintf('%d achievements have been unlocked by User ID %d:', $achievement_count, $user->ID));
     \WP_CLI\utils\format_items($assoc_args['format'], $posts, $this->fields);
 }
Beispiel #3
0
/**
 * Called before a post is deleted; if an achievement post, we tidy up any related Progress posts.
 * 
 * This function is supplemental to the actual achievement deletion which is handled by WordPress core API functions.
 * It is used to clean up after an achievement that is being deleted.
 *
 * @param int $post_id Optional; post ID that is being deleted.
 * @since Achievements (3.0)
 */
function dpa_before_achievement_deleted($post_id = 0)
{
    $post_id = dpa_get_achievement_id($post_id);
    if (empty($post_id) || !dpa_is_achievement($post_id)) {
        return;
    }
    do_action('dpa_before_achievement_deleted', $post_id);
    // An achievement is being permanently deleted, so any related Progress posts have to go, too.
    $progress = new WP_Query(array('fields' => 'id=>parent', 'nopaging' => true, 'post_parent' => $post_id, 'post_status' => array(dpa_get_locked_status_id(), dpa_get_unlocked_status_id()), 'post_type' => dpa_get_progress_post_type(), 'posts_per_page' => -1));
    if (empty($progress)) {
        return;
    }
    foreach ($progress->posts as $post) {
        wp_delete_post($post->ID, true);
    }
}
Beispiel #4
0
/**
 * If the specified achievement's criteria has been met, we unlock the
 * achievement. Otherwise we record progress for the achievement for next time.
 *
 * $skip_validation is the second parameter for backpat with Achievements 2.x
 *
 * @param int     $user_id
 * @param string  $skip_validation  Optional. Set to "skip_validation" to skip Achievement validation (unlock achievement regardless of criteria).
 * @param object  $progress_obj     Optional. The Progress post object. Defaults to Progress object in the Progress loop.
 * @param object  $achievement_obj  Optional. The Achievement post object to maybe_unlock. Defaults to current object in Achievement loop.
 * @since Achievements (2.0)
 */
function dpa_maybe_unlock_achievement($user_id, $skip_validation = '', $progress_obj = null, $achievement_obj = null)
{
    // 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;
    }
    // Default to current object in the achievement loop
    if (empty($achievement_obj)) {
        $achievement_obj = achievements()->achievement_query->post;
    }
    // Default to progress object in the progress loop
    if (empty($progress_obj) && !empty(achievements()->progress_query->posts)) {
        $progress_obj = wp_filter_object_list(achievements()->progress_query->posts, array('post_parent' => $achievement_obj->ID));
        $progress_obj = array_shift($progress_obj);
    }
    // Has the user already unlocked the achievement?
    if (!empty($progress_obj) && dpa_get_unlocked_status_id() === $progress_obj->post_status) {
        return;
    }
    // Prepare default values to create/update a progress post
    $progress_args = array('comment_status' => 'closed', 'ping_status' => 'closed', 'post_author' => $user_id, 'post_parent' => $achievement_obj->ID, 'post_title' => $achievement_obj->post_title, 'post_type' => dpa_get_progress_post_type());
    // If achievement already has some progress, grab the ID so we update the post later
    if (!empty($progress_obj->ID)) {
        $progress_args['ID'] = $progress_obj->ID;
    }
    // If the achievement does not have a target set, this is an award achievement.
    $achievement_target = dpa_get_achievement_target($achievement_obj->ID);
    if ($achievement_target) {
        // Increment progress count
        $progress_args['post_content'] = apply_filters('dpa_maybe_unlock_achievement_progress_increment', 1);
        if (!empty($progress_obj)) {
            $progress_args['post_content'] = (int) $progress_args['post_content'] + (int) $progress_obj->post_content;
        }
    }
    // Does the progress count now meet the achievement target?
    if ('skip_validation' === $skip_validation || $achievement_target && (int) $progress_args['post_content'] >= $achievement_target) {
        // Yes. Unlock achievement.
        $progress_args['post_status'] = dpa_get_unlocked_status_id();
        // No, user needs to make more progress. Make sure the locked status is set correctly.
    } else {
        $progress_args['post_status'] = dpa_get_locked_status_id();
    }
    // Create or update the progress post
    $progress_id = wp_insert_post($progress_args);
    // If the achievement was just unlocked, do stuff.
    if (dpa_get_unlocked_status_id() === $progress_args['post_status']) {
        // Achievement was unlocked. Notifications and points updates are hooked to this function.
        do_action('dpa_unlock_achievement', $achievement_obj, $user_id, $progress_id);
    }
}
Beispiel #5
0
/**
 * Check if the current post type belongs to Achievements
 *
 * @param mixed $the_post Optional. Post object or post ID.
 * @return bool
 * @since Achievements (3.0)
 */
function dpa_is_custom_post_type($the_post = false)
{
    $retval = false;
    // Viewing one of Achievements' post types
    if (in_array(get_post_type($the_post), array(dpa_get_achievement_post_type(), dpa_get_progress_post_type()))) {
        $retval = true;
    }
    return (bool) apply_filters('dpa_is_custom_post_type', $retval, $the_post);
}
Beispiel #6
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']);
 }
Beispiel #7
0
/**
 * Output the unique id of the custom post type for achievement_progress
 *
 * @since Achievements (3.0)
 * @uses dpa_get_progress_post_type() To get the achievement_progress post type
 */
function dpa_achievement_progress_post_type()
{
    echo dpa_get_progress_post_type();
}