/**
  * @covers ::bbp_update_topic_last_reply_id
  */
 public function test_bbp_update_topic_last_reply_id()
 {
     $f = $this->factory->forum->create();
     $t = $this->factory->topic->create(array('post_parent' => $f, 'topic_meta' => array('forum_id' => $f)));
     $r1 = $this->factory->reply->create(array('post_parent' => $t, 'reply_meta' => array('forum_id' => $f, 'topic_id' => $t)));
     $id = bbp_update_topic_last_reply_id($t, $r1);
     $this->assertSame($r1, $id);
     $id = bbp_get_topic_last_reply_id($t);
     $this->assertSame($r1, $id);
     $r2 = $this->factory->reply->create_many(2, array('post_parent' => $t, 'reply_meta' => array('forum_id' => $f, 'topic_id' => $t)));
     bbp_update_topic_last_reply_id($t, $r2[1]);
     $id = bbp_get_topic_last_reply_id($t);
     $this->assertSame($r2[1], $id);
 }
Example #2
0
/**
 * Split topic handler
 *
 * Handles the front end split topic submission
 *
 * @since bbPress (r2756)
 *
 * @param string $action The requested action to compare this function to
 * @uses bbp_add_error() To add an error message
 * @uses bbp_get_reply() To get the reply
 * @uses bbp_get_topic() To get the topics
 * @uses bbp_verify_nonce_request() To verify the nonce and check the request
 * @uses current_user_can() To check if the current user can edit the topics
 * @uses bbp_get_topic_post_type() To get the topic post type
 * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
 * @uses do_action() Calls 'bbp_pre_split_topic' with the from reply id, source
 *                    and destination topic ids
 * @uses bbp_get_topic_subscribers() To get the source topic subscribers
 * @uses bbp_add_user_subscription() To add the user subscription
 * @uses bbp_get_topic_favoriters() To get the source topic favoriters
 * @uses bbp_add_user_favorite() To add the user favorite
 * @uses wp_get_post_terms() To get the source topic tags
 * @uses wp_set_post_terms() To set the topic tags
 * @uses bbp_get_reply_post_type() To get the reply post type
 * @uses wpdb::prepare() To prepare our sql query
 * @uses wpdb::get_results() To execute the sql query and get results
 * @uses wp_update_post() To update the replies
 * @uses bbp_update_reply_topic_id() To update the reply topic id
 * @uses bbp_get_topic_forum_id() To get the topic forum id
 * @uses bbp_update_reply_forum_id() To update the reply forum id
 * @uses do_action() Calls 'bbp_split_topic_reply' with the reply id and
 *                    destination topic id
 * @uses bbp_update_topic_last_reply_id() To update the topic last reply id
 * @uses bbp_update_topic_last_active_time() To update the topic last active meta
 * @uses do_action() Calls 'bbp_post_split_topic' with the destination and
 *                    source topic ids and source topic's forum id
 * @uses bbp_get_topic_permalink() To get the topic permalink
 * @uses wp_safe_redirect() To redirect to the topic link
 */
