Skip to:
Content

bbPress.org

Ticket #2036: 2036.1.diff

File 2036.1.diff, 43.3 KB (added by jmdodd, 8 years ago)

First pass at hierarchical replies. (Work in progress.)

  • includes/admin/metaboxes.php

     
    402402        // Get some meta
    403403        $reply_topic_id = bbp_get_reply_topic_id( $post_id );
    404404        $reply_forum_id = bbp_get_reply_forum_id( $post_id );
     405        $reply_to       = bbp_get_reply_to(       $post_id );
    405406
    406407        // Allow individual manipulation of reply forum
    407408        if ( current_user_can( 'edit_others_replies' ) || current_user_can( 'moderate' ) ) : ?>
     
    438439                <input name="parent_id" id="bbp_topic_id" type="text" value="<?php echo esc_attr( $reply_topic_id ); ?>" />
    439440        </p>
    440441
     442        <p>
     443                <strong class="label"><?php _e( 'Reply To:', 'bbpress' ); ?></strong>
     444                <label class="screen-reader-text" for="bbp_reply_to"><?php _e( 'Reply To', 'bbpress' ); ?></label>
     445                <input name="bbp_reply_to" id="bbp_reply_to" type="text" value="<?php echo esc_attr( $reply_to ); ?>" />
     446        </p>
     447
    441448        <?php
    442449        wp_nonce_field( 'bbp_reply_metabox_save', 'bbp_reply_metabox' );
    443450        do_action( 'bbp_reply_metabox', $post_id );
  • includes/admin/replies.php

     
    224224                                '<ul>' .
    225225                                        '<li>' . __( '<strong>Forum</strong> dropdown determines the parent forum that the reply belongs to. Select the forum, or leave the default (Use Forum of Topic) to post the reply in forum of the topic.', 'bbpress' ) . '</li>' .
    226226                                        '<li>' . __( '<strong>Topic</strong> determines the parent topic that the reply belongs to.', 'bbpress' ) . '</li>' .
     227                                        '<li>' . __( '<strong>Reply To</strong> determines the threading of the reply.', 'bbpress' ) . '</li>' .
    227228                                '</ul>'
    228229                ) );
    229230
     
    310311                        return $reply_id;
    311312
    312313                // Get the reply meta post values
    313                 $topic_id = !empty( $_POST['parent_id']    ) ? (int) $_POST['parent_id']    : 0;
    314                 $forum_id = !empty( $_POST['bbp_forum_id'] ) ? (int) $_POST['bbp_forum_id'] : bbp_get_topic_forum_id( $topic_id );
     314                $topic_id    = !empty( $_POST['parent_id']    ) ? (int) $_POST['parent_id']    : 0;
     315                $forum_id    = !empty( $_POST['bbp_forum_id'] ) ? (int) $_POST['bbp_forum_id'] : bbp_get_topic_forum_id( $topic_id );
     316                $reply_to    = !empty( $_POST['bbp_reply_to'] ) ? (int) $_POST['bbp_reply_to'] : 0;
    315317
    316318                // Formally update the reply
    317                 bbp_update_reply( $reply_id, $topic_id, $forum_id );
     319                bbp_update_reply( $reply_id, $topic_id, $forum_id, false, 0, false, $reply_to );
    318320
    319321                // Allow other fun things to happen
    320                 do_action( 'bbp_reply_attributes_metabox_save', $reply_id, $topic_id, $forum_id );
     322                do_action( 'bbp_reply_attributes_metabox_save', $reply_id, $topic_id, $forum_id, $reply_to );
    321323
    322324                return $reply_id;
    323325        }
  • includes/admin/settings.php

     
    169169
    170170                'bbp_settings_theme_compat' => array(
    171171
    172                         // Replies per page setting
     172                        // Theme package setting
    173173                        '_bbp_theme_package_id' => array(
    174174                                'title'             => __( 'Current Package', 'bbpress' ),
    175175                                'callback'          => 'bbp_admin_setting_callback_subtheme_id',
     
    196196                                'callback'          => 'bbp_admin_setting_callback_replies_per_page',
    197197                                'sanitize_callback' => 'intval',
    198198                                'args'              => array()
     199                        ),
     200
     201                        // Allow hierarchical replies
     202                        '_bbp_thread_replies' => array(
     203                                'title'             => __( 'Thread replies', 'bbpress' ),
     204                                'callback'          => 'bbp_admin_setting_callback_thread_replies',
     205                                'sanitize_callback' => 'intval',
     206                                'args'              => array()
     207                        ),
     208
     209                        // Set reply threading level
     210                        '_bbp_thread_replies_depth' => array(
     211                                'title'             => __( 'Maximum levels', 'bbpress' ),
     212                                'callback'          => 'bbp_admin_setting_callback_thread_replies_depth',
     213                                'sanitize_callback' => 'intval',
     214                                'args'              => array()
    199215                        )
    200216                ),
    201217
     
    461477}
    462478
    463479/**
     480 * Allow hierarchical replies setting field
     481 *
     482 * @since bbPress (r####)
     483 *
     484 * @uses checked() To display the checked attribute
     485 * @uses bbp_thread_replies() To determine if replies are threaded
     486 */
     487function bbp_admin_setting_callback_thread_replies() {
     488?>
     489
     490        <input id="_bbp_thread_replies" name="_bbp_thread_replies" type="checkbox" id="_bbp_thread_replies" value="1" <?php checked( bbp_thread_replies( true ) ); bbp_maybe_admin_setting_disabled( '_bbp_thread_replies' ); ?> />
     491        <label for="_bbp_thread_replies"><?php _e( 'Enabled threaded (nested) replies', 'bbpress' ); ?></label>
     492
     493<?php
     494}
     495
     496/**
     497 * Hierarchical reply max depth level setting field
     498 *
     499 * @since bbPress (r####)
     500 *
     501 * @uses apply_filters() Calls 'bbp_thread_replies_depth_max' to set a
     502 *                        maximum displayed level
     503 * @uses selected() To display the selected attribute
     504 */
     505function bbp_admin_setting_callback_thread_replies_depth() {
     506
     507        // Set maximum depth for dropdown
     508        $max_depth = (int) apply_filters( 'bbp_thread_replies_depth_max', 10 );
     509        $current_depth = get_option( '_bbp_thread_replies_depth' );
     510
     511?>
     512        <label for="_bbp_thread_replies_depth">
     513                <select id="_bbp_thread_replies_depth" name="_bbp_thread_replies_depth">
     514                <?php for ( $i = 2; $i <= $max_depth; $i++ ) : ?>
     515
     516                        <option value="<?php echo esc_attr( $i ); ?>" <?php selected( $i, $current_depth ); ?>><?php echo esc_html( $i ); ?></option>
     517
     518                <?php endfor; ?>
     519                </select>
     520        <?php _e( ' levels deep', 'bbpress' ); ?>
     521        </label>
     522<?php
     523}
     524
     525/**
    464526 * Allow topic and reply revisions
    465527 *
    466528 * @since bbPress (r3412)
  • includes/common/classes.php

     
    259259        }
    260260}
    261261
     262/**
     263 * Create hierarchical list of bbPress replies.
     264 *
     265 * @package bbPress
     266 * @subpackage Classes
     267 *
     268 * @since bbPress (r####)
     269 */
     270class Walker_Reply extends Walker {
     271
     272        /**
     273         * @see Walker::$tree_type
     274         *
     275         * @since bbPress (r####)
     276         *
     277         * @var string
     278         */
     279        var $tree_type = 'reply';
     280
     281        /**
     282         * @see Walker::$db_fields
     283         *
     284         * @since bbPress (r####)
     285         *
     286         * @var array
     287         */
     288        var $db_fields = array(
     289                'parent' => 'reply_to',
     290                'id'     => 'ID'
     291        );
     292
     293        /**
     294         * @see Walker::start_lvl()
     295         *
     296         * @since bbPress (r####)
     297         *
     298         * @param string $output Passed by reference. Used to append additional content
     299         * @param int $depth Depth of reply
     300         * @param array $args Uses 'style' argument for type of HTML list
     301         */
     302        public function start_lvl( &$output, $depth = 0, $args = array() ) {
     303                $GLOBALS['reply_depth'] = $depth + 1;
     304
     305                switch ( $args['style'] ) {
     306                        case 'div':
     307                                break;
     308                        case 'ol':
     309                                echo "<ol class='children'>\n";
     310                                break;
     311                        case 'ul':
     312                        default:
     313                                echo "<ul class='children'>\n";
     314                                break;
     315                }
     316        }
     317
     318        /**
     319         * @see Walker::end_lvl()
     320         *
     321         * @since bbPress (r####)
     322         *
     323         * @param string $output Passed by reference. Used to append additional content
     324         * @param int $depth Depth of reply
     325         * @param array $args Will only append content if style argument value is 'ol' or 'ul'
     326         */
     327        public function end_lvl( &$output, $depth = 0, $args = array() ) {
     328                $GLOBALS['reply_depth'] = $depth + 1;
     329
     330                switch ( $args['style'] ) {
     331                        case 'div':
     332                                break;
     333                        case 'ol':
     334                                echo "</ol>\n";
     335                                break;
     336                        case 'ul':
     337                        default:
     338                                echo "</ul>\n";
     339                                break;
     340                }
     341        }
     342
     343        /**
     344         * @since bbPress (r####)
     345         */
     346        public function display_element( $element, &$children_elements, $max_depth, $depth = 0, $args, &$output ) {
     347
     348                if ( !$element )
     349                        return;
     350
     351                // Get element's id
     352                $id_field = $this->db_fields['id'];
     353                $id       = $element->$id_field;
     354
     355                // Display element
     356                parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
     357
     358                // If we're at the max depth and the current element still has children, loop over those
     359                // and display them at this level to prevent them being orphaned to the end of the list.
     360                if ( $max_depth <= $depth + 1 && isset( $children_elements[$id]) ) {
     361                        foreach ( $children_elements[ $id ] as $child )
     362                                $this->display_element( $child, $children_elements, $max_depth, $depth, $args, $output );
     363
     364                        unset( $children_elements[ $id ] );
     365                }
     366        }
     367
     368        /**
     369         * @see Walker:start_el()
     370         *
     371         * @since bbPress (r####)
     372         */
     373        public function start_el( &$output, $reply, $depth, $args, $id = 0 ) {
     374
     375                // Set up reply
     376                $depth++;
     377                $GLOBALS['reply_depth'] = $depth;
     378                bbpress()->reply_query->post = $reply;
     379                bbpress()->current_reply_id = $reply->ID;
     380
     381                // Check for a callback and use it if specified
     382                if ( !empty($args['callback']) ) {
     383                        call_user_func( $args['callback'], $reply, $args, $depth );
     384                        return;
     385                }
     386
     387                // Style for div or list element
     388                if ( 'div' == $args['style'] ) {
     389                        $tag = 'div';
     390                        $add_below = 'reply';
     391                } else {
     392                        $tag = 'li';
     393                        $add_below = 'div-reply';
     394                } ?>
     395
     396                <<?php echo $tag ?>>
     397
     398                <div id="reply-<?php bbp_reply_ID(); ?>">
     399
     400                        <?php bbp_get_template_part( 'loop', 'single-reply' ); ?>
     401
     402                        <?php if ( $reply->post_type == bbp_get_reply_post_type() ) : ?>
     403
     404                        <div class="reply-to"><?php bbp_reply_to_link( array_merge( $args, array( 'depth' => $depth ) ), $reply ); ?></div>
     405
     406                        <?php endif; ?>
     407
     408                </div>
     409
     410                <?php
     411        }
     412
     413        /**
     414         * @since bbPress (r####)
     415         */
     416        public function end_el( &$output, $reply, $depth = 0, $args = array() ) {
     417
     418                // Check for a callback and use it if specified
     419                if ( !empty($args['end-callback']) ) {
     420                        call_user_func( $args['end-callback'], $reply, $args, $depth );
     421                        return;
     422                }
     423
     424                // Style for div or list element
     425                if ( 'div' == $args['style'] )
     426                        echo "</div>\n";
     427                else
     428                        echo "</li>\n";
     429
     430        }
     431}
     432
    262433endif; // class_exists check
  • includes/common/template-tags.php

     
    15321532
    15331533                <input type="hidden" name="bbp_reply_title" id="bbp_reply_title" value="<?php bbp_reply_title(); ?>" />
    15341534                <input type="hidden" name="bbp_reply_id"    id="bbp_reply_id"    value="<?php bbp_reply_id(); ?>" />
     1535                <input type="hidden" name="bbp_reply_to"    id="bbp_reply_to"    value="<?php bbp_form_reply_to(); ?>" />
    15351536                <input type="hidden" name="action"          id="bbp_post_action" value="bbp-edit-reply" />
    15361537
    15371538                <?php if ( current_user_can( 'unfiltered_html' ) )
     
    15431544
    15441545                <input type="hidden" name="bbp_reply_title" id="bbp_reply_title" value="<?php printf( __( 'Reply To: %s', 'bbpress' ), bbp_get_topic_title() ); ?>" />
    15451546                <input type="hidden" name="bbp_topic_id"    id="bbp_topic_id"    value="<?php bbp_topic_id(); ?>" />
     1547                <input type="hidden" name="bbp_reply_to"    id="bbp_reply_to"    value="<?php bbp_form_reply_to(); ?>" />
    15461548                <input type="hidden" name="action"          id="bbp_post_action" value="bbp-new-reply" />
    15471549
    15481550                <?php if ( current_user_can( 'unfiltered_html' ) )
  • includes/core/actions.php

     
    174174add_action( 'bbp_forum_attributes_metabox_save', 'bbp_save_forum_extras', 2 );
    175175
    176176// New/Edit Reply
    177 add_action( 'bbp_new_reply',  'bbp_update_reply', 10, 6 );
    178 add_action( 'bbp_edit_reply', 'bbp_update_reply', 10, 6 );
     177add_action( 'bbp_new_reply',  'bbp_update_reply', 10, 7 );
     178add_action( 'bbp_edit_reply', 'bbp_update_reply', 10, 7 );
    179179
    180180// Before Delete/Trash/Untrash Reply
    181181add_action( 'wp_trash_post', 'bbp_trash_reply'   );
  • includes/core/options.php

     
    3434                '_bbp_enable_favorites'     => 1,                          // Favorites
    3535                '_bbp_enable_subscriptions' => 1,                          // Subscriptions
    3636                '_bbp_allow_topic_tags'     => 1,                          // Topic Tags
     37                '_bbp_thread_replies'       => 0,                          // Thread replies
     38                '_bbp_thread_replies_depth' => 2,                          // Thread replies depth
    3739                '_bbp_allow_anonymous'      => 0,                          // Allow anonymous posting
    3840                '_bbp_allow_global_access'  => 1,                          // Users from all sites can post
    3941                '_bbp_use_wp_editor'        => 1,                          // Use the WordPress editor if available
     
    224226}
    225227
    226228/**
     229 * Are replies threaded
     230 *
     231 * @since bbPress (r####)
     232 *
     233 * @param bool $default Optional. Default value true
     234 * @uses apply_filters() Calls 'bbp_thread_replies' with the option value and
     235 *                        the default value
     236 * @uses get_option() To get thread replies option
     237 * @return bool Are replies threaded?
     238 */
     239function bbp_thread_replies( $default = 0 ) {
     240        return (bool) apply_filters( 'bbp_thread_replies', (bool) get_option( '_bbp_thread_replies', $default ) );
     241}
     242
     243/**
     244 * Maximum reply thread depth
     245 *
     246 * @since bbPress (r####)
     247 *
     248 * @param int $default Thread replies depth
     249 * @uses apply_filters() Calls 'bbp_thread_replies_depth' with the option value and
     250 *                       the default depth
     251 * @uses get_option() To get the thread replies depth
     252 * @return int Thread replies depth
     253 */
     254function bbp_thread_replies_depth( $default = 2 ) {
     255        return (int) apply_filters( 'bbp_thread_replies_depth', (int) get_option( '_bbp_thread_replies_depth', $default ) );
     256}
     257
     258/**
    227259 * Are topic and reply revisions allowed
    228260 *
    229261 * @since bbPress (r3412)
  • includes/replies/functions.php

     
    9797 * @uses wp_set_post_terms() To set the topic tags
    9898 * @uses wp_insert_post() To insert the reply
    9999 * @uses do_action() Calls 'bbp_new_reply' with the reply id, topic id, forum
    100  *                    id, anonymous data and reply author
     100 *                    id, anonymous data, reply author, edit (false), and
     101 *                    the reply to id
    101102 * @uses bbp_get_reply_url() To get the paginated url to the reply
    102103 * @uses wp_safe_redirect() To redirect to the reply url
    103104 * @uses bbPress::errors::get_error_message() To get the {@link WP_Error} error
     
    116117        }
    117118
    118119        // Define local variable(s)
    119         $topic_id = $forum_id = $reply_author = $anonymous_data = 0;
     120        $topic_id = $forum_id = $reply_author = $anonymous_data = $reply_to = 0;
    120121        $reply_title = $reply_content = $terms = '';
    121122
    122123        /** Reply Author **********************************************************/
     
    165166                bbp_add_error( 'bbp_reply_forum_id', __( '<strong>ERROR</strong>: Forum ID is missing.', 'bbpress' ) );
    166167        }
    167168
     169        /** Reply To **************************************************************/
     170
     171        // Handle Reply To of the reply; $_REQUEST for non-JS submissions
     172        if ( isset( $_REQUEST['bbp_reply_to'] ) ) {
     173                $reply_to = (int) $_REQUEST['bbp_reply_to'];
     174        }
     175
     176        $reply_to = bbp_get_reply_id( $reply_to );
     177
    168178        /** Unfiltered HTML *******************************************************/
    169179
    170180        // Remove wp_filter_kses filters from title and content for capable users and if the nonce is verified
     
    326336
    327337                /** Update counts, etc... *********************************************/
    328338
    329                 do_action( 'bbp_new_reply', $reply_id, $topic_id, $forum_id, $anonymous_data, $reply_author );
     339                do_action( 'bbp_new_reply', $reply_id, $topic_id, $forum_id, $anonymous_data, $reply_author, false, $reply_to );
    330340
    331341                /** Additional Actions (After Save) ***********************************/
    332342
     
    383393 * @uses wp_update_post() To update the reply
    384394 * @uses bbp_get_reply_topic_id() To get the reply topic id
    385395 * @uses bbp_get_topic_forum_id() To get the topic forum id
     396 * @uses bbp_get_reply_to() To get the reply to id
    386397 * @uses do_action() Calls 'bbp_edit_reply' with the reply id, topic id, forum
    387  *                    id, anonymous data, reply author and bool true (for edit)
     398 *                    id, anonymous data, reply author, bool true (for edit),
     399 *                    and the reply to id
    388400 * @uses bbp_get_reply_url() To get the paginated url to the reply
    389401 * @uses wp_safe_redirect() To redirect to the reply url
    390402 * @uses bbPress::errors::get_error_message() To get the {@link WP_Error} error
     
    462474
    463475        $forum_id = bbp_get_topic_forum_id( $topic_id );
    464476
     477        /** Reply To **************************************************************/
     478
     479        $reply_to = bbp_get_reply_to( $reply_id );
     480
    465481        // Forum exists
    466482        if ( !empty( $forum_id ) && ( $forum_id !== bbp_get_reply_forum_id( $reply_id ) ) ) {
    467483
     
    611627        if ( !empty( $reply_id ) && !is_wp_error( $reply_id ) ) {
    612628
    613629                // Update counts, etc...
    614                 do_action( 'bbp_edit_reply', $reply_id, $topic_id, $forum_id, $anonymous_data, $reply_author , true /* Is edit */ );
     630                do_action( 'bbp_edit_reply', $reply_id, $topic_id, $forum_id, $anonymous_data, $reply_author , true /* Is edit */, $reply_to );
    615631
    616632                /** Additional Actions (After Save) ***********************************/
    617633
     
    653669 * @param bool|array $anonymous_data Optional logged-out user data.
    654670 * @param int $author_id Author id
    655671 * @param bool $is_edit Optional. Is the post being edited? Defaults to false.
     672 * @param int $reply_to Optional. Reply to id
    656673 * @uses bbp_get_reply_id() To get the reply id
    657674 * @uses bbp_get_topic_id() To get the topic id
    658675 * @uses bbp_get_forum_id() To get the forum id
     
    669686 * @uses bbp_add_user_subscription() To add the user's subscription
    670687 * @uses bbp_update_reply_forum_id() To update the reply forum id
    671688 * @uses bbp_update_reply_topic_id() To update the reply topic id
     689 * @uses bbp_update_reply_to() To update the reply to id
    672690 * @uses bbp_update_reply_walker() To update the reply's ancestors' counts
    673691 */
    674 function bbp_update_reply( $reply_id = 0, $topic_id = 0, $forum_id = 0, $anonymous_data = false, $author_id = 0, $is_edit = false ) {
     692function bbp_update_reply( $reply_id = 0, $topic_id = 0, $forum_id = 0, $anonymous_data = false, $author_id = 0, $is_edit = false, $reply_to = 0 ) {
    675693
    676694        // Validate the ID's passed from 'bbp_new_reply' action
    677         $reply_id = bbp_get_reply_id( $reply_id );
    678         $topic_id = bbp_get_topic_id( $topic_id );
    679         $forum_id = bbp_get_forum_id( $forum_id );
     695        $reply_id    = bbp_get_reply_id( $reply_id );
     696        $topic_id    = bbp_get_topic_id( $topic_id );
     697        $forum_id    = bbp_get_forum_id( $forum_id );
     698        $reply_to    = bbp_get_reply_id( $reply_to );
    680699
    681700        // Bail if there is no reply
    682701        if ( empty( $reply_id ) )
     
    740759        // Reply meta relating to reply position in tree
    741760        bbp_update_reply_forum_id( $reply_id, $forum_id );
    742761        bbp_update_reply_topic_id( $reply_id, $topic_id );
     762        bbp_update_reply_to(       $reply_id, $reply_to );
    743763
    744764        // Update associated topic values if this is a new reply
    745765        if ( empty( $is_edit ) ) {
     
    977997        return apply_filters( 'bbp_update_reply_topic_id', (int) $topic_id, $reply_id );
    978998}
    979999
     1000/*
     1001 * Update the reply's meta data with its reply to id
     1002 *
     1003 * @since bbPress (r####)
     1004 *
     1005 * @param int $reply_id Reply id to update
     1006 * @param int $reply_to Optional. Reply to id
     1007 * @uses bbp_get_reply_id() To get the reply id
     1008 * @uses update_post_meta() To update the reply to meta
     1009 * @uses apply_filters() Calls 'bbp_update_reply_to' with the reply id and
     1010 *                        and reply to id
     1011 * @return bool Reply's parent reply id
     1012 */
     1013function bbp_update_reply_to( $reply_id = 0, $reply_to = 0 ) {
     1014
     1015        // Validation
     1016        $reply_id = bbp_get_reply_id( $reply_id );
     1017        $reply_to = bbp_get_reply_id( $reply_to );
     1018
     1019        // Return if no reply
     1020        if ( empty( $reply_id ) )
     1021                return;
     1022
     1023        // Return if no reply to
     1024        if ( empty( $reply_to ) )
     1025                return;
     1026
     1027        // Set the reply to
     1028        update_post_meta( $reply_id, '_bbp_reply_to', $reply_to );
     1029
     1030        return (int) apply_filters( 'bbp_update_reply_to', (int) $reply_to, $reply_id );
     1031}
     1032
    9801033/**
    9811034 * Update the revision log of the reply
    9821035 *
     
    19992052
    20002053        return (int) $reply_position;
    20012054}
     2055
     2056/** Hierarchical Replies ******************************************************/
     2057
     2058/**
     2059 * List replies
     2060 *
     2061 * @since bbPress (r####)
     2062 */
     2063function bbp_list_replies( $args = array(), $replies = null ) {
     2064        global $reply_alt, $reply_depth, $reply_thread_alt;
     2065
     2066        // In reply loop
     2067        bbpress()->reply_query->in_the_loop = true;
     2068
     2069        // Initialize variables
     2070        $reply_alt = $reply_thread_alt = 0;
     2071        $reply_depth = 1;
     2072
     2073        $defaults = array(
     2074                'walker'       => null,
     2075                'max_depth'    => bbp_thread_replies_depth(),
     2076                'style'        => 'ul',
     2077                'callback'     => null,
     2078                'end_callback' => null,
     2079                'page'         => bbp_get_paged(),
     2080                'per_page'     => bbp_get_replies_per_page()
     2081        );
     2082
     2083        $r = wp_parse_args( $args, $defaults );
     2084
     2085        // Get replies to loop through in $_replies
     2086        if ( null !== $replies ) {
     2087                $replies = (array) $replies;
     2088                if ( empty( $replies ) )
     2089                        return;
     2090                $_replies = $replies;
     2091        } else {
     2092                if ( empty( bbpress()->reply_query->posts ) )
     2093                        return;
     2094                $_replies = bbpress()->reply_query->posts;
     2095        }
     2096
     2097        if ( empty( $walker ) )
     2098                $walker = new Walker_Reply;
     2099
     2100        $walker->paged_walk( $_replies, $r['max_depth'], $r['page'], $r['per_page'], $r );
     2101        bbpress()->max_num_pages = $walker->max_pages;
     2102
     2103        bbpress()->reply_query->in_the_loop = false;
     2104}
     2105
     2106/**
     2107 * Update the hierarchical position of the reply.
     2108 *
     2109 * The hierarchical reply position is stored as _bbp_reply_position in the postmeta
     2110 * table. This is done to prevent repeated complex queries to sort out reply
     2111 * position.
     2112 *
     2113 * @since bbPress (r####)
     2114 *
     2115 * @param int $reply_id The reply id
     2116 * @param int $reply_hierarchical_position Optional. The reply position
     2117 * @return int The reply's hierarchical position (technically, the position of the reply's
     2118 *              ancestor in the uppermost level of the hierarchy).
     2119 */
     2120function bbp_update_reply_hierarchical_position( $reply_id = 0, $reply_hierarchical_position = 0 ) {
     2121
     2122        // Bail if reply_id is empty
     2123        $reply_id = bbp_get_reply_id( $reply_id );
     2124        if ( empty( $reply_id ) )
     2125                return false;
     2126
     2127        // If no position was passed, get it from the db and update the menu_order
     2128        if ( empty( $reply_hierarchical_position ) ) {
     2129                $reply_hierarchical_position = bbp_get_reply_hierarchical_position_raw( $reply_id, bbp_get_reply_topic_id( $reply_id ) );
     2130        }
     2131
     2132        // Update the reply's meta _bbp_reply_position with the reply position
     2133        update_post_meta( $reply_id, '_bbp_reply_position', $reply_hierarchical_position );
     2134
     2135        return (int) $reply_hierarchical_position;
     2136}
     2137
     2138/**
     2139 * Get the hierarchical position of a reply by querying the DB directly for the
     2140 * replies of a given topic. This function uses the time of the ancestor reply, as
     2141 * that is the defining branch of the hierarchy of replies.
     2142 *
     2143 * @since bbPress (r####)
     2144 *
     2145 * @param int $reply_id The reply id
     2146 * @param int $topic_id
     2147 */
     2148function bbp_get_reply_hierarchical_position_raw( $reply_id = 0, $topic_id = 0 ) {
     2149
     2150        // Get required data
     2151        $reply_id                    = bbp_get_reply_id( $reply_id );
     2152        $topic_id                    = !empty( $topic_id ) ? bbp_get_topic_id( $topic_id ) : bbp_get_reply_topic_id( $reply_id );
     2153        $reply_hierarchical_position = 0;
     2154
     2155        // If reply is actually the first post in a topic, return 0
     2156        if ( $reply_id != $topic_id ) {
     2157
     2158                // Make sure the topic has replies before running another query
     2159                $reply_count = bbp_get_topic_reply_count( $topic_id, false );
     2160                if ( !empty( $reply_count ) ) {
     2161                        global $wpdb;
     2162
     2163                        // Use ancestor for date calculations
     2164                        $ancestor_id   = bbp_get_reply_ancestor_id( $reply_id );
     2165                        $post_date_gmt = get_post_time( 'Y-m-d H:i:s', true, $ancestor_id );
     2166
     2167                        // Post stati
     2168                        $post_stati = array(
     2169                                bbp_get_public_status_id()
     2170                        );
     2171
     2172                        // Clean up for query
     2173                        $post_status_in_array = array();
     2174                        foreach( $post_stati as $post_status )
     2175                                $post_status_in_array[] = $wpdb->prepare( "%s", $post_status );
     2176
     2177                        // Join post statuses together
     2178                        $post_status_in_array = implode( ',', $post_status_in_array );
     2179
     2180                        // Direct SQL query for post meta values
     2181                        $sql = $wpdb->prepare( "
     2182                                SELECT COUNT(*) FROM {$wpdb->posts} p
     2183                                WHERE p.post_parent = %d
     2184                                        AND p.post_type = %s
     2185                                        AND p.post_date_gmt < %s
     2186                                        AND p.post_status IN ( {$post_status_in_array} )
     2187                                        AND (
     2188                                                NOT EXISTS (
     2189                                                        SELECT pm.* FROM {$wpdb->postmeta} pm WHERE p.ID = pm.post_id AND pm.meta_key = '_bbp_reply_to'
     2190                                                ) OR EXISTS (
     2191                                                        SELECT pm.* FROM {$wpdb->postmeta} pm WHERE p.ID = pm.post_id AND pm.meta_key = '_bbp_reply_to' AND pm.meta_value = 0
     2192                                                ) OR EXISTS (
     2193                                                        SELECT pm.* FROM {$wpdb->postmeta} pm WHERE p.ID = pm.post_id AND pm.meta_key = '_bbp_reply_to' AND pm.meta_value = %d
     2194                                ) ) ORDER BY p.post_date_gmt ASC",
     2195                                $topic_id, bbp_get_reply_post_type(), $post_date_gmt, $topic_id
     2196                        );
     2197                        $reply_hierarchical_position = (int) $wpdb->get_var( $sql );
     2198
     2199                        // Bump the position to compensate for the lead topic post
     2200                        $reply_hierarchical_position++;
     2201                }
     2202        }
     2203
     2204        return (int) $reply_hierarchical_position;
     2205}
  • includes/replies/template-tags.php

     
    8181                'paged'          => bbp_get_paged(),            // On this page
    8282                'orderby'        => 'date',                     // Sorted by date
    8383                'order'          => 'ASC',                      // Oldest to newest
     84                'hierarchical'   => false,                      // Hierarchical replies
    8485                's'              => $default_reply_search,      // Maybe search
    8586        );
    8687
     
    113114        // Parse arguments against default values
    114115        $r = bbp_parse_args( $args, $default, 'has_replies' );
    115116
     117        // Set posts_per_page value if replies are threaded
     118        $replies_per_page = $r['posts_per_page'];
     119        if ( $r['hierarchical'] ) {
     120                $r['posts_per_page'] = -1;
     121        }
     122
    116123        // Get bbPress
    117124        $bbp = bbpress();
    118125
    119126        // Call the query
    120127        $bbp->reply_query = new WP_Query( $r );
    121        
     128
    122129        // Add pagination values to query object
    123         $bbp->reply_query->posts_per_page = $r['posts_per_page'];
     130        $bbp->reply_query->posts_per_page = $replies_per_page;
    124131        $bbp->reply_query->paged          = $r['paged'];
    125132
    126133        // Never home, regardless of what parse_query says
     
    131138                $bbp->reply_query->is_single = true;
    132139        }
    133140
     141        // Only add reply to if query returned results
     142        if ( (int) $bbp->reply_query->found_posts ) {
     143
     144                // Get reply to for each reply
     145                foreach ( $bbp->reply_query->posts as &$post ) {
     146
     147                        // Check for reply post type
     148                        if ( $post->post_type == bbp_get_reply_post_type() ) {
     149                                $reply_to = bbp_get_reply_to( $post->ID );
     150
     151                                // Make sure it's a reply to a reply
     152                                if ( empty( $reply_to ) || ( bbp_get_reply_topic_id( $post->ID ) == $reply_to ) )
     153                                        $reply_to = 0;
     154                                $post->reply_to = $reply_to;
     155                        }
     156                }
     157        }
     158
    134159        // Only add pagination if query returned results
    135160        if ( (int) $bbp->reply_query->found_posts && (int) $bbp->reply_query->posts_per_page ) {
    136161
     
    157182                        $base = add_query_arg( 'paged', '%#%' );
    158183                }
    159184
     185                // Figure out total pages
     186                if ( $r['hierarchical'] ) {
     187                        $walker      = new Walker_Reply;
     188                        $total_pages = ceil( (int) $walker->get_number_of_root_elements( $bbp->reply_query->posts ) / (int) $replies_per_page );
     189                } else {
     190                        $total_pages = ceil( (int) $bbp->reply_query->found_posts / (int) $replies_per_page );
     191                }
     192
    160193                // Add pagination to query object
    161194                $bbp->reply_query->pagination_links = paginate_links(
    162195                        apply_filters( 'bbp_replies_pagination', array(
    163196                                'base'      => $base,
    164197                                'format'    => '',
    165                                 'total'     => ceil( (int) $bbp->reply_query->found_posts / (int) $r['posts_per_page'] ),
     198                                'total'     => $total_pages,
    166199                                'current'   => (int) $bbp->reply_query->paged,
    167200                                'prev_text' => is_rtl() ? '&rarr;' : '&larr;',
    168201                                'next_text' => is_rtl() ? '&larr;' : '&rarr;',
     
    382415                // Set needed variables
    383416                $reply_id   = bbp_get_reply_id      ( $reply_id );
    384417                $topic_id   = bbp_get_reply_topic_id( $reply_id );
    385                 $reply_page = ceil( (int) bbp_get_reply_position( $reply_id, $topic_id ) / (int) bbp_get_replies_per_page() );
     418
     419                // Hierarchical reply page
     420                if ( bbp_thread_replies() ) {
     421                        $reply_page = ceil( (int) bbp_get_reply_hierarchical_position( $reply_id, $topic_id ) / (int) bbp_get_replies_per_page() );
     422
     423                // Standard reply page
     424                } else {
     425                        $reply_page = ceil( (int) bbp_get_reply_position( $reply_id, $topic_id ) / (int) bbp_get_replies_per_page() );
     426                }
     427
    386428                $reply_hash = '#post-' . $reply_id;
    387429                $topic_link = bbp_get_topic_permalink( $topic_id, $redirect_to );
    388430                $topic_url  = remove_query_arg( 'view', $topic_link );
     
    13451387        }
    13461388
    13471389/**
     1390 * Output the reply's ancestor reply id
     1391 *
     1392 * @since bbPress (r####)
     1393 *
     1394 * @param int $reply_id Optional. Reply id
     1395 * @uses bbp_get_reply_ancestor_id() To get the reply's ancestor id
     1396 */
     1397function bbp_reply_ancestor_id( $reply_id = 0 ) {
     1398        echo bbp_get_reply_ancestor_id( $reply_id );
     1399}
     1400        /**
     1401         * Return the reply's ancestor reply id
     1402         *
     1403         * @since bbPress (r####)
     1404         *
     1405         * @param in $reply_id Reply id
     1406         * @uses bbp_get_reply_id() To get the reply id
     1407         */
     1408        function bbp_get_reply_ancestor_id( $reply_id = 0 ) {
     1409
     1410                // Validation
     1411                $reply_id = bbp_get_reply_id( $reply_id );
     1412                if ( empty( $reply_id ) )
     1413                        return false;
     1414
     1415                // Find highest reply ancestor
     1416                $ancestor_id = $reply_id;
     1417                while ( $parent_id = bbp_get_reply_to( $ancestor_id ) ) {
     1418                        if ( empty( $parent_id ) || $parent_id == $ancestor_id || $parent_id == bbp_get_reply_topic_id( $reply_id ) || $parent_id == $reply_id )
     1419                                break;
     1420                        $ancestor_id = $parent_id;
     1421                }
     1422
     1423                return (int) $ancestor_id;
     1424        }
     1425
     1426/**
     1427 * Output the reply to id of a reply
     1428 *
     1429 * @since bbPress (r####)
     1430 *
     1431 * @param int $reply_id Optional. Reply id
     1432 * @uses bbp_get_reply_to() To get the reply to id
     1433 */
     1434function bbp_reply_to( $reply_id = 0 ) {
     1435        echo bbp_get_reply_to( $reply_id );
     1436}
     1437        /**
     1438         * Return the reply to id of a reply
     1439         *
     1440         * @since bbPress (r####)
     1441         *
     1442         * @param int $reply_id Optional. Reply id
     1443         * @uses bbp_get_reply_id() To get the reply id
     1444         * @uses get_post_meta() To get the reply to id
     1445         * @uses apply_filters() Calls 'bbp_get_reply_to' with the reply to id and
     1446         *                        reply id
     1447         * @return int Reply's reply to id
     1448         */
     1449        function bbp_get_reply_to( $reply_id = 0 ) {
     1450
     1451                // Assume there is no reply_to set
     1452                $reply_to = 0;
     1453
     1454                // Check that reply_id is valid
     1455                if ( $reply_id = bbp_get_reply_id( $reply_id ) )
     1456
     1457                        // Get reply_to value
     1458                        $reply_to = (int) get_post_meta( $reply_id, '_bbp_reply_to', true );
     1459
     1460                return (int) apply_filters( 'bbp_get_reply_to', $reply_to, $reply_id );
     1461        }
     1462
     1463/**
     1464 * Output the link for the reply to
     1465 *
     1466 * @since bbPress (r####)
     1467 *
     1468 * @param array $args
     1469 * @param int $reply
     1470 * @uses bbp_get_reply_to_link() To get the reply to link
     1471 */
     1472function bbp_reply_to_link( $args = array(), $reply = 0 ) {
     1473        echo bbp_get_reply_to_link( $args, $reply );
     1474}
     1475
     1476        /**
     1477         * Return the link for a reply to a reply
     1478         *
     1479         * @since bbPress (r####)
     1480         *
     1481         * @param array $args Arguments
     1482         * @param int $reply_id Reply id
     1483         * @uses bbp_current_user_can_access_create_reply_form() To check permissions
     1484         * @uses bbp_get_reply_id() To validate the reply id
     1485         * @uses bbp_get_reply() To get the reply
     1486         * @uses apply_filters() Calls 'bbp_get_reply_to_link' with the formatted link,
     1487         *                        the arguments array, and the reply
     1488         * @return string Link for a reply to a reply
     1489         */
     1490        function bbp_get_reply_to_link( $args = array(), $reply_id = 0 ) {
     1491
     1492                // Permissions check
     1493                if ( !bbp_current_user_can_access_create_reply_form() )
     1494                        return;
     1495
     1496                // Validate
     1497                $reply_id = bbp_get_reply_id( $reply_id );
     1498                if ( empty( $reply_id ) )
     1499                        $reply_id = bbp_get_reply_id();
     1500
     1501                if ( empty( $reply_id ) )
     1502                        return;
     1503
     1504                // Set defaults
     1505                $reply    = bbp_get_reply( $reply_id );
     1506                $defaults = array(
     1507                        'add_below'  => 'reply',
     1508                        'respond_id' => 'new-reply-' . bbp_get_topic_id(),
     1509                        'reply_text' => __( 'Reply to this', 'bbpress' ),
     1510                        'depth' => 0,
     1511                        'before' => '',
     1512                        'after' => ''
     1513                );
     1514
     1515                $r = wp_parse_args( $args, $defaults );
     1516
     1517                // Don't display for deeply nested replies
     1518                if ( 0 == $r['depth'] || $r['max_depth'] <= $r['depth'] )
     1519                        return;
     1520
     1521                // Non-JS compat
     1522                remove_query_arg( array( 'bbp_reply_to' ) );
     1523
     1524                // Assemble
     1525                $link = "<a class='reply-to-link' href='" . esc_url( add_query_arg( array( 'bbp_reply_to' => $reply->ID ) ) ) .
     1526                        "#" . $r['respond_id'] . "' onclick='return addReply.moveForm(\"" . $r['add_below'] . '-' . $reply->ID .
     1527                        '","' . $reply->ID . '","' . $r['respond_id'] . '","' . $reply->post_parent .  '")\'>' . $r['reply_text'] . '</a>';
     1528
     1529                return apply_filters( 'bpp_get_reply_to_link', $link, $args, $reply );
     1530        }
     1531
     1532/**
     1533 * Output the reply to a reply cancellation link
     1534 *
     1535 * @since bbPress (r####)
     1536 *
     1537 * @uses bbp_get_cancel_reply_to_link() To get the reply cancellation link
     1538 */
     1539function bbp_cancel_reply_to_link( $text = '' ) {
     1540        echo bbp_get_cancel_reply_to_link( $text );
     1541}
     1542        /**
     1543         * Return the cancellation link for a reply to a reply
     1544         *
     1545         * @since bbPress (r####)
     1546         *
     1547         * @param string $text The cancel text
     1548         * @uses apply_filters() Calls 'bbp_get_cancel_reply_to_link' with the cancellation
     1549         *                        link and the cancel text
     1550         * @return string The cancellation link
     1551         */
     1552        function bbp_get_cancel_reply_to_link( $text = '' ) {
     1553
     1554                // Set default text
     1555                if ( empty( $text ) )
     1556                        $text = __( 'Click here to cancel reply.', 'bbpress' );
     1557
     1558                // Set visibility
     1559                $style = isset( $_GET['bbp_reply_to'] ) ? '' : ' style="display:none;"';
     1560                $link  = esc_html( remove_query_arg( array( 'bbp_reply_to' ) ) ) . '#respond';
     1561
     1562                return apply_filters( 'bbp_get_cancel_reply_to_link', '<a rel="nofollow" id="cancel-reply-to-link" href="' . $link . '"' . $style . '>' . $text . '</a>', $link, $text );
     1563        }
     1564
     1565/**
    13481566 * Output the numeric position of a reply within a topic
    13491567 *
    13501568 * @since bbPress (r2984)
     
    14071625                return (int) apply_filters( 'bbp_get_reply_position', $reply_position, $reply_id, $topic_id );
    14081626        }
    14091627
     1628
     1629        /**
     1630         * Return the numeric position of a threaded reply within a topic. Technically,
     1631         * get the position of the reply's ancestor in the context of other top-level
     1632         * replies to the topic.
     1633         *
     1634         * @since bbPress (r2984)
     1635         *
     1636         * @param int $reply_id Optional. Reply id
     1637         * @param int $topic_id Optional. Topic id
     1638         * @uses bbp_get_reply_id() To get the reply id
     1639         * @uses bbp_get_reply_topic_id() Get the topic id of the reply id
     1640         * @uses bbp_get_reply_hierarchical_position_raw() To get calculate the reply position
     1641         * @uses bbp_update_reply_hierarchical_position() To update the reply position
     1642         * @uses bbp_show_lead_topic() Bump the count if lead topic is included
     1643         * @uses apply_filters() Calls 'bbp_get_reply_hierarchical_position' with the reply
     1644         *                        position, reply id and topic id
     1645         * @return int Reply hierarchical position
     1646         */
     1647        function bbp_get_reply_hierarchical_position( $reply_id = 0, $topic_id = 0 ) {
     1648
     1649                // Validate
     1650                $reply_id                    = bbp_get_reply_id( $reply_id );
     1651                $reply_hierarchical_position = get_post_meta( '_bbp_reply_position', $reply_id );
     1652
     1653                // Calculate and save the position
     1654                if ( empty( $reply_hierarchical_position ) ) {
     1655                        $topic_id = !empty( $topic_id ) ? bbp_get_topic_id( $topic_id ) : bbp_get_reply_topic_id( $reply_id );
     1656
     1657                        // Post is not the topic
     1658                        if ( $reply_id != $topic_id ) {
     1659                                $reply_hierarchical_position = bbp_get_reply_hierarchical_position_raw( $reply_id, $topic_id );
     1660
     1661                                // Update the reply position in the posts table to avoid expensive
     1662                                // queries.
     1663                                if ( !empty( $reply_hierarchical_position ) ) {
     1664                                        bbp_update_reply_hierarchical_position( $reply_id, $reply_hierarchical_position );
     1665                                }
     1666
     1667                        // Topic's position is always 0
     1668                        } else {
     1669                                $reply_hierarchical_position = 0;
     1670                        }
     1671                }
     1672
     1673                // Bump the position by one if the lead topic is in the replies loop
     1674                if ( ! bbp_show_lead_topic() )
     1675                        $reply_hierarchical_position++;
     1676
     1677                return (int) apply_filters( 'bbp_get_reply_hierarchical_position', $reply_hierarchical_position, $reply_id, $topic_id );
     1678        }
     1679
    14101680/** Reply Admin Links *********************************************************/
    14111681
    14121682/**
     
    20742344        }
    20752345
    20762346/**
     2347 * Output the value of the reply to field
     2348 *
     2349 * @since bbPress (r####)
     2350 *
     2351 * @uses bbp_get_form_reply_to() To get value of the reply to field
     2352 */
     2353function bbp_form_reply_to() {
     2354        echo bbp_get_form_reply_to();
     2355}
     2356
     2357        /**
     2358         * Return the value of reply to field
     2359         *
     2360         * @since bbPress (r####)
     2361         *
     2362         * @uses bbp_get_reply_id() To validate the reply to
     2363         * @uses apply_filters() Calls 'bbp_get_form_reply_to' with the reply to
     2364         * @return string Value of reply to field
     2365         */
     2366        function bbp_get_form_reply_to() {
     2367
     2368                // Set initial value
     2369                $reply_to = 0;
     2370
     2371                // Get $_REQUEST data
     2372                if ( isset( $_REQUEST['bbp_reply_to'] ) )
     2373                        $reply_to = (int) $_REQUEST['bbp_reply_to'];
     2374
     2375                // If empty, get from meta
     2376                if ( empty( $reply_to ) )
     2377                        $reply_to = bbp_get_reply_to();
     2378
     2379                // Validate
     2380                $reply_to = bbp_get_reply_id( $reply_to );
     2381
     2382                return (int) apply_filters( 'bbp_get_form_reply_to', $reply_to );
     2383        }
     2384
     2385/**
    20772386 * Output checked value of reply log edit field
    20782387 *
    20792388 * @since bbPress (r31301)
  • templates/default/bbpress/content-single-topic.php

     
    3131
    3232                <?php endif; ?>
    3333
    34                 <?php if ( bbp_has_replies() ) : ?>
     34                <?php if ( bbp_has_replies( array( 'hierarchical' => bbp_thread_replies() ) ) ) : ?>
    3535
    3636                        <?php bbp_get_template_part( 'pagination', 'replies' ); ?>
    3737
  • templates/default/bbpress/form-reply.php

     
    2828                        <fieldset class="bbp-form">
    2929                                <legend><?php printf( __( 'Reply To: %s', 'bbpress' ), bbp_get_topic_title() ); ?></legend>
    3030
     31                                <?php if ( bbp_thread_replies() && !bbp_is_reply_edit() ) : ?>
     32
     33                                        <h3><small><?php bbp_cancel_reply_to_link(); ?></small></h3>
     34
     35                                <?php endif; ?>
     36
    3137                                <?php do_action( 'bbp_theme_before_reply_form_notices' ); ?>
    3238
    3339                                <?php if ( !bbp_is_topic_open() && !bbp_is_reply_edit() ) : ?>
  • templates/default/bbpress/loop-replies.php

     
    3939
    4040        <li class="bbp-body">
    4141
    42                 <?php while ( bbp_replies() ) : bbp_the_reply(); ?>
     42                <?php if ( bbp_thread_replies() ) : ?>
    4343
    44                         <?php bbp_get_template_part( 'loop', 'single-reply' ); ?>
     44                        <?php bbp_list_replies(); ?>
    4545
    46                 <?php endwhile; ?>
     46                <?php else : ?>
    4747
     48                        <?php while ( bbp_replies() ) : bbp_the_reply(); ?>
     49
     50                                <?php bbp_get_template_part( 'loop', 'single-reply' ); ?>
     51
     52                        <?php endwhile; ?>
     53
     54                <?php endif; ?>
     55
    4856        </li><!-- .bbp-body -->
    4957
    5058        <li class="bbp-footer">
  • templates/default/bbpress-functions.php

     
    179179                        wp_enqueue_script( 'jquery' );
    180180                }
    181181
    182                 // Topic favorite/subscribe
     182                // Topic-specific scripts
    183183                if ( bbp_is_single_topic() ) {
     184
     185                        // Topic favorite/unsubscribe
    184186                        wp_enqueue_script( 'bbpress-topic', $this->url . 'js/topic.js', array( 'jquery' ), $this->version );
     187
     188                        // Hierarchical replies
     189                        if ( bbp_thread_replies() )
     190                                wp_enqueue_script( 'bbpress-reply', $this->url . 'js/reply.js', array(), $this->version );
    185191                }
    186192
    187193                // User Profile edit
  • templates/default/css/bbpress.css

     
    6060        padding: 0;
    6161}
    6262
     63#bbpress-forums ul.children {
     64        margin-left: 2em;
     65}
     66
    6367#bbpress-forums li {
    6468        margin: 0;
    6569        list-style: none;
  • templates/default/js/reply.js

     
     1addReply = {
     2        moveForm : function(replyId, parentId, respondId, postId) {
     3                var t = this, div, reply = t.I(replyId), respond = t.I(respondId), cancel = t.I('cancel-reply-to-link'), parent = t.I('bbp_reply_to'), post = t.I('bbp_topic_id');
     4
     5                if ( ! reply || ! respond || ! cancel || ! parent )
     6                        return;
     7
     8                t.respondId = respondId;
     9                postId = postId || false;
     10
     11                if ( ! t.I('bbp-temp-form-div') ) {
     12                        div = document.createElement('div');
     13                        div.id = 'bbp-temp-form-div';
     14                        div.style.display = 'none';
     15                        respond.parentNode.insertBefore(div, respond);
     16                }
     17
     18                reply.parentNode.insertBefore(respond, reply.nextSibling);
     19                if ( post && postId )
     20                        post.value = postId;
     21                parent.value = parentId;
     22                cancel.style.display = '';
     23
     24                cancel.onclick = function() {
     25                        var t = addReply, temp = t.I('bbp-temp-form-div'), respond = t.I(t.respondId);
     26
     27                        if ( ! temp || ! respond )
     28                                return;
     29
     30                        t.I('bbp_reply_to').value = '0';
     31                        temp.parentNode.insertBefore(respond, temp);
     32                        temp.parentNode.removeChild(temp);
     33                        this.style.display = 'none';
     34                        this.onclick = null;
     35                        return false;
     36                }
     37
     38                try { t.I('bbp_reply_content').focus(); }
     39                catch(e) {}
     40
     41                return false;
     42        },
     43
     44        I : function(e) {
     45                return document.getElementById(e);
     46        }
     47}