Exemplo n.º 1
0
/**
 * Return the numeric position of a reply within a topic
 *
 * @since bbPress (r2984)
 *
 * @param int $reply_id Optional. Reply id
 * @param int $topic_id Optional. Topic id
 * @uses bbp_get_reply_id() To get the reply id
 * @uses bbp_get_reply_topic_id() Get the topic id of the reply id
 * @uses bbp_get_topic_reply_count() To get the topic reply count
 * @uses bbp_get_reply_post_type() To get the reply post type
 * @uses bbp_get_reply_position_raw() To get calculate the reply position
 * @uses bbp_update_reply_position() To update the reply position
 * @uses bbp_show_lead_topic() Bump the count if lead topic is included
 * @uses apply_filters() Calls 'bbp_get_reply_position' with the reply
 *                        position, reply id and topic id
 * @return int Reply position
 */
function bbp_get_reply_position($reply_id = 0, $topic_id = 0)
{
    // Get required data
    $reply_id = bbp_get_reply_id($reply_id);
    $reply_position = get_post_field('menu_order', $reply_id);
    // Reply doesn't have a position so get the raw value
    if (empty($reply_position)) {
        $topic_id = !empty($topic_id) ? bbp_get_topic_id($topic_id) : bbp_get_reply_topic_id($reply_id);
        // Post is not the topic
        if ($reply_id !== $topic_id) {
            $reply_position = bbp_get_reply_position_raw($reply_id, $topic_id);
            // Update the reply position in the posts table so we'll never have
            // to hit the DB again.
            if (!empty($reply_position)) {
                bbp_update_reply_position($reply_id, $reply_position);
            }
            // Topic's position is always 0
        } else {
            $reply_position = 0;
        }
    }
    // Bump the position by one if the lead topic is in the replies loop
    if (!bbp_show_lead_topic()) {
        $reply_position++;
    }
    return (int) apply_filters('bbp_get_reply_position', $reply_position, $reply_id, $topic_id);
}
Exemplo n.º 2
0
/**
 * Recalculate reply menu order
 *
 * @since 2.5.4 bbPress (r5367)
 *
 * @uses wpdb::query() To run our recount sql queries
 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
 * @uses bbp_get_reply_post_type() To get the reply post type
 * @uses bbp_update_reply_position() To update the reply position
 * @return array An array of the status code and the message
 */
function bbp_admin_repair_reply_menu_order()
{
    // Define variables
    $bbp_db = bbp_db();
    $statement = __('Recalculating reply menu order … %s', 'bbpress');
    $result = __('No reply positions to recalculate!', 'bbpress');
    // Delete cases where `_bbp_reply_to` was accidentally set to itself
    if (is_wp_error($bbp_db->query("DELETE FROM `{$bbp_db->postmeta}` WHERE `meta_key` = '_bbp_reply_to' AND `post_id` = `meta_value`;"))) {
        return array(1, sprintf($statement, $result));
    }
    // Post type
    $rpt = bbp_get_reply_post_type();
    // Get an array of reply id's to update the menu oder for each reply
    $replies = $bbp_db->get_results("SELECT `a`.`ID` FROM `{$bbp_db->posts}` AS `a`\n\t\t\t\t\t\t\t\t\t\tINNER JOIN (\n\t\t\t\t\t\t\t\t\t\t\tSELECT `menu_order`, `post_parent`\n\t\t\t\t\t\t\t\t\t\t\tFROM `{$bbp_db->posts}`\n\t\t\t\t\t\t\t\t\t\t\tGROUP BY `menu_order`, `post_parent`\n\t\t\t\t\t\t\t\t\t\t\tHAVING COUNT( * ) >1\n\t\t\t\t\t\t\t\t\t\t)`b`\n\t\t\t\t\t\t\t\t\t\tON `a`.`menu_order` = `b`.`menu_order`\n\t\t\t\t\t\t\t\t\t\tAND `a`.`post_parent` = `b`.`post_parent`\n\t\t\t\t\t\t\t\t\t\tWHERE `post_type` = '{$rpt}';", OBJECT_K);
    // Bail if no replies returned
    if (empty($replies)) {
        return array(1, sprintf($statement, $result));
    }
    // Recalculate the menu order position for each reply
    foreach ($replies as $reply) {
        bbp_update_reply_position($reply->ID);
    }
    // Cleanup
    unset($replies, $reply);
    // Flush the cache; things are about to get ugly.
    wp_cache_flush();
    return array(0, sprintf($statement, __('Complete!', 'bbpress')));
}
Exemplo n.º 3
0
/**
 * Split topic handler
 *
 * Handles the front end split topic submission
 *
 * @since 2.0.0 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 bbp_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;
    }
    // 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>: A reply ID is required.', '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 permission to edit the source topic.', 'bbpress'));
    }
    // How to Split
    if (!empty($_POST['bbp_topic_split_option'])) {
        $split_option = sanitize_key($_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>: A topic ID is required.', '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 permission 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 = sanitize_text_field($_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 permission 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.
    $bbp_db = bbp_db();
    $query = $bbp_db->prepare("SELECT * FROM {$bbp_db->posts} WHERE {$bbp_db->posts}.post_date >= %s AND {$bbp_db->posts}.post_parent = %d AND {$bbp_db->posts}.post_type = %s ORDER BY {$bbp_db->posts}.post_date ASC", $from_reply->post_date, $source_topic->ID, bbp_get_reply_post_type());
    $replies = (array) $bbp_db->get_results($query);
    // Make sure there are replies to loop through
    if (!empty($replies) && !is_wp_error($replies)) {
        // Save reply ids
        $reply_ids = array();
        // Change the post_parent of each reply to the destination topic id
        foreach ($replies as $reply) {
            // Update the reply
            wp_update_post(array('ID' => $reply->ID, 'post_title' => '', 'post_name' => false, 'post_parent' => $destination_topic->ID, '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 position
            bbp_update_reply_position($reply->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
    bbp_redirect(bbp_get_topic_permalink($destination_topic->ID));
}