Пример #1
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);
    }
}
Пример #2
0
/**
 * Output the target value of the achievement. Only used for event-type achievements.
 * The target is the number of times that an achievement's events must occur before the achievement is unlocked.
 *
 * @param int $achievement_id Optional. Achievement ID
 * @since Achievements (3.0)
 */
function dpa_achievement_target($achievement_id = 0)
{
    echo number_format_i18n(dpa_get_achievement_target($achievement_id));
}
Пример #3
0
/**
 * Achievements metabox
 *
 * Contains fields to set the karma points, pick between action/event, and the list of events.
 *
 * @param WP_Post $post The post being added or edited
 * @since Achievements (3.0)
 */
function dpa_achievement_metabox(WP_Post $post)
{
    // Get all events grouped by the extension which provided them
    $events = dpa_get_all_events_details();
    // Get existing values (if this is an edit)
    $existing_points = dpa_get_achievement_points($post->ID);
    $existing_target = dpa_get_achievement_target($post->ID);
    $existing_events = wp_get_post_terms($post->ID, dpa_get_event_tax_id(), array('fields' => 'ids'));
    $existing_type = empty($existing_events) && !empty($_GET['action']) && 'edit' === $_GET['action'] ? 'award' : 'event';
    $existing_code = dpa_get_achievement_redemption_code($post->ID);
    // Ensure sane defaults
    if (empty($existing_points)) {
        $existing_points = 0;
    }
    if (empty($existing_target)) {
        $existing_target = 1;
    }
    ?>

	<div class="misc-pub-section dpa-karma">
		<label for="dpa-points"><?php 
    _e('Karma points:', 'achievements');
    ?>
</label>
		<input type="number" name="dpa_points" id="dpa-points" value="<?php 
    echo esc_attr($existing_points);
    ?>
" />
	</div>

	<div class="misc-pub-section dpa-type">
		<label for="dpa_type"><?php 
    _ex('Type:', 'type of achievement', 'achievements');
    ?>
</label>
		<input type="radio" name="dpa_type" id="dpa-type-award" value="award" <?php 
    checked($existing_type, 'award');
    ?>
><?php 
    _ex('&nbsp;Award', 'type of achievement', 'achievements');
    ?>
</input>
		<input type="radio" name="dpa_type" id="dpa-type-event" value="event" <?php 
    checked($existing_type, 'event');
    ?>
><?php 
    _ex('&nbsp;Event', 'type of achievement', 'achievements');
    ?>
</input>

		<p class="hint"><?php 
    _e("An <em>award</em> is given by a site admin, whereas an <em>event</em> is unlocked automatically when its criteria have been met.", 'achievements');
    ?>
</p>

		<select id="dpa-event" name="dpa_event[]" style="visibility: hidden" data-placeholder="<?php 
    esc_attr_e('Press here to pick events', 'achievements');
    ?>
" class="chzn-select <?php 
    if (is_rtl()) {
        echo 'chzn-rtl';
    }
    ?>
" multiple="multiple">
			<option value=""></option>

			<?php 
    foreach ($events as $extension => $extension_events) {
        ?>
				<optgroup label="<?php 
        echo esc_attr($extension);
        ?>
">

				<?php 
        foreach ($extension_events as $event) {
            ?>
					<option value="<?php 
            echo esc_attr($event['id']);
            ?>
" <?php 
            selected(in_array($event['id'], $existing_events), true);
            ?>
><?php 
            echo esc_html($event['description']);
            ?>
</option>
				<?php 
        }
        ?>

				</optgroup>
			<?php 
    }
    ?>

		</select>
	</div>

	<div class="misc-pub-section dpa-target">
		<label for="dpa_target"><?php 
    _ex('Events repeat:', "Number of times an achievement&#8217;s events need to repeat before the achievement is awarded", 'achievements');
    ?>
</label>
		<input type="number" name="dpa_target" id="dpa-target" min="1" value="<?php 
    echo esc_attr($existing_target);
    ?>
" />

		<p class="hint"><?php 
    _e("Number of times the events need to repeat before the achievement is awarded.", 'achievements');
    ?>
</p>
	</div>

	<div class="misc-pub-section dpa-redemption-code">
		<label for="dpa-code"><?php 
    _e('Redemption code:', 'achievements');
    ?>
</label>
		<input id="dpa-code" value="<?php 
    echo esc_attr($existing_code);
    ?>
" name="dpa_code" type="text" />

		<p class="hint"><?php 
    _e("Users can enter this code into the Redemption widget to unlock the achievement.", 'achievements');
    ?>
</p>
	</div>

	<?php 
    wp_nonce_field('dpa_achievement_metabox_save', 'dpa_achievement_metabox');
    do_action('dpa_achievement_metabox');
}