function bbp_split_topic_handler($action = '')
{
    // Bail if action is not 'bbp-split-topic'
    if ('bbp-split-topic' !== $action) {
        return;
    }
    global $wpdb;
    // Prevent debug notices
    $from_reply_id = $destination_topic_id = 0;
    $destination_topic_title = '';
    $destination_topic = $from_reply = $source_topic = '';
    $split_option = false;
    /** Split Reply ***********************************************************/
    if (empty($_POST['bbp_reply_id'])) {
        bbp_add_error('bbp_split_topic_reply_id', __('<strong>ERROR</strong>: Reply ID to split the topic from not found!', 'bbpress'));
    } else {
        $from_reply_id = (int) $_POST['bbp_reply_id'];
    }
    $from_reply = bbp_get_reply($from_reply_id);
    // Reply exists
    if (empty($from_reply)) {
        bbp_add_error('bbp_split_topic_r_not_found', __('<strong>ERROR</strong>: The reply you want to split from was not found.', 'bbpress'));
    }
    /** Topic to Split ********************************************************/
    // Get the topic being split
    $source_topic = bbp_get_topic($from_reply->post_parent);
    // No topic
    if (empty($source_topic)) {
        bbp_add_error('bbp_split_topic_source_not_found', __('<strong>ERROR</strong>: The topic you want to split was not found.', 'bbpress'));
    }
    // Nonce check failed
    if (!bbp_verify_nonce_request('bbp-split-topic_' . $source_topic->ID)) {
        bbp_add_error('bbp_split_topic_nonce', __('<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress'));
        return;
    }
    // Use cannot edit topic
    if (!current_user_can('edit_topic', $source_topic->ID)) {
        bbp_add_error('bbp_split_topic_source_permission', __('<strong>ERROR</strong>: You do not have the permissions to edit the source topic.', 'bbpress'));
    }
    // How to Split
    if (!empty($_POST['bbp_topic_split_option'])) {
        $split_option = (string) trim($_POST['bbp_topic_split_option']);
    }
    // Invalid split option
    if (empty($split_option) || !in_array($split_option, array('existing', 'reply'))) {
        bbp_add_error('bbp_split_topic_option', __('<strong>ERROR</strong>: You need to choose a valid split option.', 'bbpress'));
        // Valid Split Option
    } else {
        // What kind of split
        switch ($split_option) {
            // Into an existing topic
            case 'existing':
                // Get destination topic id
                if (empty($_POST['bbp_destination_topic'])) {
                    bbp_add_error('bbp_split_topic_destination_id', __('<strong>ERROR</strong>: Destination topic ID not found!', 'bbpress'));
                } else {
                    $destination_topic_id = (int) $_POST['bbp_destination_topic'];
                }
                // Get the destination topic
                $destination_topic = bbp_get_topic($destination_topic_id);
                // No destination topic
                if (empty($destination_topic)) {
                    bbp_add_error('bbp_split_topic_destination_not_found', __('<strong>ERROR</strong>: The topic you want to split to was not found!', 'bbpress'));
                }
                // User cannot edit the destination topic
                if (!current_user_can('edit_topic', $destination_topic->ID)) {
                    bbp_add_error('bbp_split_topic_destination_permission', __('<strong>ERROR</strong>: You do not have the permissions to edit the destination topic!', 'bbpress'));
                }
                break;
                // Split at reply into a new topic
            // Split at reply into a new topic
            case 'reply':
            default:
                // User needs to be able to publish topics
                if (current_user_can('publish_topics')) {
                    // Use the new title that was passed
                    if (!empty($_POST['bbp_topic_split_destination_title'])) {
                        $destination_topic_title = esc_attr(strip_tags($_POST['bbp_topic_split_destination_title']));
                        // Use the source topic title
                    } else {
                        $destination_topic_title = $source_topic->post_title;
                    }
                    // Update the topic
                    $destination_topic_id = wp_update_post(array('ID' => $from_reply->ID, 'post_title' => $destination_topic_title, 'post_name' => false, 'post_type' => bbp_get_topic_post_type(), 'post_parent' => $source_topic->post_parent, 'menu_order' => 0, 'guid' => ''));
                    $destination_topic = bbp_get_topic($destination_topic_id);
                    // Make sure the new topic knows its a topic
                    bbp_update_topic_topic_id($from_reply->ID);
                    // Shouldn't happen
                    if (false === $destination_topic_id || is_wp_error($destination_topic_id) || empty($destination_topic)) {
                        bbp_add_error('bbp_split_topic_destination_reply', __('<strong>ERROR</strong>: There was a problem converting the reply into the topic. Please try again.', 'bbpress'));
                    }
                    // User cannot publish posts
                } else {
                    bbp_add_error('bbp_split_topic_destination_permission', __('<strong>ERROR</strong>: You do not have the permissions to create new topics. The reply could not be converted into a topic.', 'bbpress'));
                }
                break;
        }
    }
    // Bail if there are errors
    if (bbp_has_errors()) {
        return;
    }
    /** No Errors - Do the Spit ***********************************************/
    // Update counts, etc...
    do_action('bbp_pre_split_topic', $from_reply->ID, $source_topic->ID, $destination_topic->ID);
    /** Date Check ************************************************************/
    // Check if the destination topic is older than the from reply
    if (strtotime($from_reply->post_date) < strtotime($destination_topic->post_date)) {
        // Set destination topic post_date to 1 second before from reply
        $destination_post_date = date('Y-m-d H:i:s', strtotime($from_reply->post_date) - 1);
        // Update destination topic
        wp_update_post(array('ID' => $destination_topic_id, 'post_date' => $destination_post_date, 'post_date_gmt' => get_gmt_from_date($destination_post_date)));
    }
    /** Subscriptions *********************************************************/
    // Copy the subscribers
    if (!empty($_POST['bbp_topic_subscribers']) && "1" === $_POST['bbp_topic_subscribers'] && bbp_is_subscriptions_active()) {
        // Get the subscribers
        $subscribers = bbp_get_topic_subscribers($source_topic->ID);
        if (!empty($subscribers)) {
            // Add subscribers to new topic
            foreach ((array) $subscribers as $subscriber) {
                bbp_add_user_subscription($subscriber, $destination_topic->ID);
            }
        }
    }
    /** Favorites *************************************************************/
    // Copy the favoriters if told to
    if (!empty($_POST['bbp_topic_favoriters']) && "1" === $_POST['bbp_topic_favoriters']) {
        // Get the favoriters
        $favoriters = bbp_get_topic_favoriters($source_topic->ID);
        if (!empty($favoriters)) {
            // Add the favoriters to new topic
            foreach ((array) $favoriters as $favoriter) {
                bbp_add_user_favorite($favoriter, $destination_topic->ID);
            }
        }
    }
    /** Tags ******************************************************************/
    // Copy the tags if told to
    if (!empty($_POST['bbp_topic_tags']) && "1" === $_POST['bbp_topic_tags']) {
        // Get the source topic tags
        $source_topic_tags = wp_get_post_terms($source_topic->ID, bbp_get_topic_tag_tax_id(), array('fields' => 'names'));
        if (!empty($source_topic_tags)) {
            wp_set_post_terms($destination_topic->ID, $source_topic_tags, bbp_get_topic_tag_tax_id(), true);
        }
    }
    /** Split Replies *********************************************************/
    // get_posts() is not used because it doesn't allow us to use '>='
    // comparision without a filter.
    $replies = (array) $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE {$wpdb->posts}.post_date >= %s AND {$wpdb->posts}.post_parent = %d AND {$wpdb->posts}.post_type = %s ORDER BY {$wpdb->posts}.post_date ASC", $from_reply->post_date, $source_topic->ID, bbp_get_reply_post_type()));
    // Make sure there are replies to loop through
    if (!empty($replies) && !is_wp_error($replies)) {
        // Calculate starting point for reply positions
        switch ($split_option) {
            // Get topic reply count for existing topic
            case 'existing':
                $reply_position = bbp_get_topic_reply_count($destination_topic->ID);
                break;
                // Account for new lead topic
            // Account for new lead topic
            case 'reply':
                $reply_position = 1;
                break;
        }
        // Save reply ids
        $reply_ids = array();
        // Change the post_parent of each reply to the destination topic id
        foreach ($replies as $reply) {
            // Bump the reply position each iteration through the loop
            $reply_position++;
            // Update the reply
            wp_update_post(array('ID' => $reply->ID, 'post_title' => sprintf(__('Reply To: %s', 'bbpress'), $destination_topic->post_title), 'post_name' => false, 'post_parent' => $destination_topic->ID, 'menu_order' => $reply_position, 'guid' => ''));
            // Gather reply ids
            $reply_ids[] = $reply->ID;
            // Adjust reply meta values
            bbp_update_reply_topic_id($reply->ID, $destination_topic->ID);
            bbp_update_reply_forum_id($reply->ID, bbp_get_topic_forum_id($destination_topic->ID));
            // Adjust reply to values
            $reply_to = bbp_get_reply_to($reply->ID);
            // Not a reply to a reply that moved over
            if (!in_array($reply_to, $reply_ids)) {
                bbp_update_reply_to($reply->ID, 0);
            }
            // New topic from reply can't be a reply to
            if ($from_reply->ID === $destination_topic->ID && $from_reply->ID === $reply_to) {
                bbp_update_reply_to($reply->ID, 0);
            }
            // Do additional actions per split reply
            do_action('bbp_split_topic_reply', $reply->ID, $destination_topic->ID);
        }
        // Remove reply to from new topic
        if ($from_reply->ID === $destination_topic->ID) {
            delete_post_meta($from_reply->ID, '_bbp_reply_to');
        }
        // Set the last reply ID and freshness
        $last_reply_id = $reply->ID;
        $freshness = $reply->post_date;
        // Set the last reply ID and freshness to the from_reply
    } else {
        $last_reply_id = $from_reply->ID;
        $freshness = $from_reply->post_date;
    }
    // It is a new topic and we need to set some default metas to make
    // the topic display in bbp_has_topics() list
    if ('reply' === $split_option) {
        bbp_update_topic_last_reply_id($destination_topic->ID, $last_reply_id);
        bbp_update_topic_last_active_id($destination_topic->ID, $last_reply_id);
        bbp_update_topic_last_active_time($destination_topic->ID, $freshness);
    }
    // Update source topic ID last active
    bbp_update_topic_last_reply_id($source_topic->ID);
    bbp_update_topic_last_active_id($source_topic->ID);
    bbp_update_topic_last_active_time($source_topic->ID);
    /** Successful Split ******************************************************/
    // Update counts, etc...
    do_action('bbp_post_split_topic', $from_reply->ID, $source_topic->ID, $destination_topic->ID);
    // Redirect back to the topic
    wp_safe_redirect(bbp_get_topic_permalink($destination_topic->ID));
    // For good measure
    exit;
}
/**
 * Move reply handler
 *
 * Handles the front end move reply submission
 *
 * @since bbPress (r4521)
 *
 * @param string $action The requested action to compare this function to
 * @uses bbp_add_error() To add an error message
 * @uses bbp_get_reply() To get the reply
 * @uses bbp_get_topic() To get the topics
 * @uses bbp_verify_nonce_request() To verify the nonce and check the request
 * @uses current_user_can() To check if the current user can edit the reply and topics
 * @uses bbp_get_topic_post_type() To get the topic post type
 * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
 * @uses do_action() Calls 'bbp_pre_move_reply' with the from reply id, source
 *                    and destination topic ids
 * @uses bbp_get_reply_post_type() To get the reply post type
 * @uses wpdb::prepare() To prepare our sql query
 * @uses wpdb::get_results() To execute the sql query and get results
 * @uses wp_update_post() To update the replies
 * @uses bbp_update_reply_topic_id() To update the reply topic id
 * @uses bbp_get_topic_forum_id() To get the topic forum id
 * @uses bbp_update_reply_forum_id() To update the reply forum id
 * @uses do_action() Calls 'bbp_split_topic_reply' with the reply id and
 *                    destination topic id
 * @uses bbp_update_topic_last_reply_id() To update the topic last reply id
 * @uses bbp_update_topic_last_active_time() To update the topic last active meta
 * @uses do_action() Calls 'bbp_post_split_topic' with the destination and
 *                    source topic ids and source topic's forum id
 * @uses bbp_get_topic_permalink() To get the topic permalink
 * @uses wp_safe_redirect() To redirect to the topic link
 */
