Skip to:
Content

BuddyPress.org

Ticket #5296: 5296.patch

File 5296.patch, 10.6 KB (added by boonebgorges, 8 years ago)
  • bp-core/admin/bp-core-functions.php

    diff --git bp-core/admin/bp-core-functions.php bp-core/admin/bp-core-functions.php
    index e47e7da..8c01ff6 100644
    function bp_core_admin_tabs( $active_tab = '' ) { 
    388388                '2' => array(
    389389                        'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-settings' ), 'admin.php' ) ),
    390390                        'name' => __( 'Settings', 'buddypress' )
    391                 )
     391                ),
     392
     393                // Keyed late so it's always last
     394                '99' => array(
     395                        'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-tools' ), 'admin.php' ) ),
     396                        'name' => __( 'Tools', 'buddypress' ),
     397                ),
    392398        );
    393399
    394400        // If forums component is active, add additional tab
  • new file p-core/admin/bp-core-tools.php

    diff --git bp-core/admin/bp-core-tools.php bp-core/admin/bp-core-tools.php
    new file mode 100644
    index 0000000..ed050fe
    - +  
     1<?php
     2
     3/**
     4 * BuddyPress Tools panel
     5 *
     6 * @since BuddyPress (2.0.0)
     7 */
     8
     9/**
     10 * Render the BuddyPress Tools page.
     11 *
     12 * @since BuddyPress (2.0.0)
     13 */
     14function bp_core_admin_tools() {
     15        ?>
     16        <div class="wrap">
     17                <?php screen_icon( 'buddypress'); ?>
     18
     19                <h2 class="nav-tab-wrapper"><?php bp_core_admin_tabs( __( 'Tools', 'buddypress' ) ); ?></h2>
     20
     21                <p><?php esc_html_e( 'BuddyPress keeps track of various relationships between users, groups, and activity items. Occasionally these relationships become out of sync, most often after an import, update, or migration. Use the tools below to manually recalculate these relationships.', 'buddypress' ); ?></p>
     22                <p class="description"><?php esc_html_e( 'Some of these tools create substantial database overhead. Avoid running more than one repair job at a time.', 'buddypress' ); ?></p>
     23
     24                <form class="settings" method="post" action="">
     25                        <table class="form-table">
     26                                <tbody>
     27                                        <tr valign="top">
     28                                                <th scope="row"><?php esc_html_e( 'Data to Repair:', 'buddypress' ) ?></th>
     29                                                <td>
     30                                                        <fieldset>
     31                                                                <legend class="screen-reader-text"><span><?php esc_html_e( 'Repair', 'buddypress' ) ?></span></legend>
     32
     33                                                                <?php foreach ( bp_admin_repair_list() as $item ) : ?>
     34
     35                                                                        <label><input type="checkbox" class="checkbox" name="<?php echo esc_attr( $item[0] ) . '" id="' . esc_attr( str_replace( '_', '-', $item[0] ) ); ?>" value="1" /> <?php echo esc_html( $item[1] ); ?></label><br />
     36
     37                                                                <?php endforeach; ?>
     38
     39                                                        </fieldset>
     40                                                </td>
     41                                        </tr>
     42                                </tbody>
     43                        </table>
     44
     45                        <fieldset class="submit">
     46                                <input class="button-primary" type="submit" name="submit" value="<?php esc_attr_e( 'Repair Items', 'buddypress' ); ?>" />
     47                                <?php wp_nonce_field( 'bp-do-counts' ); ?>
     48                        </fieldset>
     49                </form>
     50        </div>
     51        <?php
     52}
     53
     54/**
     55 * Handle the processing and feedback of the admin tools page.
     56 *
     57 * @since BuddyPress (2.0.0)
     58 */
     59function bp_admin_repair_handler() {
     60        if ( ! bp_is_post_request() ) {
     61                return;
     62        }
     63
     64        check_admin_referer( 'bp-do-counts' );
     65
     66        // Stores messages
     67        $messages = array();
     68
     69        wp_cache_flush();
     70
     71        foreach ( (array) bp_admin_repair_list() as $item ) {
     72                if ( isset( $item[2] ) && isset( $_POST[$item[0]] ) && 1 === absint( $_POST[$item[0]] ) && is_callable( $item[2] ) ) {
     73                        $messages[] = call_user_func( $item[2] );
     74                }
     75        }
     76
     77        if ( count( $messages ) ) {
     78                foreach ( $messages as $message ) {
     79                        bp_admin_tools_feedback( $message[1] );
     80                }
     81        }
     82}
     83add_action( bp_core_admin_hook(), 'bp_admin_repair_handler' );
     84
     85/**
     86 * Get the array of the repair list.
     87 *
     88 * @return array
     89 */
     90function bp_admin_repair_list() {
     91        // Members:
     92        // - member count
     93        $repair_list = array(
     94                20 => array(
     95                        'bp-total-member-count',
     96                        __( 'Count total members', 'buddypress' ),
     97                        'bp_admin_repair_count_members',
     98                ),
     99        );
     100
     101        // Friends:
     102        // - user friend count
     103        if ( bp_is_active( 'friends' ) ) {
     104                $repair_list[0] = array(
     105                        'bp-user-friends',
     106                        __( 'Count friends for each user', 'buddypress' ),
     107                        'bp_admin_repair_friend_count',
     108                );
     109        }
     110
     111        // Groups:
     112        // - user group count
     113        if ( bp_is_active( 'groups' ) ) {
     114                $repair_list[10] = array(
     115                        'bp-group-count',
     116                        __( 'Count groups for each user', 'buddypress' ),
     117                        'bp_admin_repair_group_count',
     118                );
     119        }
     120
     121        ksort( $repair_list );
     122
     123        return (array) apply_filters( 'bp_repair_list', $repair_list );
     124}
     125
     126/**
     127 * Recalculate friend counts for each user.
     128 *
     129 * @since BuddyPress (2.0.0)
     130 *
     131 * @return array
     132 */
     133function bp_admin_repair_friend_count() {
     134        global $wpdb, $bp;
     135
     136        if ( ! bp_is_active( 'friends' ) ) {
     137                return;
     138        }
     139
     140        $statement = __( 'Counting the number of friends for each user&hellip; %s', 'buddypress' );
     141        $result    = __( 'Failed!', 'buddypress' );
     142
     143        $sql_delete = "DELETE FROM {$wpdb->usermeta} WHERE meta_key IN ( 'total_friend_count' );";
     144        if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) {
     145                return array( 1, sprintf( $statement, $result ) );
     146        }
     147
     148        // Walk through all users on the site
     149        $total_users = $wpdb->get_row( "SELECT count(ID) as c FROM {$wpdb->users}" )->c;
     150
     151        $updated = array();
     152        if ( $total_users > 0 ) {
     153                $per_query = 500;
     154                $offset = 0;
     155                while ( $offset < $total_users ) {
     156                        // Only bother updating counts for users who actually have friendships
     157                        $friendships = $wpdb->get_results( $wpdb->prepare( "SELECT initiator_user_id, friend_user_id FROM {$bp->friends->table_name} WHERE is_confirmed = 1 AND ( ( initiator_user_id > %d AND initiator_user_id <= %d ) OR ( friend_user_id > %d AND friend_user_id <= %d ) )", $offset, $offset + $per_query, $offset, $offset + $per_query ) );
     158
     159                        // The previous query will turn up duplicates, so we
     160                        // filter them here
     161                        foreach ( $friendships as $friendship ) {
     162                                if ( ! isset( $updated[ $friendship->initiator_user_id ] ) ) {
     163                                        BP_Friends_Friendship::total_friend_count( $friendship->initiator_user_id );
     164                                        $updated[ $friendship->initiator_user_id ] = 1;
     165                                }
     166
     167                                if ( ! isset( $updated[ $friendship->friend_user_id ] ) ) {
     168                                        BP_Friends_Friendship::total_friend_count( $friendship->friend_user_id );
     169                                        $updated[ $friendship->friend_user_id ] = 1;
     170                                }
     171                        }
     172
     173                        $offset += $per_query;
     174                }
     175        } else {
     176                return array( 2, sprintf( $statement, $result ) );
     177        }
     178
     179        return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
     180}
     181
     182/**
     183 * Recalculate group counts for each user.
     184 *
     185 * @since BuddyPress (2.0.0)
     186 *
     187 * @return array
     188 */
     189function bp_admin_repair_group_count() {
     190        global $wpdb, $bp;
     191
     192        if ( ! bp_is_active( 'groups' ) ) {
     193                return;
     194        }
     195
     196        $statement = __( 'Counting the number of groups for each user&hellip; %s', 'buddypress' );
     197        $result    = __( 'Failed!', 'buddypress' );
     198
     199        $sql_delete = "DELETE FROM {$wpdb->usermeta} WHERE meta_key IN ( 'total_group_count' );";
     200        if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) {
     201                return array( 1, sprintf( $statement, $result ) );
     202        }
     203
     204        // Walk through all users on the site
     205        $total_users = $wpdb->get_row( "SELECT count(ID) as c FROM {$wpdb->users}" )->c;
     206
     207        if ( $total_users > 0 ) {
     208                $per_query = 500;
     209                $offset = 0;
     210                while ( $offset < $total_users ) {
     211                        // But only bother to update counts for users that have groups
     212                        $users = $wpdb->get_col( $wpdb->prepare( "SELECT user_id FROM {$bp->groups->table_name_members} WHERE is_confirmed = 1 AND is_banned = 0 AND user_id > %d AND user_id <= %d", $offset, $offset + $per_query ) );
     213
     214                        foreach ( $users as $user ) {
     215                                BP_Groups_Member::refresh_total_group_count_for_user( $user );
     216                        }
     217
     218                        $offset += $per_query;
     219                }
     220        } else {
     221                return array( 2, sprintf( $statement, $result ) );
     222        }
     223
     224        return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
     225}
     226
     227/**
     228 * Recalculate the total number of active site members.
     229 *
     230 * @since BuddyPress (2.0.0)
     231 */
     232function bp_admin_repair_count_members() {
     233        $statement = __( 'Counting the number of active members on the site&hellip; %s', 'buddypress' );
     234        delete_transient( 'bp_active_member_count' );
     235        bp_core_get_active_member_count();
     236        return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
     237}
     238
     239/**
     240 * Assemble admin notices relating success/failure of repair processes.
     241 *
     242 * @since BuddyPress (2.0.0)
     243 *
     244 * @param string $message Feedback message.
     245 * @param unknown $class Unused.
     246 */
     247function bp_admin_tools_feedback( $message, $class = false ) {
     248        if ( is_string( $message ) ) {
     249                $message = '<p>' . $message . '</p>';
     250                $class = $class ? $class : 'updated';
     251        } elseif ( is_wp_error( $message ) ) {
     252                $errors = $message->get_error_messages();
     253
     254                switch ( count( $errors ) ) {
     255                        case 0:
     256                                return false;
     257                                break;
     258
     259                        case 1:
     260                                $message = '<p>' . $errors[0] . '</p>';
     261                                break;
     262
     263                        default:
     264                                $message = '<ul>' . "\n\t" . '<li>' . implode( '</li>' . "\n\t" . '<li>', $errors ) . '</li>' . "\n" . '</ul>';
     265                                break;
     266                }
     267
     268                $class = $class ? $class : 'error';
     269        } else {
     270                return false;
     271        }
     272
     273        $message = '<div id="message" class="' . esc_attr( $class ) . '">' . $message . '</div>';
     274        $message = str_replace( "'", "\'", $message );
     275        $lambda  = create_function( '', "echo '$message';" );
     276
     277        add_action( 'admin_notices', $lambda );
     278
     279        return $lambda;
     280}
  • bp-core/bp-core-admin.php

    diff --git bp-core/bp-core-admin.php bp-core/bp-core-admin.php
    index 4020355..4aaae35 100644
    class BP_Admin { 
    118118                require( $this->admin_dir . 'bp-core-functions.php'  );
    119119                require( $this->admin_dir . 'bp-core-components.php' );
    120120                require( $this->admin_dir . 'bp-core-slugs.php'      );
     121                require( $this->admin_dir . 'bp-core-tools.php'      );
    121122        }
    122123
    123124        /**
    class BP_Admin { 
    242243                        'bp_core_admin_settings'
    243244                );
    244245
     246                $hooks[] = add_submenu_page(
     247                        $this->settings_page,
     248                        __( 'BuddyPress Tools', 'buddypress' ),
     249                        __( 'BuddyPress Tools', 'buddypress' ),
     250                        'manage_options',
     251                        'bp-tools',
     252                        'bp_core_admin_tools'
     253                );
     254
    245255                // Fudge the highlighted subnav item when on a BuddyPress admin page
    246256                foreach( $hooks as $hook ) {
    247257                        add_action( "admin_head-$hook", 'bp_core_modify_admin_menu_highlight' );
    class BP_Admin { 
    342352                }
    343353
    344354                /** Avatar upload for users or groups ************************************/
    345                
     355
    346356                if ( ! empty( $avatar_setting ) ) {
    347357                    // Allow avatar uploads
    348358                    add_settings_field( 'bp-disable-avatar-uploads', __( 'Avatar Uploads',   'buddypress' ), 'bp_admin_setting_callback_avatar_uploads',   'buddypress', $avatar_setting );
    class BP_Admin { 
    400410                // Settings pages
    401411                remove_submenu_page( $this->settings_page, 'bp-page-settings' );
    402412                remove_submenu_page( $this->settings_page, 'bp-settings'      );
     413                remove_submenu_page( $this->settings_page, 'bp-tools'         );
    403414
    404415                // About and Credits pages
    405416                remove_submenu_page( 'index.php', 'bp-about'   );