Skip to:
Content

bbPress.org

Ticket #2731: 2731.8.diff

File 2731.8.diff, 17.4 KB (added by tharsheblows, 6 years ago)

with non-js fallback

  • src/includes/admin/admin.php

     
    588588                                        break;
    589589                        }
    590590                }
     591
     592                if( 'tools_page_bbp-repair' === get_current_screen()->id ) {
     593                        wp_enqueue_script( 'bbp-tools-js', $this->js_url . 'tools.js', array( 'jquery' ), $version );
     594                }
    591595        }
    592596
    593597        /**
  • src/includes/admin/js/tools.js

     
     1jQuery( document ).ready( function( ) {
     2
     3        // add in something here to check if the recalculate menu order box is ticked.
     4        // If it is, it is the *only* one that can be ticked, maybe grey out the others?
     5
     6    var input = {};
     7
     8    // add run_sync to link
     9    var sync_reply_positions =  jQuery( '#the-list a#bbp-sync-all-reply-positions' );
     10    jQuery( sync_reply_positions ).addClass( 'run_sync' );
     11
     12    // (don't) disable checkbox for testing purposes
     13   // jQuery( '#the-list a#bbp-sync-all-reply-positions' ).closest( '#bbp-repair-tools' ).find( 'input[type=checkbox]' ).attr( 'disabled', 'disabled' );
     14
     15    function bbp_repair_reply_menu_order_call( nonce, iteration, continue_menu_order_zero  ) {
     16
     17        if( jQuery( '#the-list a#bbp-sync-all-reply-positions.killed' ).length > 0 ){
     18            jQuery( '#the-list a#bbp-sync-all-reply-positions.killed' ).removeClass( 'killed' );
     19            console.log( 'Process killed.' );
     20            return;
     21        }
     22
     23        input = {
     24            'action'    : 'bbp_admin_repair_reply_menu_order',
     25            'nonce'     : nonce,
     26            'iteration' : iteration,
     27            'continue_menu_order_zero' : continue_menu_order_zero
     28        };
     29
     30        var bbp_repair_ajax = jQuery.ajax({
     31                    type: 'POST',
     32                    url : ajaxurl, // this is already there, let's use it
     33                    data : input,
     34                    dataType : 'json'
     35               });
     36
     37        jQuery.when( bbp_repair_ajax ).then( function( data ){
     38
     39            if (data.result === 'keep-going' ) {
     40
     41                input = {};
     42
     43                if( jQuery( '#the-list a#bbp-sync-all-reply-positions.killed' ).length > 0 ){
     44                    jQuery( '#the-list a#bbp-sync-all-reply-positions.killed' ).addClass( 'run_sync' );
     45                }
     46
     47                console.log( data.notice );
     48                return bbp_repair_reply_menu_order_call( data.passed_nonce, data.iteration, data.continue_menu_order_zero );
     49            }
     50            else if (data.result === 'all-done' ){
     51                console.log( data.notice );
     52                jQuery( '#the-list a#bbp-sync-all-reply-positions' ).removeClass( 'killed' ).removeClass( 'kill' ).html( 'Finished. Run again' );
     53            }
     54            else if (data.result === 'nonce-failed' ){
     55                console.log( data.notice );
     56            }
     57            else{
     58                console.log( 'boo' );
     59            }
     60        });
     61    }
     62
     63    jQuery( '#the-list' ).on( 'click', 'a#bbp-sync-all-reply-positions.run_sync', function(e){
     64
     65        e.preventDefault();
     66
     67        // set the initial values
     68        var nonce = jQuery( this ).attr( 'data-nonce' );
     69        var iteration;
     70        var continue_menu_order_zero = true;
     71
     72        // make the run link a kill link
     73        jQuery( this ).removeClass( 'run_sync' ).addClass( 'kill' ).html( '<strong>Kill process (will take a few seconds)</strong>' );
     74        jQuery( this ).closest( '.row-actions' ).css({ 'visibility' : 'visible' });
     75
     76        // and now call the function to start the repair
     77        bbp_repair_reply_menu_order_call( nonce, iteration, continue_menu_order_zero );
     78
     79    });
     80
     81    jQuery( '#the-list' ).on( 'click', 'a#bbp-sync-all-reply-positions.kill', function(e){
     82        e.preventDefault();
     83
     84        // don't kill anymore, we can run again
     85        jQuery( this ).removeClass( 'kill' ).addClass( 'killed').html( 'Process killed. Click to restart.');
     86    });
     87
     88
     89});
  • src/includes/admin/tools.php

    Property changes on: src/includes/admin/js/tools.js
    ___________________________________________________________________
    Added: svn:eol-style
    ## -0,0 +1 ##
    +native
    \ No newline at end of property
     
    1010// Exit if accessed directly
    1111defined( 'ABSPATH' ) || exit;
    1212
     13// The reply menu order repair tool uses ajax
     14add_action( 'wp_ajax_bbp_admin_repair_reply_menu_order', 'bbp_admin_repair_reply_menu_order_callback' );
     15
    1316/** Repair ********************************************************************/
    1417
    1518/**
     
    9396                                                                        <strong><?php echo esc_html( $item['description'] ); ?></strong>
    9497                                                                        <div class="row-actions hide-if-no-js">
    9598                                                                                <span class="run">
    96                                                                                         <a href="<?php bbp_admin_repair_tool_run_url( $item['id'] ); ?>" aria-label="<?php printf( esc_html__( 'Run %s', 'bbpress' ), $item['description'] ); ?>" id="<?php echo esc_attr( $item['id'] ); ?>" ><?php esc_html_e( 'Run', 'bbpress' ); ?></a>
     99                                                                                        <a href="<?php bbp_admin_repair_tool_run_url( $item['id'] ); ?>" aria-label="<?php printf( esc_html__( 'Run %s', 'bbpress' ), $item['description'] ); ?>" id="<?php echo esc_attr( $item['id'] ); ?>" data-nonce="<?php echo wp_create_nonce( esc_attr( $item['id'] ) ); ?>" ><?php esc_html_e( 'Run', 'bbpress' ); ?></a>
    97100                                                                                </span>
    98101                                                                        </div>
    99102                                                                        <button type="button" class="toggle-row">
     
    20722075 * @uses bbp_update_reply_position() To update the reply position
    20732076 * @return array An array of the status code and the message
    20742077 */
    2075 function bbp_admin_repair_reply_menu_order() {
     2078function bbp_admin_repair_reply_menu_order_callback() {
    20762079
     2080        // nonceify this
     2081        $nonce = ( !empty( $_POST['nonce'] ) ) ? $_POST['nonce'] : '';
     2082        $iteration = ( !empty( $_POST['iteration'] ) ) ? intval( $_POST['iteration'] ) : 0;
     2083
     2084        $nonce_action = ( $iteration === 0 ) ? 'bbp-sync-all-reply-positions' : 'bbp-sync-all-reply-positions' . $iteration;
     2085
     2086        if( empty( wp_verify_nonce( $nonce, $nonce_action ) ) ){
     2087                $data = array('notice' => 'Nonce failed.' . $create_nonce . $nonce, 'continue_menu_order_zero' => '', 'result' => 'nonce-failed');
     2088                echo json_encode( $data );
     2089                wp_die();
     2090
     2091        }
     2092
     2093        $continue_menu_order_zero = ( !empty( $_POST['continue_menu_order_zero'] ) ) ?  $_POST['continue_menu_order_zero'] : false;
     2094
    20772095        // Define variables
    20782096        $bbp_db    = bbp_db();
    20792097        $statement = __( 'Recalculating reply menu order &hellip; %s', 'bbpress' );
     
    20872105        // Post type
    20882106        $rpt = bbp_get_reply_post_type();
    20892107
    2090         // Get an array of reply id's to update the menu oder for each reply
    2091         $replies = $bbp_db->get_results( "SELECT `a`.`ID` FROM `{$bbp_db->posts}` AS `a`
    2092                                                                                 INNER JOIN (
    2093                                                                                         SELECT `menu_order`, `post_parent`
    2094                                                                                         FROM `{$bbp_db->posts}`
    2095                                                                                         GROUP BY `menu_order`, `post_parent`
    2096                                                                                         HAVING COUNT( * ) >1
    2097                                                                                 )`b`
    2098                                                                                 ON `a`.`menu_order` = `b`.`menu_order`
    2099                                                                                 AND `a`.`post_parent` = `b`.`post_parent`
    2100                                                                                 WHERE `post_type` = '{$rpt}';", OBJECT_K );
     2108        // Pending status
     2109        $pst = bbp_get_pending_status_id();
     2110        // Public status
     2111        $pub = bbp_get_public_status_id();
    21012112
     2113        $offset = 0;
     2114        $limit = 300;
     2115        $replies_count = 0;
     2116
     2117        // ready steady GO
     2118        $startTime = microtime(true);
     2119
     2120        // First look through the menu_order 0 replies. Are there any published replies with menu_order 0?
     2121        // But don't do this if you don't need to.
     2122
     2123        $menu_order_zero_published = ( !$continue_menu_order_zero ) ? array() :
     2124                $bbp_db->get_results(
     2125                        "SELECT `ID`
     2126                                FROM `{$bbp_db->posts}`
     2127                                WHERE `post_type` = '{$rpt}' AND `post_status` = '{$pub}' AND `menu_order` = 0
     2128                         LIMIT {$limit}", OBJECT_K );
     2129
     2130        $menu_order_zero_count = count( $menu_order_zero_published );
     2131
     2132        // only get the array with duplicate menu orders if we're going to use it.
     2133        if( $menu_order_zero_count < $limit ){
     2134
     2135                $limit = $limit - $menu_order_zero_count;
     2136
     2137                // Get an array of reply ids to update the menu oder for each reply
     2138                $menu_order_repeated = $bbp_db->get_results(
     2139                        "SELECT `a`.`ID` FROM `{$bbp_db->posts}` AS `a`
     2140                                INNER JOIN (
     2141                                        SELECT `menu_order`, `post_parent`
     2142                                        FROM `{$bbp_db->posts}` WHERE `post_type` = '{$rpt}' AND `menu_order` != 0
     2143                                        GROUP BY `menu_order`, `post_parent`
     2144                                        HAVING COUNT( * ) >1
     2145                                )`b`
     2146                                ON `a`.`menu_order` = `b`.`menu_order`
     2147                                AND `a`.`post_parent` = `b`.`post_parent`
     2148                         LIMIT {$limit}", OBJECT_K );
     2149
     2150                $replies = array_merge( $menu_order_zero_published, $menu_order_repeated );
     2151        } else{
     2152                $replies = $menu_order_zero_published;
     2153        }
     2154
     2155        $replies_count = count( $replies );
     2156
     2157        // Bail if no replies returned
     2158        if ( $replies_count === 0 ) {
     2159                // Flush the cache; things are about to get ugly.
     2160                $data = array('notice' => 'All done.', 'replies' => $replies, 'result' => 'all-done');
     2161                echo json_encode( $data );
     2162                wp_die();
     2163        }
     2164
     2165        $update_count = 0;
     2166
     2167        // Recalculate the menu order position for each reply
     2168        foreach ( $replies as $reply ) {
     2169                $data = bbp_update_reply_position( $reply->ID );
     2170                $update_count++;
     2171        }
     2172
     2173        // Cleanup
     2174        unset( $replies, $reply );
     2175        $endTime = microtime(true);
     2176
     2177        // If you did a limit's worth of updating replies and that amount is the same as menu_order=0 replies,
     2178        // then check again to see if there are any more. If not, don't do that query, they're all done.
     2179        $continue_menu_order_zero = ( $menu_order_zero_count === $update_count ) ? true : false;
     2180
     2181        // Let's make a new nonce for each pass through. Just for laughs.
     2182        $iteration++;
     2183        $new_nonce = wp_create_nonce( 'bbp-sync-all-reply-positions' . $iteration );
     2184
     2185        $data = array('notice' => 'still more to do, it has been ' .  number_format( $endTime - $startTime, 2 ) . ' seconds.', 'continue_menu_order_zero' => $continue_menu_order_zero, 'passed_nonce'=> $new_nonce, 'iteration' => $iteration, 'result' => 'keep-going');
     2186        echo json_encode( $data );
     2187        wp_die();
     2188
     2189        //return array( 0, sprintf( $statement, __('Average update time: ' . $averageUpdateTime . "\n\nStandard deviation: " . $stdDevUpdateTime . "\n\nAverage query time: " . $averageQueryTime . "\n\nOffset: " . $offset . ' // Replies count: ' . $replies_count . ' // Mid time: ' . ($midTime - $startTime) . ' // End time: ' . ($endTime - $startTime), 'bbpress' ) ) );
     2190  }
     2191
     2192/**
     2193 * Recalculate reply menu order
     2194 *
     2195 * @since bbPress (r5367)
     2196 *
     2197 * @uses wpdb::query() To run our recount sql queries
     2198 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
     2199 * @uses bbp_get_reply_post_type() To get the reply post type
     2200 * @uses bbp_update_reply_position() To update the reply position
     2201 * @return array An array of the status code and the message
     2202 */
     2203function bbp_admin_repair_reply_menu_order( ) {
     2204        $bbp_db = bbp_db();
     2205
     2206        // Delete cases where `_bbp_reply_to` was accidentally set to itself
     2207        if ( is_wp_error( $bbp_db->query( "DELETE FROM `{$bbp_db->postmeta}` WHERE `meta_key` = '_bbp_reply_to' AND `post_id` = `meta_value`;" ) ) ) {
     2208                return array( 1, sprintf( $statement, $result ) );
     2209        }
     2210
     2211        // Post type
     2212        $rpt = bbp_get_reply_post_type();
     2213
     2214        // Pending status
     2215        $pst = bbp_get_pending_status_id();
     2216        // Public status
     2217        $pub = bbp_get_public_status_id();
     2218
     2219        $offset = 0;
     2220        $limit = ( !empty( $_GET['limit'] ) ) ? (int) $_GET['limit'] : 500;
     2221        $replies_count = 0;
     2222
     2223        $url = add_query_arg( 'limit', $limit );
     2224
     2225        $statement =  __( 'Recalculating reply menu order &hellip; %s', 'bbpress' );
     2226        $result    = __( 'No more reply positions to recalculate!', 'bbpress' );
     2227
     2228        // First look through the menu_order 0 replies. Are there any published replies with menu_order 0?
     2229        // But don't do this if you don't need to.
     2230
     2231        $menu_order_zero_published =
     2232                $bbp_db->get_results(
     2233                        "SELECT `ID`
     2234                                FROM `{$bbp_db->posts}`
     2235                                WHERE `post_type` = '{$rpt}' AND `post_status` = '{$pub}' AND `menu_order` = 0
     2236                         LIMIT {$limit}", OBJECT_K );
     2237
     2238        $menu_order_zero_count = count( $menu_order_zero_published );
     2239
     2240        // only get the array with duplicate menu orders if we're going to use it.
     2241        if( $menu_order_zero_count < $limit ){
     2242
     2243                $limit = $limit - $menu_order_zero_count;
     2244
     2245                // Get an array of reply ids to update the menu oder for each reply
     2246                $menu_order_repeated = $bbp_db->get_results(
     2247                        "SELECT `a`.`ID` FROM `{$bbp_db->posts}` AS `a`
     2248                                INNER JOIN (
     2249                                        SELECT `menu_order`, `post_parent`
     2250                                        FROM `{$bbp_db->posts}` WHERE `post_type` = '{$rpt}' AND `menu_order` != 0
     2251                                        GROUP BY `menu_order`, `post_parent`
     2252                                        HAVING COUNT( * ) >1
     2253                                )`b`
     2254                                ON `a`.`menu_order` = `b`.`menu_order`
     2255                                AND `a`.`post_parent` = `b`.`post_parent`
     2256                         LIMIT {$limit}", OBJECT_K );
     2257
     2258                $replies = array_merge( $menu_order_zero_published, $menu_order_repeated );
     2259        } else{
     2260                $replies = $menu_order_zero_published;
     2261        }
     2262
     2263        $replies_count = count( $replies );
     2264        $url = add_query_arg( 'limit', '500' );
     2265
    21022266        // Bail if no replies returned
    2103         if ( empty( $replies ) ) {
     2267        if ( 0 === $replies_count ) {
     2268                wp_cache_flush();
    21042269                return array( 1, sprintf( $statement, $result ) );
    21052270        }
    21062271
     
    21122277        // Cleanup
    21132278        unset( $replies, $reply );
    21142279
    2115         // Flush the cache; things are about to get ugly.
    2116         wp_cache_flush();
    2117 
    2118         return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
     2280        $result = sprintf( __( 'There are more to do. <a href="%s">Do more!</a>', 'bbpress' ), esc_url( $url ) );
     2281        return array( 1, sprintf( $statement, $result ) );
    21192282}
    21202283
    21212284/** Reset ********************************************************************/
  • src/includes/common/functions.php

     
    16121612 *                        parent id and post type
    16131613 * @return array The array of children
    16141614 */
    1615 function bbp_get_public_child_ids( $parent_id = 0, $post_type = 'post' ) {
     1615function bbp_get_public_child_ids( $parent_id = 0, $post_type = 'post', $order_by = 'ID', $use_cache = true ) {
    16161616
    16171617        // Bail if nothing passed
    16181618        if ( empty( $parent_id ) ) {
     
    16201620        }
    16211621
    16221622        // The ID of the cached query
    1623         $cache_id  = 'bbp_parent_public_' . $parent_id . '_type_' . $post_type . '_child_ids';
     1623        if( $order_by === 'ID' ){
     1624                $cache_id  = 'bbp_parent_public_' . $parent_id . '_type_' . $post_type . '_child_ids';
     1625        }
     1626        else{
     1627                $cache_id = 'bbp_' . $parent_id . '_public_children_orderby_' . $order_by;
     1628        }
    16241629
    16251630        // Check for cache and set if needed
    1626         $child_ids = wp_cache_get( $cache_id, 'bbpress_posts' );
     1631        $child_ids = ( $use_cache ) ? wp_cache_get( $cache_id, 'bbpress_posts' ) : false;
     1632
    16271633        if ( false === $child_ids ) {
    16281634                $post_status = array( bbp_get_public_status_id() );
    16291635
     
    16351641                // Join post statuses together
    16361642                $post_status = "'" . implode( "', '", $post_status ) . "'";
    16371643                $bbp_db      = bbp_db();
    1638                 $query       = $bbp_db->prepare( "SELECT ID FROM {$bbp_db->posts} WHERE post_parent = %d AND post_status IN ( {$post_status} ) AND post_type = '%s' ORDER BY ID DESC;", $parent_id, $post_type );
     1644                $query       = $bbp_db->prepare( "SELECT ID FROM {$bbp_db->posts} WHERE post_parent = %d AND post_status IN ( {$post_status} ) AND post_type = '%s' ORDER BY {$order_by} DESC;", $parent_id, $post_type );
    16391645                $child_ids   = (array) $bbp_db->get_col( $query );
    16401646
    16411647                wp_cache_set( $cache_id, $child_ids, 'bbpress_posts' );
     
    16421648        } else {
    16431649                $child_ids = (array) $child_ids;
    16441650        }
    1645 
    16461651        // Filter and return
    16471652        return (array) apply_filters( 'bbp_get_public_child_ids', $child_ids, $parent_id, $post_type );
    16481653}
  • src/includes/replies/functions.php

     
    23352335
    23362336        // If no position was passed, get it from the db and update the menu_order
    23372337        if ( empty( $reply_position ) ) {
    2338                 $reply_position = bbp_get_reply_position_raw( $reply_id, bbp_get_reply_topic_id( $reply_id ) );
     2338                $reply_position = bbp_get_reply_position_published( $reply_id, bbp_get_reply_topic_id( $reply_id ) );
    23392339        }
    23402340
    23412341        // Toggle revisions off as we are not altering content
     
    23692369 * @param int $topic_id
    23702370 */
    23712371function bbp_get_reply_position_raw( $reply_id = 0, $topic_id = 0 ) {
     2372        return bbp_get_reply_position_any( $reply_id, $topic_id, $post_status = 'all' );
     2373}
    23722374
     2375function bbp_get_reply_position_published( $reply_id = 0, $topic_id = 0 ) {
     2376        return bbp_get_reply_position_any( $reply_id, $topic_id, $post_status = 'publish' );
     2377}
     2378
     2379function bbp_get_reply_position_any( $reply_id = 0, $topic_id = 0, $post_status = 'all' ){
     2380
    23732381        // Get required data
    23742382        $reply_id       = bbp_get_reply_id( $reply_id );
    23752383        $topic_id       = ! empty( $topic_id ) ? bbp_get_topic_id( $topic_id ) : bbp_get_reply_topic_id( $reply_id );
     
    23832391                if ( ! empty( $reply_count ) ) {
    23842392
    23852393                        // Get reply id's
    2386                         $topic_replies = bbp_get_all_child_ids( $topic_id, bbp_get_reply_post_type() );
     2394                        switch ( $post_status ) {
     2395                                case 'publish' :
     2396                                        $topic_replies = bbp_get_public_child_ids( $topic_id, bbp_get_reply_post_type(), 'post_date DESC, ID', false );
     2397                                        break;
     2398                                default:
     2399                                        $topic_replies = bbp_get_all_child_ids( $topic_id, bbp_get_reply_post_type() );
     2400                        }
     2401
    23872402                        if ( ! empty( $topic_replies ) ) {
    23882403
    23892404                                // Reverse replies array and search for current reply position