function bbp_move_reply_handler($action = '')
{
    // Bail if action is not 'bbp-move-reply'
    if ('bbp-move-reply' !== $action) {
        return;
    }
    // Prevent debug notices
    $move_reply_id = $destination_topic_id = 0;
    $destination_topic_title = '';
    $destination_topic = $move_reply = $source_topic = '';
    /** Move Reply ***********************************************************/
    if (empty($_POST['bbp_reply_id'])) {
        bbp_add_error('bbp_move_reply_reply_id', __('<strong>ERROR</strong>: Reply ID to move not found!', 'bbpress'));
    } else {
        $move_reply_id = (int) $_POST['bbp_reply_id'];
    }
    $move_reply = bbp_get_reply($move_reply_id);
    // Reply exists
    if (empty($move_reply)) {
        bbp_add_error('bbp_mover_reply_r_not_found', __('<strong>ERROR</strong>: The reply you want to move was not found.', 'bbpress'));
    }
    /** Topic to Move From ***************************************************/
    // Get the reply's current topic
    $source_topic = bbp_get_topic($move_reply->post_parent);
    // No topic
    if (empty($source_topic)) {
        bbp_add_error('bbp_move_reply_source_not_found', __('<strong>ERROR</strong>: The topic you want to move from was not found.', 'bbpress'));
    }
    // Nonce check failed
    if (!bbp_verify_nonce_request('bbp-move-reply_' . $move_reply->ID)) {
        bbp_add_error('bbp_move_reply_nonce', __('<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress'));
        return;
    }
    // Use cannot edit topic
    if (!current_user_can('edit_topic', $source_topic->ID)) {
        bbp_add_error('bbp_move_reply_source_permission', __('<strong>ERROR</strong>: You do not have the permissions to edit the source topic.', 'bbpress'));
    }
    // How to move
    if (!empty($_POST['bbp_reply_move_option'])) {
        $move_option = (string) trim($_POST['bbp_reply_move_option']);
    }
    // Invalid move option
    if (empty($move_option) || !in_array($move_option, array('existing', 'topic'))) {
        bbp_add_error('bbp_move_reply_option', __('<strong>ERROR</strong>: You need to choose a valid move option.', 'bbpress'));
        // Valid move option
    } else {
        // What kind of move
        switch ($move_option) {
            // Into an existing topic
            case 'existing':
                // Get destination topic id
                if (empty($_POST['bbp_destination_topic'])) {
                    bbp_add_error('bbp_move_reply_destination_id', __('<strong>ERROR</strong>: Destination topic ID not found!', 'bbpress'));
                } else {
                    $destination_topic_id = (int) $_POST['bbp_destination_topic'];
                }
                // Get the destination topic
                $destination_topic = bbp_get_topic($destination_topic_id);
                // No destination topic
                if (empty($destination_topic)) {
                    bbp_add_error('bbp_move_reply_destination_not_found', __('<strong>ERROR</strong>: The topic you want to move to was not found!', 'bbpress'));
                }
                // User cannot edit the destination topic
                if (!current_user_can('edit_topic', $destination_topic->ID)) {
                    bbp_add_error('bbp_move_reply_destination_permission', __('<strong>ERROR</strong>: You do not have the permissions to edit the destination topic!', 'bbpress'));
                }
                // Bump the reply position
                $reply_position = bbp_get_topic_reply_count($destination_topic->ID) + 1;
                // Update the reply
                wp_update_post(array('ID' => $move_reply->ID, 'post_title' => sprintf(__('Reply To: %s', 'bbpress'), $destination_topic->post_title), 'post_name' => false, 'post_parent' => $destination_topic->ID, 'menu_order' => $reply_position, 'guid' => ''));
                // Adjust reply meta values
                bbp_update_reply_topic_id($move_reply->ID, $destination_topic->ID);
                bbp_update_reply_forum_id($move_reply->ID, bbp_get_topic_forum_id($destination_topic->ID));
                break;
                // Move reply to a new topic
            // Move reply to a new topic
            case 'topic':
            default:
                // User needs to be able to publish topics
                if (current_user_can('publish_topics')) {
                    // Use the new title that was passed
                    if (!empty($_POST['bbp_reply_move_destination_title'])) {
                        $destination_topic_title = esc_attr(strip_tags($_POST['bbp_reply_move_destination_title']));
                        // Use the source topic title
                    } else {
                        $destination_topic_title = $source_topic->post_title;
                    }
                    // Update the topic
                    $destination_topic_id = wp_update_post(array('ID' => $move_reply->ID, 'post_title' => $destination_topic_title, 'post_name' => false, 'post_type' => bbp_get_topic_post_type(), 'post_parent' => $source_topic->post_parent, 'guid' => ''));
                    $destination_topic = bbp_get_topic($destination_topic_id);
                    // Make sure the new topic knows its a topic
                    bbp_update_topic_topic_id($move_reply->ID);
                    // Shouldn't happen
                    if (false === $destination_topic_id || is_wp_error($destination_topic_id) || empty($destination_topic)) {
                        bbp_add_error('bbp_move_reply_destination_reply', __('<strong>ERROR</strong>: There was a problem converting the reply into the topic. Please try again.', 'bbpress'));
                    }
                    // User cannot publish posts
                } else {
                    bbp_add_error('bbp_move_reply_destination_permission', __('<strong>ERROR</strong>: You do not have the permissions to create new topics. The reply could not be converted into a topic.', 'bbpress'));
                }
                break;
        }
    }
    // Bail if there are errors
    if (bbp_has_errors()) {
        return;
    }
    /** No Errors - Clean Up **************************************************/
    // Update counts, etc...
    do_action('bbp_pre_move_reply', $move_reply->ID, $source_topic->ID, $destination_topic->ID);
    /** Date Check ************************************************************/
    // Check if the destination topic is older than the move reply
    if (strtotime($move_reply->post_date) < strtotime($destination_topic->post_date)) {
        // Set destination topic post_date to 1 second before from reply
        $destination_post_date = date('Y-m-d H:i:s', strtotime($move_reply->post_date) - 1);
        // Update destination topic
        wp_update_post(array('ID' => $destination_topic_id, 'post_date' => $destination_post_date, 'post_date_gmt' => get_gmt_from_date($destination_post_date)));
    }
    // Set the last reply ID and freshness to the move_reply
    $last_reply_id = $move_reply->ID;
    $freshness = $move_reply->post_date;
    // Get the reply to
    $parent = bbp_get_reply_to($move_reply->ID);
    // Fix orphaned children
    $children = get_posts(array('post_type' => bbp_get_reply_post_type(), 'meta_key' => '_bbp_reply_to', 'meta_value' => $move_reply->ID));
    foreach ($children as $child) {
        bbp_update_reply_to($child->ID, $parent);
    }
    // Remove reply_to from moved reply
    delete_post_meta($move_reply->ID, '_bbp_reply_to');
    // It is a new topic and we need to set some default metas to make
    // the topic display in bbp_has_topics() list
    if ('topic' === $move_option) {
        bbp_update_topic_last_reply_id($destination_topic->ID, $last_reply_id);
        bbp_update_topic_last_active_id($destination_topic->ID, $last_reply_id);
        bbp_update_topic_last_active_time($destination_topic->ID, $freshness);
        // Otherwise update the existing destination topic
    } else {
        bbp_update_topic_last_reply_id($destination_topic->ID);
        bbp_update_topic_last_active_id($destination_topic->ID);
        bbp_update_topic_last_active_time($destination_topic->ID);
    }
    // Update source topic ID last active
    bbp_update_topic_last_reply_id($source_topic->ID);
    bbp_update_topic_last_active_id($source_topic->ID);
    bbp_update_topic_last_active_time($source_topic->ID);
    /** Successful Move ******************************************************/
    // Update counts, etc...
    do_action('bbp_post_move_reply', $move_reply->ID, $source_topic->ID, $destination_topic->ID);
    // Redirect back to the topic
    wp_safe_redirect(bbp_get_topic_permalink($destination_topic->ID));
    // For good measure
    exit;
}
Example #4
0
/**
 * Walk up the ancestor tree from the current reply, and update all the counts
 *
 * @since bbPress (r2884)
 *
 * @param int $reply_id Optional. Reply id
 * @param string $last_active_time Optional. Last active time
 * @param int $forum_id Optional. Forum id
 * @param int $topic_id Optional. Topic id
 * @param bool $refresh If set to true, unsets all the previous parameters.
 *                       Defaults to true
 * @uses bbp_get_reply_id() To get the reply id
 * @uses bbp_get_reply_topic_id() To get the reply topic id
 * @uses bbp_get_reply_forum_id() To get the reply forum id
 * @uses get_post_ancestors() To get the ancestors of the reply
 * @uses bbp_is_reply() To check if the ancestor is a reply
 * @uses bbp_is_topic() To check if the ancestor is a topic
 * @uses bbp_update_topic_last_reply_id() To update the topic last reply id
 * @uses bbp_update_topic_last_active_id() To update the topic last active id
 * @uses bbp_get_topic_last_active_id() To get the topic last active id
 * @uses get_post_field() To get the post date of the last active id
 * @uses bbp_update_topic_last_active_time() To update the last active topic meta
 * @uses bbp_update_topic_voice_count() To update the topic voice count
 * @uses bbp_update_topic_reply_count() To update the topic reply count
 * @uses bbp_update_topic_reply_count_hidden() To update the topic hidden reply
 *                                              count
 * @uses bbp_is_forum() To check if the ancestor is a forum
 * @uses bbp_update_forum_last_topic_id() To update the last topic id forum meta
 * @uses bbp_update_forum_last_reply_id() To update the last reply id forum meta
 * @uses bbp_update_forum_last_active_id() To update the forum last active id
 * @uses bbp_get_forum_last_active_id() To get the forum last active id
 * @uses bbp_update_forum_last_active_time() To update the forum last active time
 * @uses bbp_update_forum_reply_count() To update the forum reply count
 */
