Skip to:
Content

BuddyPress.org

Ticket #5296: 5296.02.patch

File 5296.02.patch, 12.8 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..ef11105 100644
    add_action( bp_core_admin_hook(), 'bp_core_admin_backpat_menu', 999 ); 
    7474 * @since BuddyPress (1.6)
    7575 */
    7676function bp_core_modify_admin_menu_highlight() {
    77         global $plugin_page, $submenu_file;
     77        global $pagenow, $plugin_page, $submenu_file;
    7878
    7979        // This tweaks the Settings subnav menu to show only one BuddyPress menu item
    8080        if ( ! in_array( $plugin_page, array( 'bp-activity', 'bp-general-settings', ) ) )
    8181                $submenu_file = 'bp-components';
     82
     83        // Network Admin > Tools
     84        if ( in_array( $plugin_page, array( 'bp-tools', 'available-tools' ) ) ) {
     85                $submenu_file = $plugin_page;
     86        }
    8287}
    8388
    8489/**
    function bp_core_admin_tabs( $active_tab = '' ) { 
    388393                '2' => array(
    389394                        'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-settings' ), 'admin.php' ) ),
    390395                        'name' => __( 'Settings', 'buddypress' )
    391                 )
     396                ),
    392397        );
    393398
    394399        // 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..ecaac64
    - +  
     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><?php esc_html_e( 'BuddyPress 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="bp-tools-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        if ( empty( $_POST['bp-tools-submit'] ) ) {
     65                return;
     66        }
     67
     68        check_admin_referer( 'bp-do-counts' );
     69
     70        // Stores messages
     71        $messages = array();
     72
     73        wp_cache_flush();
     74
     75        foreach ( (array) bp_admin_repair_list() as $item ) {
     76                if ( isset( $item[2] ) && isset( $_POST[$item[0]] ) && 1 === absint( $_POST[$item[0]] ) && is_callable( $item[2] ) ) {
     77                        $messages[] = call_user_func( $item[2] );
     78                }
     79        }
     80
     81        if ( count( $messages ) ) {
     82                foreach ( $messages as $message ) {
     83                        bp_admin_tools_feedback( $message[1] );
     84                }
     85        }
     86}
     87add_action( bp_core_admin_hook(), 'bp_admin_repair_handler' );
     88
     89/**
     90 * Get the array of the repair list.
     91 *
     92 * @return array
     93 */
     94function bp_admin_repair_list() {
     95        // Members:
     96        // - member count
     97        $repair_list = array(
     98                20 => array(
     99                        'bp-total-member-count',
     100                        __( 'Count total members', 'buddypress' ),
     101                        'bp_admin_repair_count_members',
     102                ),
     103        );
     104
     105        // Friends:
     106        // - user friend count
     107        if ( bp_is_active( 'friends' ) ) {
     108                $repair_list[0] = array(
     109                        'bp-user-friends',
     110                        __( 'Count friends for each user', 'buddypress' ),
     111                        'bp_admin_repair_friend_count',
     112                );
     113        }
     114
     115        // Groups:
     116        // - user group count
     117        if ( bp_is_active( 'groups' ) ) {
     118                $repair_list[10] = array(
     119                        'bp-group-count',
     120                        __( 'Count groups for each user', 'buddypress' ),
     121                        'bp_admin_repair_group_count',
     122                );
     123        }
     124
     125        ksort( $repair_list );
     126
     127        return (array) apply_filters( 'bp_repair_list', $repair_list );
     128}
     129
     130/**
     131 * Recalculate friend counts for each user.
     132 *
     133 * @since BuddyPress (2.0.0)
     134 *
     135 * @return array
     136 */
     137function bp_admin_repair_friend_count() {
     138        global $wpdb, $bp;
     139
     140        if ( ! bp_is_active( 'friends' ) ) {
     141                return;
     142        }
     143
     144        $statement = __( 'Counting the number of friends for each user&hellip; %s', 'buddypress' );
     145        $result    = __( 'Failed!', 'buddypress' );
     146
     147        $sql_delete = "DELETE FROM {$wpdb->usermeta} WHERE meta_key IN ( 'total_friend_count' );";
     148        if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) {
     149                return array( 1, sprintf( $statement, $result ) );
     150        }
     151
     152        // Walk through all users on the site
     153        $total_users = $wpdb->get_row( "SELECT count(ID) as c FROM {$wpdb->users}" )->c;
     154
     155        $updated = array();
     156        if ( $total_users > 0 ) {
     157                $per_query = 500;
     158                $offset = 0;
     159                while ( $offset < $total_users ) {
     160                        // Only bother updating counts for users who actually have friendships
     161                        $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 ) );
     162
     163                        // The previous query will turn up duplicates, so we
     164                        // filter them here
     165                        foreach ( $friendships as $friendship ) {
     166                                if ( ! isset( $updated[ $friendship->initiator_user_id ] ) ) {
     167                                        BP_Friends_Friendship::total_friend_count( $friendship->initiator_user_id );
     168                                        $updated[ $friendship->initiator_user_id ] = 1;
     169                                }
     170
     171                                if ( ! isset( $updated[ $friendship->friend_user_id ] ) ) {
     172                                        BP_Friends_Friendship::total_friend_count( $friendship->friend_user_id );
     173                                        $updated[ $friendship->friend_user_id ] = 1;
     174                                }
     175                        }
     176
     177                        $offset += $per_query;
     178                }
     179        } else {
     180                return array( 2, sprintf( $statement, $result ) );
     181        }
     182
     183        return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
     184}
     185
     186/**
     187 * Recalculate group counts for each user.
     188 *
     189 * @since BuddyPress (2.0.0)
     190 *
     191 * @return array
     192 */
     193function bp_admin_repair_group_count() {
     194        global $wpdb, $bp;
     195
     196        if ( ! bp_is_active( 'groups' ) ) {
     197                return;
     198        }
     199
     200        $statement = __( 'Counting the number of groups for each user&hellip; %s', 'buddypress' );
     201        $result    = __( 'Failed!', 'buddypress' );
     202
     203        $sql_delete = "DELETE FROM {$wpdb->usermeta} WHERE meta_key IN ( 'total_group_count' );";
     204        if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) {
     205                return array( 1, sprintf( $statement, $result ) );
     206        }
     207
     208        // Walk through all users on the site
     209        $total_users = $wpdb->get_row( "SELECT count(ID) as c FROM {$wpdb->users}" )->c;
     210
     211        if ( $total_users > 0 ) {
     212                $per_query = 500;
     213                $offset = 0;
     214                while ( $offset < $total_users ) {
     215                        // But only bother to update counts for users that have groups
     216                        $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 ) );
     217
     218                        foreach ( $users as $user ) {
     219                                BP_Groups_Member::refresh_total_group_count_for_user( $user );
     220                        }
     221
     222                        $offset += $per_query;
     223                }
     224        } else {
     225                return array( 2, sprintf( $statement, $result ) );
     226        }
     227
     228        return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
     229}
     230
     231/**
     232 * Recalculate the total number of active site members.
     233 *
     234 * @since BuddyPress (2.0.0)
     235 */
     236function bp_admin_repair_count_members() {
     237        $statement = __( 'Counting the number of active members on the site&hellip; %s', 'buddypress' );
     238        delete_transient( 'bp_active_member_count' );
     239        bp_core_get_active_member_count();
     240        return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
     241}
     242
     243/**
     244 * Assemble admin notices relating success/failure of repair processes.
     245 *
     246 * @since BuddyPress (2.0.0)
     247 *
     248 * @param string $message Feedback message.
     249 * @param unknown $class Unused.
     250 */
     251function bp_admin_tools_feedback( $message, $class = false ) {
     252        if ( is_string( $message ) ) {
     253                $message = '<p>' . $message . '</p>';
     254                $class = $class ? $class : 'updated';
     255        } elseif ( is_wp_error( $message ) ) {
     256                $errors = $message->get_error_messages();
     257
     258                switch ( count( $errors ) ) {
     259                        case 0:
     260                                return false;
     261                                break;
     262
     263                        case 1:
     264                                $message = '<p>' . $errors[0] . '</p>';
     265                                break;
     266
     267                        default:
     268                                $message = '<ul>' . "\n\t" . '<li>' . implode( '</li>' . "\n\t" . '<li>', $errors ) . '</li>' . "\n" . '</ul>';
     269                                break;
     270                }
     271
     272                $class = $class ? $class : 'error';
     273        } else {
     274                return false;
     275        }
     276
     277        $message = '<div id="message" class="' . esc_attr( $class ) . '">' . $message . '</div>';
     278        $message = str_replace( "'", "\'", $message );
     279        $lambda  = create_function( '', "echo '$message';" );
     280
     281        add_action( 'admin_notices', $lambda );
     282
     283        return $lambda;
     284}
     285
     286/**
     287 * Render the Available Tools page.
     288 *
     289 * We register this page on Network Admin as a top-level home for our
     290 * BuddyPress tools. This displays the default content.
     291 *
     292 * @since BuddyPress (2.0.0)
     293 */
     294function bp_core_admin_available_tools_page() {
     295        global $submenu;
     296
     297        // Stupid trick: grab all the submenu items and make a list
     298        $tools = isset( $submenu['network-tools'] ) ? $submenu['network-tools'] : array();
     299
     300        ?>
     301        <div class="wrap">
     302                <h2><?php esc_attr_e( 'Tools', 'buddypress' ) ?></h2>
     303
     304                <ul>
     305                <?php foreach ( $tools as $tool ) : ?>
     306                        <?php /* Skip "Available Tools" */ ?>
     307                        <?php if ( 'available-tools' === $tool[2] ) continue; ?>
     308                        <li><a href="<?php echo esc_url( add_query_arg( 'page', $tool[2], network_admin_url( 'admin.php' ) ) ) ?>"><?php echo esc_html( $tool[3] ) ?></a></li>
     309                <?php endforeach; ?>
     310                </ul>
     311        </div>
     312        <?php
     313}
  • bp-core/admin/css/common.css

    diff --git bp-core/admin/css/common.css bp-core/admin/css/common.css
    index 17548ec..e476679 100644
    body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network.current .wp-menu 
    9090body.branch-3-7 ul#adminmenu li.toplevel_page_bp-groups_network.wp-has-current-submenu .wp-menu-image {
    9191        background-position: -61px -2px;
    9292}
     93
     94/* Tools */
     95#adminmenu .toplevel_page_network-tools div.wp-menu-image:before {
     96    content: "";
     97}
     98
    9399th.column-gid {
    94100        width: 60px;
    95101}
  • bp-core/bp-core-admin.php

    diff --git bp-core/bp-core-admin.php bp-core/bp-core-admin.php
    index 4020355..bf541ac 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                // For consistency with non-Multisite, we add a Tools menu in
     247                // the Network Admin as a home for our Tools panel
     248                if ( is_multisite() && bp_core_do_network_admin() ) {
     249                        $tools_parent = 'network-tools';
     250
     251                        $hooks[] = add_menu_page(
     252                                __( 'Tools', 'buddypress' ),
     253                                __( 'Tools', 'buddypress' ),
     254                                'manage_network_options',
     255                                $tools_parent,
     256                                'bp_core_tools_top_level_item',
     257                                '',
     258                                24 // just above Settings
     259                        );
     260
     261                        $hooks[] = add_submenu_page(
     262                                $tools_parent,
     263                                __( 'Available Tools', 'buddypress' ),
     264                                __( 'Available Tools', 'buddypress' ),
     265                                'manage_network_options',
     266                                'available-tools',
     267                                'bp_core_admin_available_tools_page'
     268                        );
     269                } else {
     270                        $tools_parent = 'tools.php';
     271                }
     272
     273                $hooks[] = add_submenu_page(
     274                        $tools_parent,
     275                        __( 'BuddyPress Tools', 'buddypress' ),
     276                        __( 'BuddyPress', 'buddypress' ),
     277                        'manage_options',
     278                        'bp-tools',
     279                        'bp_core_admin_tools'
     280                );
     281
    245282                // Fudge the highlighted subnav item when on a BuddyPress admin page
    246283                foreach( $hooks as $hook ) {
    247284                        add_action( "admin_head-$hook", 'bp_core_modify_admin_menu_highlight' );
    class BP_Admin { 
    401438                remove_submenu_page( $this->settings_page, 'bp-page-settings' );
    402439                remove_submenu_page( $this->settings_page, 'bp-settings'      );
    403440
     441                // Network Admin Tools
     442                remove_submenu_page( 'network-tools', 'network-tools' );
     443
    404444                // About and Credits pages
    405445                remove_submenu_page( 'index.php', 'bp-about'   );
    406446                remove_submenu_page( 'index.php', 'bp-credits' );