Example #1
0
/**
 * Clears any notifications for the specified user for the specified achievement.
 *
 * @param int $post_id int Optional. The post ID of the achievement to clear the notification for.
 * @param int $user_id int Optional. The ID for the user.
 * @since Achievements (3.0)
 */
function dpa_clear_notification($post_id = 0, $user_id = 0)
{
    // Default to current user
    if (empty($user_id) && is_user_logged_in()) {
        $user_id = get_current_user_id();
    }
    // Default to current post
    if (empty($post_id) && is_single()) {
        $post_id = get_the_ID();
    }
    // No user or post ID to check
    if (empty($user_id) || empty($post_id)) {
        return;
    }
    // The notifications array is keyed by the achievement (post) ID.
    $notifications = dpa_get_user_notifications($user_id);
    // Is there a notification to clear?
    if (!isset($notifications[$post_id])) {
        return;
    }
    // Clear the notification
    unset($notifications[$post_id]);
    dpa_update_user_notifications($notifications, $user_id);
    // Tell other plugins that we've just cleared other plugins
    do_action('dpa_clear_notification', $post_id, $user_id);
}
 /**
  * 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);
 }
Example #3
0
/**
 * 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);
}