function bbp_update_reply_walker($reply_id, $last_active_time = '', $forum_id = 0, $topic_id = 0, $refresh = true)
{
    // Verify the reply ID
    $reply_id = bbp_get_reply_id($reply_id);
    // Reply was passed
    if (!empty($reply_id)) {
        // Get the topic ID if none was passed
        if (empty($topic_id)) {
            $topic_id = bbp_get_reply_topic_id($reply_id);
        }
        // Get the forum ID if none was passed
        if (empty($forum_id)) {
            $forum_id = bbp_get_reply_forum_id($reply_id);
        }
    }
    // Set the active_id based on topic_id/reply_id
    $active_id = empty($reply_id) ? $topic_id : $reply_id;
    // Setup ancestors array to walk up
    $ancestors = array_values(array_unique(array_merge(array($topic_id, $forum_id), (array) get_post_ancestors($topic_id))));
    // If we want a full refresh, unset any of the possibly passed variables
    if (true == $refresh) {
        $forum_id = $topic_id = $reply_id = $active_id = $last_active_time = 0;
    }
    // Walk up ancestors
    if (!empty($ancestors)) {
        foreach ($ancestors as $ancestor) {
            // Reply meta relating to most recent reply
            if (bbp_is_reply($ancestor)) {
                // @todo - hierarchical replies
                // Topic meta relating to most recent reply
            } elseif (bbp_is_topic($ancestor)) {
                // Last reply and active ID's
                bbp_update_topic_last_reply_id($ancestor, $reply_id);
                bbp_update_topic_last_active_id($ancestor, $active_id);
                // Get the last active time if none was passed
                $topic_last_active_time = $last_active_time;
                if (empty($last_active_time)) {
                    $topic_last_active_time = get_post_field('post_date', bbp_get_topic_last_active_id($ancestor));
                }
                // Only update if reply is published
                if (bbp_is_reply_published($reply_id)) {
                    bbp_update_topic_last_active_time($ancestor, $topic_last_active_time);
                }
                // Counts
                bbp_update_topic_voice_count($ancestor);
                bbp_update_topic_reply_count($ancestor);
                bbp_update_topic_reply_count_hidden($ancestor);
                // Forum meta relating to most recent topic
            } elseif (bbp_is_forum($ancestor)) {
                // Last topic and reply ID's
                bbp_update_forum_last_topic_id($ancestor, $topic_id);
                bbp_update_forum_last_reply_id($ancestor, $reply_id);
                // Last Active
                bbp_update_forum_last_active_id($ancestor, $active_id);
                // Get the last active time if none was passed
                $forum_last_active_time = $last_active_time;
                if (empty($last_active_time)) {
                    $forum_last_active_time = get_post_field('post_date', bbp_get_forum_last_active_id($ancestor));
                }
                // Only update if reply is published
                if (bbp_is_reply_published($reply_id)) {
                    bbp_update_forum_last_active_time($ancestor, $forum_last_active_time);
                }
                // Counts
                bbp_update_forum_reply_count($ancestor);
            }
        }
    }
}