Skip to:
Content

BuddyPress.org

Ticket #4414: 4414.03.patch

File 4414.03.patch, 55.5 KB (added by boonebgorges, 12 years ago)
  • bp-core/admin/css/common.dev.css

    diff --git bp-core/admin/css/common.dev.css bp-core/admin/css/common.dev.css
    index f722b52..9295759 100644
    div#icon-buddypress-activity { 
    1515        background: url( ../images/icons32.png ) no-repeat -10px -6px;
    1616}
    1717
     18div#icon-buddypress-groups {
     19        background: url( ../images/icons32.png ) no-repeat -250px -6px;
     20}
     21
    1822/* Menu Icons
    1923------------------------------------------------------------------------------*/
    2024
    ul#adminmenu li.toplevel_page_bp-activity_network.wp-has-current-submenu .wp-men 
    6973        background-position: 0 -2px;
    7074}
    7175
     76/* Groups */
     77ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image a img,
     78ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image a img {
     79        display: none;
     80}
     81ul#adminmenu li.toplevel_page_bp-groups .wp-menu-image a,
     82ul#adminmenu li.toplevel_page_bp-groups_network .wp-menu-image a {
     83        background-image: url( ../images/menu.png ) !important;
     84        background-position: -61px -34px;
     85}
     86ul#adminmenu li.toplevel_page_bp-groups:hover .wp-menu-image a,
     87ul#adminmenu li.toplevel_page_bp-groups.current .wp-menu-image a,
     88ul#adminmenu li.toplevel_page_bp-groups.wp-has-current-submenu .wp-menu-image a,
     89ul#adminmenu li.toplevel_page_bp-groups_network:hover .wp-menu-image a,
     90ul#adminmenu li.toplevel_page_bp-groups_network.current .wp-menu-image a,
     91ul#adminmenu li.toplevel_page_bp-groups_network.wp-has-current-submenu .wp-menu-image a {
     92        background-position: -61px -2px;
     93}
     94th.column-gid {
     95        width: 60px;
     96}
     97td.column-gid {
     98        vertical-align: middle;
     99}
     100table.bp-group-members th,
     101table.bp-group-members td {
     102        padding: 5px 0;
     103}
     104table.bp-group-members .uid-column {
     105        padding-left: 20px;
     106        padding-right: 20px;
     107}
     108table.bp-group-members .uname-column {
     109        width: 70%;
     110}
     111table.bp-group-members .urole-column {
     112        padding-left: 20px;
     113        padding-right: 20px;
     114}
    72115
    73116/* Components
    74117------------------------------------------------------------------------------*/
  • new file p-groups/admin/css/admin.dev.css

    diff --git bp-groups/admin/css/admin.dev.css bp-groups/admin/css/admin.dev.css
    new file mode 100644
    index 0000000..41049cb
    - +  
     1body.js #bp-groups-new-members-help-nojs {
     2        display: none;
     3}
     4body.no-js #bp-groups-new-members-help-js {
     5        display: none;
     6}
     7#bp-groups-edit-form input {
     8        outline: medium none;
     9        padding: 3px 8px;
     10}
     11#bp-groups-edit-form input#bp-groups-name {
     12        font-size: 1.7em;
     13        width: 100%;
     14}
     15#bp-groups-edit-form input#bp-groups-new-members {
     16        border: 0;
     17}
  • new file p-groups/admin/js/admin.dev.js

    diff --git bp-groups/admin/js/admin.dev.js bp-groups/admin/js/admin.dev.js
    new file mode 100644
    index 0000000..ce9e634
    - +  
     1(function($) {
     2        function add_member_to_list( e, ui ) {
     3                var remove_id = 'bp-groups-remove-new-member-' + ui.item.value;
     4                $('#bp-groups-new-members-list').append('<li><a href="#" class="bp-groups-remove-new-member" id="' + remove_id + '">x</a> ' + ui.item.label + '</li>');
     5                $('#' + remove_id).bind('click', function(e) { remove_member_from_list(e); return false; });
     6
     7                $('#bp-groups-new-members-list').after('<input name="new_members[]" type="hidden" value="' + ui.item.value + '" />');
     8        }
     9
     10        function remove_member_from_list( e ) {
     11                $(e.target).closest('li').remove();
     12        }
     13
     14        var id = 'undefined' !== typeof group_members ? '&group_members=' + group_members : '';
     15        $(document).ready( function() {
     16                $( '.bp-suggest-user' ).autocomplete({
     17                        source:    ajaxurl + '?action=bp_group_admin_member_autocomplete' + id,
     18                        delay:     500,
     19                        minLength: 2,
     20                        position:  ( 'undefined' !== typeof isRtl && isRtl ) ? { my: 'right top', at: 'right bottom', offset: '0, -1' } : { offset: '0, -1' },
     21                        open:      function() { $(this).addClass('open'); },
     22                        close:     function() { $(this).removeClass('open'); $(this).val(''); },
     23                        select:    function( event, ui ) { add_member_to_list( event, ui ); },
     24
     25                });
     26
     27        });
     28})(jQuery);
  • new file p-groups/bp-groups-admin.php

    diff --git bp-groups/bp-groups-admin.php bp-groups/bp-groups-admin.php
    new file mode 100644
    index 0000000..62db683
    - +  
     1<?php
     2/**
     3 * BuddyPress Groups component admin screen
     4 *
     5 * Props to WordPress core for the Comments admin screen, and its contextual help text,
     6 * on which this implementation is heavily based.
     7 *
     8 * @package BuddyPress
     9 * @since 1.7
     10 * @subpackage Groups
     11 */
     12
     13// Exit if accessed directly
     14if ( !defined( 'ABSPATH' ) ) exit;
     15
     16// Include WP's list table class
     17if ( !class_exists( 'WP_List_Table' ) ) require( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
     18
     19// per_page screen option. Has to be hooked in extremely early.
     20if ( is_admin() && ! empty( $_REQUEST['page'] ) && 'bp-groups' == $_REQUEST['page'] )
     21        add_filter( 'set-screen-option', 'bp_groups_admin_screen_options', 10, 3 );
     22
     23/**
     24 * Registers the Groups component admin screen
     25 *
     26 * @since 1.7
     27 */
     28function bp_groups_add_admin_menu() {
     29
     30        if ( ! bp_current_user_can( 'bp_moderate' ) )
     31                return;
     32
     33        // Add our screen
     34        $hook = add_menu_page( __( 'Groups', 'buddypress' ), __( 'Groups', 'buddypress' ), 'manage_options', 'bp-groups', 'bp_groups_admin' );
     35
     36        // Hook into early actions to load custom CSS and our init handler.
     37        add_action( "load-$hook", 'bp_groups_admin_load' );
     38}
     39add_action( bp_core_admin_hook(), 'bp_groups_add_admin_menu' );
     40
     41/**
     42 * Set up the admin page before any output is sent. Register contextual help and screen options for this admin page.
     43 *
     44 * @global object $bp BuddyPress global settings
     45 * @global BP_Groups_List_Table $bp_groups_list_table Groups screen list table
     46 * @since 1.6
     47 */
     48function bp_groups_admin_load() {
     49        global $bp, $bp_groups_list_table;
     50
     51        // Build redirection URL
     52        $redirect_to = remove_query_arg( array( 'action', 'gid', 'deleted', 'error', 'updated', 'success_new', 'error_new', 'success_modified', 'error_modified' ), $_SERVER['REQUEST_URI'] );
     53
     54        // Decide whether to load the dev version of the CSS and JavaScript
     55        $dev = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? 'dev.' : '';
     56
     57        // Decide whether to load the index or edit screen
     58        $doaction = ! empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
     59
     60        // Call an action for plugins to hook in early
     61        do_action( 'bp_groups_admin_load', $doaction );
     62
     63        // Edit screen
     64        if ( 'delete' == $doaction && ! empty( $_GET['gid'] ) ) {
     65
     66                check_admin_referer( 'bp-groups-delete' );
     67
     68                $group_id = (int) $_GET['gid'];
     69
     70                $result = groups_delete_group( $group_id );
     71
     72                if ( $result ) {
     73                        $redirect_to = add_query_arg( 'deleted', '1', $redirect_to );
     74                } else {
     75                        $redirect_to = add_query_arg( array(
     76                                'deleted' => 0,
     77                                'action'  => 'edit',
     78                                'gid'     => $group_id
     79                        ) );
     80                }
     81
     82                bp_core_redirect( $redirect_to );
     83
     84        } else if ( 'edit' == $doaction && ! empty( $_GET['gid'] ) ) {
     85                // columns screen option
     86                add_screen_option( 'layout_columns', array( 'default' => 2, 'max' => 2, ) );
     87
     88                get_current_screen()->add_help_tab( array(
     89                        'id'      => 'bp-activity-edit-overview',
     90                        'title'   => __( 'Overview', 'buddypress' ),
     91                        'content' =>
     92                                '<p>' . __( 'This page is a convenient way to edit the details associated with one of your groups.', 'buddypress' ) . '</p>' .
     93                                '<p>' . __( 'The Name and Description boxes are fixed in place, but you can reposition all the other boxes using drag and drop, and can minimize or expand them by clicking the title bar of each box. Use the Screen Options tab to hide or unhide, or to choose a 1- or 2-column layout for this screen.', 'buddypress' ) . '</p>'
     94                ) );
     95
     96                get_current_screen()->add_help_tab( array(
     97                        'id'      => 'bp-activity-edit-advanced',
     98                        'title'   => __( 'Item, Link, Type', 'buddypress' ),
     99                        'content' =>
     100                                '<p>' . __( '<strong>Primary Item/Secondary Item</strong> - These identify the object that created the activity. For example, the fields could reference a comment left on a specific site. Some types of activity may only use one, or none, of these fields.', 'buddypress' ) . '</p>' .
     101                                '<p>' . __( '<strong>Link</strong> - Activity generated by blog posts and comments, forum topics and replies, and some plugins, uses the link field for a permalink back to the content item. Some types of activity may not use this field, even if it has been set.', 'buddypress' ) . '</p>' .
     102                                '<p>' . __( '<strong>Type</strong> - Each distinct kind of activity has its own type. For example, <code>created_group</code> is used when a group is created and <code>joined_group</code> is used when a user joins a group.', 'buddypress' ) . '</p>' .
     103                                '<p>' . __( 'For information about when and how BuddyPress uses all of these settings, see the Managing Activity link in the panel to the side.', 'buddypress' ) . '</p>'
     104                ) );
     105
     106                // Help panel - sidebar links
     107                get_current_screen()->set_help_sidebar(
     108                        '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
     109                        '<p>' . __( '<a href="http://codex.buddypress.org/buddypress-site-administration/managing-activity/">Managing Activity</a>', 'buddypress' ) . '</p>' .
     110                        '<p>' . __( '<a href="http://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
     111                );
     112
     113                // Register metaboxes for the edit screen.
     114                add_meta_box( 'submitdiv',            _x( 'Save', 'activity admin edit screen', 'buddypress' ), 'bp_groups_admin_edit_metabox_status', get_current_screen()->id, 'side', 'core' );
     115                add_meta_box( 'bp_group_settings',    _x( 'Settings', 'group admin edit screen', 'buddypress' ), 'bp_groups_admin_edit_metabox_settings', get_current_screen()->id, 'side', 'core' );
     116                add_meta_box( 'bp_group_add_members', _x( 'Add New Members', 'group admin edit screen', 'buddypress' ), 'bp_groups_admin_edit_metabox_add_new_members', get_current_screen()->id, 'normal', 'core' );
     117                add_meta_box( 'bp_group_members',     _x( 'Manage Members', 'group admin edit screen', 'buddypress' ), 'bp_groups_admin_edit_metabox_members', get_current_screen()->id, 'normal', 'core' );
     118
     119                // Enqueue javascripts
     120                wp_enqueue_script( 'postbox' );
     121                wp_enqueue_script( 'dashboard' );
     122                wp_enqueue_script( 'comment' );
     123
     124        // Index screen
     125        } else {
     126                // Create the Activity screen list table
     127                $bp_groups_list_table = new BP_Groups_List_Table();
     128
     129                // per_page screen option
     130                add_screen_option( 'per_page', array( 'label' => _x( 'Groups', 'Groups per page (screen options)', 'buddypress' )) );
     131
     132                // Help panel - overview text
     133                get_current_screen()->add_help_tab( array(
     134                        'id'      => 'bp-groups-overview',
     135                        'title'   => __( 'Overview', 'buddypress' ),
     136                        'content' =>
     137                                '<p>' . __( 'You can manage activities made on your site similar to the way you manage comments and other content. This screen is customizable in the same ways as other management screens, and you can act on activities using the on-hover action links or the Bulk Actions.', 'buddypress' ) . '</p>' .
     138                                '<p>' . __( 'There are many different types of activities. Some are generated automatically by BuddyPress and other plugins, and some are entered directly by a user in the form of status update. To help manage the different activity types, use the filter dropdown box to switch between them.', 'buddypress' ) . '</p>'
     139                ) );
     140
     141                // Help panel - moderation text
     142                get_current_screen()->add_help_tab( array(
     143                        'id'            => 'bp-activity-moderating',
     144                        'title'         => __( 'Moderating Activity', 'buddypress' ),
     145                        'content'       =>
     146                                '<p>' . __( 'In the <strong>Activity</strong> column, above each activity it says &#8220;Submitted on,&#8221; followed by the date and time the activity item was generated on your site. Clicking on the date/time link will take you to that activity on your live site. Hovering over any activity gives you options to reply, edit, spam mark, or delete that activity.', 'buddypress' ) . '</p>' .
     147                                '<p>' . __( "In the <strong>In Response To</strong> column, if the activity was in reply to another activity, it shows that activity's author's picture and name, and a link to that activity on your live site. If there is a small bubble, the number in it shows how many other activities are related to this one; these are usually comments. Clicking the bubble will filter the activity screen to show only related activity items.", 'buddypress' ) . '</p>'
     148                ) );
     149
     150                // Help panel - sidebar links
     151                get_current_screen()->set_help_sidebar(
     152                        '<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
     153                        '<p>' . __( '<a href="http://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
     154                );
     155        }
     156
     157        // Enqueue CSS and JavaScript
     158        wp_enqueue_script( 'bp_groups_admin_js', BP_PLUGIN_URL . "bp-groups/admin/js/admin.{$dev}js", array( 'jquery', 'wp-ajax-response', 'jquery-ui-autocomplete' ), bp_get_version(), true );
     159        wp_enqueue_style( 'bp_groups_admin_css', BP_PLUGIN_URL . "bp-groups/admin/css/admin.{$dev}css", array(), bp_get_version() );
     160
     161        if ( $doaction && 'save' == $doaction ) {
     162                // Get activity ID
     163                $group_id = isset( $_REQUEST['gid'] ) ? (int) $_REQUEST['gid'] : '';
     164
     165                $redirect_to = add_query_arg( array(
     166                        'gid'    => (int) $group_id,
     167                        'action' => 'edit'
     168                ), $redirect_to );
     169
     170                // Check this is a valid form submission
     171                check_admin_referer( 'edit-group_' . $group_id );
     172
     173                // Get the group from the database
     174                $group = groups_get_group( 'group_id=' . $group_id );
     175
     176                // If the group doesn't exist, just redirect back to the index
     177                if ( empty( $group->slug ) ) {
     178                        wp_redirect( $redirect_to );
     179                        exit;
     180                }
     181
     182                // Check the form for the updated properties
     183
     184                // Store errors
     185                $error = 0;
     186                $success_new = $error_new = $success_modified = $error_modified = array();
     187
     188                // Group name and description are handled with
     189                // groups_edit_base_group_details()
     190                if ( !groups_edit_base_group_details( $group_id, $_POST['bp-groups-name'], $_POST['bp-groups-description'], 0 ) ) {
     191                        $error = $group_id;
     192                }
     193
     194                // Enable discussion forum
     195                $enable_forum   = ( isset( $_POST['group-show-forum'] ) ) ? 1 : 0;
     196
     197                // Privacy setting
     198                $allowed_status = apply_filters( 'groups_allowed_status', array( 'public', 'private', 'hidden' ) );
     199                $status         = ( in_array( $_POST['group-status'], (array) $allowed_status ) ) ? $_POST['group-status'] : 'public';
     200
     201                // Invite status
     202                $allowed_invite_status = apply_filters( 'groups_allowed_invite_status', array( 'members', 'mods', 'admins' ) );
     203                $invite_status         = in_array( $_POST['group-invite-status'], (array) $allowed_invite_status ) ? $_POST['group-invite-status'] : 'members';
     204
     205                if ( !groups_edit_group_settings( $group_id, $enable_forum, $status, $invite_status ) ) {
     206                        $error = $group_id;
     207                }
     208
     209                // Process new members
     210                $user_names = array();
     211
     212                if ( ! empty( $_POST['bp-groups-new-members'] ) ) {
     213                        $user_names = array_merge( $user_names, explode( ',', $_POST['bp-groups-new-members'] ) );
     214                }
     215
     216                if ( ! empty( $_POST['new_members'] ) ) {
     217                        $user_names = array_merge( $user_names, $_POST['new_members'] );
     218                }
     219
     220                if ( ! empty( $user_names ) ) {
     221
     222                        foreach( $user_names as $user_key => $user_name ) {
     223                                $un = trim( $user_name );
     224
     225                                // Make sure the user exists before attempting
     226                                // to add to the group
     227                                if ( ! $user_id = username_exists( $un ) ) {
     228                                        $error_new[]   = $un;
     229                                } else if ( ! groups_join_group( $group_id, $user_id ) ) {
     230                                        $error_new[]   = $un;
     231                                } else {
     232                                        $success_new[] = $un;
     233                                }
     234                        }
     235                }
     236
     237                // Process member role changes
     238                if ( ! empty( $_POST['bp-groups-role'] ) && ! empty( $_POST['bp-groups-existing-role'] ) ) {
     239
     240                        // Before processing anything, make sure you're not
     241                        // attempting to remove the all user admins
     242                        $admin_count = 0;
     243                        foreach ( (array) $_POST['bp-groups-role'] as $new_role ) {
     244                                if ( 'admin' == $new_role ) {
     245                                        $admin_count++;
     246                                        break;
     247                                }
     248                        }
     249
     250                        if ( ! $admin_count ) {
     251                                $redirect_to = add_query_arg( 'no_admins', 1, $redirect_to );
     252                                bp_core_redirect( $redirect_to );
     253                        }
     254
     255                        // Process only those users who have had their roles changed
     256                        foreach ( (array) $_POST['bp-groups-role'] as $user_id => $new_role ) {
     257
     258                                $existing_role = isset( $_POST['bp-groups-existing-role'][$user_id] ) ? $_POST['bp-groups-existing-role'][$user_id] : '';
     259
     260                                if ( $existing_role != $new_role ) {
     261
     262                                        switch ( $new_role ) {
     263                                                case 'mod' :
     264                                                        // Admin to mod is a demotion. Demote to
     265                                                        // member, then fall through
     266                                                        if ( 'admin' == $existing_role ) {
     267                                                                groups_demote_member( $user_id, $group_id );
     268                                                        }
     269
     270                                                case 'admin' :
     271                                                        // If the user was banned, we must
     272                                                        // unban first
     273                                                        if ( 'banned' == $existing_role ) {
     274                                                                groups_unban_member( $user_id, $group_id );
     275                                                        }
     276
     277                                                        // At this point, each existing_role
     278                                                        // is a member, so promote
     279                                                        $result = groups_promote_member( $user_id, $group_id, $new_role );
     280
     281                                                        break;
     282
     283                                                case 'member' :
     284
     285                                                        if ( 'admin' == $existing_role || 'mod' == $existing_role ) {
     286                                                                $result = groups_demote_member( $user_id, $group_id );
     287                                                        } else if ( 'banned' == $existing_role ) {
     288                                                                $result = groups_unban_member( $user_id, $group_id );
     289                                                        }
     290
     291                                                        break;
     292
     293                                                case 'banned' :
     294
     295                                                        $result = groups_ban_member( $user_id, $group_id );
     296
     297                                                        break;
     298
     299                                                case 'remove' :
     300
     301                                                        $result = groups_remove_member( $user_id, $group_id );
     302
     303                                                        break;
     304                                        }
     305
     306                                        // Store the success or failure
     307                                        if ( $result ) {
     308                                                $success_modified[] = $user_id;
     309                                        } else {
     310                                                $error_modified[]   = $user_id;
     311                                        }
     312                                }
     313                        }
     314                }
     315
     316                // Call actions for plugins to do something before we redirect
     317                do_action_ref_array( 'bp_group_admin_edit_after', array( &$group, $error, $error_new, $success_new, $error_modified, $success_modified ) );
     318
     319                // Create the redirect URL
     320
     321                if ( $error ) {
     322                        // This means there was an error updating group details
     323                        $redirect_to = add_query_arg( 'error', (int) $error, $redirect_to );
     324                } else {
     325                        // Group details were update successfully
     326                        $redirect_to = add_query_arg( 'updated', 1, $redirect_to );
     327                }
     328
     329                if ( !empty( $success_new ) ) {
     330                        $success_new = implode( ',', array_filter( $success_new, 'urlencode' ) );
     331                        $redirect_to = add_query_arg( 'success_new', $success_new, $redirect_to );
     332                }
     333
     334                if ( !empty( $error_new ) ) {
     335                        $error_new = implode( ',', array_filter( $error_new, 'urlencode' ) );
     336                        $redirect_to = add_query_arg( 'error_new', $error_new, $redirect_to );
     337                }
     338
     339                if ( !empty( $success_modified ) ) {
     340                        $success_modified = implode( ',', array_filter( $success_modified, 'urlencode' ) );
     341                        $redirect_to = add_query_arg( 'success_modified', $success_modified, $redirect_to );
     342                }
     343
     344                if ( !empty( $error_modified ) ) {
     345                        $error_modified = implode( ',', array_filter( $error_modified, 'urlencode' ) );
     346                        $redirect_to = add_query_arg( 'error_modified', $error_modified, $redirect_to );
     347                }
     348
     349                // Redirect
     350                wp_redirect( apply_filters( 'bp_group_admin_edit_redirect', $redirect_to ) );
     351                exit;
     352
     353
     354        // If a referrer and a nonce is supplied, but no action, redirect back.
     355        } elseif ( ! empty( $_GET['_wp_http_referer'] ) ) {
     356                wp_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), stripslashes( $_SERVER['REQUEST_URI'] ) ) );
     357                exit;
     358        }
     359}
     360
     361/**
     362 * Outputs the Groups component admin screens
     363 *
     364 * @since 1.7
     365 */
     366function bp_groups_admin() {
     367        // Decide whether to load the index or edit screen
     368        $doaction = ! empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
     369
     370        // Display the single activity edit screen
     371        if ( 'edit' == $doaction && ! empty( $_GET['gid'] ) ) {
     372                bp_groups_admin_edit();
     373
     374        // Otherwise, display the Activity index screen
     375        } else {
     376                bp_groups_admin_index();
     377        }
     378}
     379
     380/**
     381 * Display the single groups edit screen
     382 *
     383 * @global int $screen_layout_columns Number of columns shown on this admin page
     384 * @since 1.7
     385 */
     386function bp_groups_admin_edit() {
     387        global $screen_layout_columns;
     388
     389        // @todo: Check if user is allowed to edit activity items
     390        // if ( ! current_user_can( 'bp_edit_activity' ) )
     391        if ( ! is_super_admin() )
     392                die( '-1' );
     393
     394        $messages = array();
     395
     396        // If the user has just made a change to a group, build status messages
     397        if ( !empty( $_REQUEST['no_admins'] ) || ! empty( $_REQUEST['error'] ) || ! empty( $_REQUEST['updated'] ) || ! empty( $_REQUEST['error_new'] ) || ! empty( $_REQUEST['success_new'] ) || ! empty( $_REQUEST['error_modified'] ) || ! empty( $_REQUEST['success_modified'] ) ) {
     398                $no_admins        = ! empty( $_REQUEST['no_admins']        ) ? 1                                             : 0;
     399                $errors           = ! empty( $_REQUEST['error']            ) ? $_REQUEST['error']                            : '';
     400                $updated          = ! empty( $_REQUEST['updated']          ) ? $_REQUEST['updated']                          : '';
     401                $error_new        = ! empty( $_REQUEST['error_new']        ) ? explode( ',', $_REQUEST['error_new'] )        : array();
     402                $success_new      = ! empty( $_REQUEST['success_new']      ) ? explode( ',', $_REQUEST['success_new'] )      : array();
     403                $error_modified   = ! empty( $_REQUEST['error_modified']   ) ? explode( ',', $_REQUEST['error_modified'] )   : array();
     404                $success_modified = ! empty( $_REQUEST['success_modified'] ) ? explode( ',', $_REQUEST['success_modified'] ) : array();
     405
     406                if ( ! empty( $no_admins ) ) {
     407                        $messages[] = __( 'You cannot remove all administrators from a group.', 'buddypress' );
     408                }
     409
     410                if ( ! empty( $errors ) ) {
     411                        $messages[] = __( 'An error occurred when trying to update your group details.', 'buddypress' );
     412                } else if ( ! empty( $updated ) ) {
     413                        $messages[] = __( 'The group has been updated successfully.', 'buddypress' );
     414                }
     415
     416                if ( ! empty( $error_new ) ) {
     417                        $messages[] = sprintf( __( 'The following users could not be added to the group: <em>%s</em>', 'buddypress' ), implode( ', ', $error_new ) );
     418                }
     419
     420                if ( ! empty( $success_new ) ) {
     421                        $messages[] = sprintf( __( 'The following users were successfully added to the group: <em>%s</em>', 'buddypress' ), implode( ', ', $success_new ) );
     422                }
     423
     424                if ( ! empty( $error_modified ) ) {
     425                        $error_modified = bp_groups_admin_get_usernames_from_ids( $error_modified );
     426                        $messages[] = sprintf( __( 'An error occurred when trying to modify the following members: <em>%s</em>', 'buddypress' ), implode( ', ', $error_modified ) );
     427                }
     428
     429                if ( ! empty( $success_modified ) ) {
     430                        $success_modified = bp_groups_admin_get_usernames_from_ids( $success_modified );
     431                        $messages[] = sprintf( __( 'The following members were successfully modified: <em>%s</em>', 'buddypress' ), implode( ', ', $success_modified ) );
     432                }
     433        }
     434
     435        $is_error = ! empty( $no_admins ) || ! empty( $errors ) || ! empty( $error_new ) || ! empty( $error_modified );
     436
     437        // Get the activity from the database
     438        $group      = groups_get_group( 'group_id=' . $_GET['gid'] );
     439        $group_name = isset( $group->name ) ? apply_filters( 'bp_get_group_name', $group->name ) : '';
     440
     441        // Construct URL for form
     442        $form_url = remove_query_arg( array( 'action', 'deleted', 'no_admins', 'error', 'error_new', 'success_new', 'error_modified', 'success_modified' ), $_SERVER['REQUEST_URI'] );
     443        $form_url = add_query_arg( 'action', 'save', $form_url );
     444
     445        // Call an action for plugins to modify the group before we display the edit form
     446        do_action_ref_array( 'bp_groups_admin_edit', array( &$group ) );
     447?>
     448
     449        <div class="wrap">
     450                <?php screen_icon( 'buddypress-groups' ); ?>
     451                <h2><?php printf( __( 'Editing <em>%s</em> (ID #%s)', 'buddypress' ), $group_name, number_format_i18n( (int) $_REQUEST['gid'] ) ); ?></h2>
     452
     453                <?php // If the user has just made a change to an group, display the status messages ?>
     454                <?php if ( !empty( $messages ) ) : ?>
     455                        <div id="moderated" class="<?php echo ( $is_error ) ? 'error' : 'updated'; ?>"><p><?php echo implode( "<br/>\n", $messages ); ?></p></div>
     456                <?php endif; ?>
     457
     458                <?php if ( ! empty( $group ) ) : ?>
     459
     460                        <form action="<?php echo esc_attr( $form_url ); ?>" id="bp-groups-edit-form" method="post">
     461                                <div id="poststuff">
     462
     463                                        <div id="post-body" class="metabox-holder columns-<?php echo 1 == get_current_screen()->get_columns() ? '1' : '2'; ?>">
     464                                                <div id="post-body-content">
     465                                                        <div id="postdiv" class="postarea">
     466                                                                <div id="bp_groups_name" class="postbox">
     467                                                                        <h3><?php _e( 'Name', 'buddypress' ); ?></h3>
     468                                                                        <div class="inside">
     469                                                                                <input type="text" name="bp-groups-name" id="bp-groups-name" value="<?php echo esc_attr( stripslashes( $group_name ) ) ?>" />
     470                                                                        </div>
     471                                                                </div>
     472
     473                                                                <div id="bp_groups_description" class="postbox">
     474                                                                        <h3><?php _e( 'Description', 'buddypress' ); ?></h3>
     475                                                                        <div class="inside">
     476                                                                                <?php wp_editor( stripslashes( $group->description ), 'bp-groups-description', array( 'media_buttons' => false, 'teeny' => true, 'textarea_rows' => 5, 'quicktags' => array( 'buttons' => 'strong,em,link,block,del,ins,img,code,spell,close' ) ) ); ?>
     477                                                                        </div>
     478                                                                </div>
     479                                                        </div>
     480                                                </div><!-- #post-body-content -->
     481
     482                                                <div id="postbox-container-1" class="postbox-container">
     483                                                        <?php do_meta_boxes( get_current_screen()->id, 'side', $group ); ?>
     484                                                </div>
     485
     486                                                <div id="postbox-container-2" class="postbox-container">
     487                                                        <?php do_meta_boxes( get_current_screen()->id, 'normal', $group ); ?>
     488                                                        <?php do_meta_boxes( get_current_screen()->id, 'advanced', $group ); ?>
     489                                                </div>
     490                                        </div><!-- #post-body -->
     491
     492                                </div><!-- #poststuff -->
     493                                <?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
     494                                <?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?>
     495                                <?php wp_nonce_field( 'edit-group_' . $group->id ); ?>
     496                        </form>
     497
     498                <?php else : ?>
     499                        <p><?php printf( __( 'No group found with this ID. <a href="%s">Go back and try again</a>.', 'buddypress' ), network_admin_url( 'admin.php?page=bp-groups' ) ); ?></p>
     500                <?php endif; ?>
     501
     502        </div><!-- .wrap -->
     503
     504<?php
     505}
     506
     507/**
     508 * Display the Groups admin index screen, which contains a list of all your
     509 * BuddyPress groups.
     510 *
     511 * @global BP_Activity_List_Table $bp_groups_list_table Activity screen list table
     512 * @global string $plugin_page
     513 * @since 1.7
     514 */
     515function bp_groups_admin_index() {
     516        global $bp_groups_list_table, $plugin_page;
     517
     518        $messages = array();
     519
     520        // If the user has just made a change to a group, build status messages
     521        if ( ! empty( $_REQUEST['deleted'] ) ) {
     522                $deleted  = ! empty( $_REQUEST['deleted'] ) ? (int) $_REQUEST['deleted'] : 0;
     523
     524                if ( $deleted > 0 ) {
     525                        $messages[] = sprintf( _n( '%s activity has been permanently deleted.', '%s activity items have been permanently deleted.', $deleted, 'buddypress' ), number_format_i18n( $deleted ) );
     526                }
     527
     528        }
     529
     530        // Prepare the activity items for display
     531        $bp_groups_list_table->prepare_items();
     532
     533        // Call an action for plugins to modify the messages before we display the edit form
     534        do_action( 'bp_groups_admin_index', $messages );
     535?>
     536
     537        <div class="wrap">
     538                <?php screen_icon( 'buddypress-groups' ); ?>
     539                <h2>
     540                        <?php _e( 'Groups', 'buddypress' ); ?>
     541
     542                        <?php if ( !empty( $_REQUEST['s'] ) ) : ?>
     543                                <span class="subtitle"><?php printf( __( 'Search results for &#8220;%s&#8221;', 'buddypress' ), wp_html_excerpt( esc_html( stripslashes( $_REQUEST['s'] ) ), 50 ) ); ?></span>
     544                        <?php endif; ?>
     545                </h2>
     546
     547                <?php // If the user has just made a change to an group, display the status messages ?>
     548                <?php if ( !empty( $messages ) ) : ?>
     549                        <div id="moderated" class="<?php echo ( ! empty( $_REQUEST['error'] ) ) ? 'error' : 'updated'; ?>"><p><?php echo implode( "<br/>\n", $messages ); ?></p></div>
     550                <?php endif; ?>
     551
     552                <?php // Display each group on its own row ?>
     553                <?php $bp_groups_list_table->views(); ?>
     554
     555                <form id="bp-groups-form" action="" method="get">
     556                        <?php $bp_groups_list_table->search_box( __( 'Search all Groups', 'buddypress' ), 'bp-groups' ); ?>
     557                        <input type="hidden" name="page" value="<?php echo esc_attr( $plugin_page ); ?>" />
     558                        <?php $bp_groups_list_table->display(); ?>
     559                </form>
     560
     561        </div>
     562
     563<?php
     564}
     565
     566/**
     567 * Settings metabox
     568 *
     569 * @param object $item Group item
     570 * @since 1.7
     571 */
     572function bp_groups_admin_edit_metabox_settings( $item ) {
     573        $invite_status = groups_get_groupmeta( $item->id, 'invite_status' );
     574
     575?>
     576
     577        <div class="bp-groups-settings-section" id="bp-groups-settings-section-forum">
     578                <label for="group-show-forum"><input type="checkbox" name="group-show-forum" id="group-show-forum" <?php checked( $item->enable_forum ) ?> /> <?php _e( 'Enable discussion forum', 'buddypress' ) ?><br />
     579        </div>
     580
     581        <div class="bp-groups-settings-section" id="bp-groups-settings-section-status">
     582                <label for="group-status"><?php _e( 'Privacy', 'buddypress' ); ?></label>
     583
     584                <ul>
     585                        <li><input type="radio" name="group-status" id="bp-group-status-public" value="public" <?php checked( $item->status, 'public' ) ?> /> <?php _e( 'Public', 'buddypress' ) ?></li>
     586                        <li><input type="radio" name="group-status" id="bp-group-status-private" value="private" <?php checked( $item->status, 'private' ) ?> /> <?php _e( 'Private', 'buddypress' ) ?></li>
     587                        <li><input type="radio" name="group-status" id="bp-group-status-hidden" value="hidden" <?php checked( $item->status, 'hidden' ) ?> /> <?php _e( 'Hidden', 'buddypress' ) ?></li>
     588        </div>
     589
     590        <div class="bp-groups-settings-section" id="bp-groups-settings-section-invite-status">
     591                <label for="group-invite-status"><?php _e( 'Who can invite others to this group?', 'buddypress' ); ?></label>
     592
     593                <ul>
     594                        <li><input type="radio" name="group-invite-status" id="bp-group-invite-status-members" value="members" <?php checked( $invite_status, 'members' ) ?> /> <?php _e( 'All group members', 'buddypress' ) ?></li>
     595                        <li><input type="radio" name="group-invite-status" id="bp-group-invite-status-mods" value="mods" <?php checked( $invite_status, 'mods' ) ?> /> <?php _e( 'Group admins and mods only', 'buddypress' ) ?></li>
     596                        <li><input type="radio" name="group-invite-status" id="bp-group-invite-status-admins" value="admins" <?php checked( $invite_status, 'admins' ) ?> /> <?php _e( 'Group admins only', 'buddypress' ) ?></li>
     597                </ul>
     598        </div>
     599
     600<?php
     601}
     602
     603/**
     604 * Add New Members metabox
     605 *
     606 * @since 1.7
     607 */
     608function bp_groups_admin_edit_metabox_add_new_members( $item ) {
     609        ?>
     610
     611        <input name="bp-groups-new-members" id="bp-groups-new-members" class="bp-suggest-user" />
     612        <p id="bp-groups-new-members-help-nojs" class="description"><?php _e( 'Enter a comma-separated list of user logins.', 'buddypress' ); ?></p>
     613        <p id="bp-groups-new-members-help-js" class="description"><?php _e( 'Start typing the username of the member you want to add.', 'buddypress' ); ?></p>
     614        <ul id="bp-groups-new-members-list"></ul>
     615        <?php
     616}
     617
     618/**
     619 * Members metabox
     620 *
     621 * @since 1.7
     622 */
     623function bp_groups_admin_edit_metabox_members( $item ) {
     624        global $members_template;
     625
     626        // Pull up a list of group members, so we can separate out the types
     627        // We'll also keep track of group members here to place them into a
     628        // javascript variable, which will help with group member autocomplete
     629        $member_ids = array();
     630        $members = array(
     631                'admin'  => array(),
     632                'mod'    => array(),
     633                'member' => array(),
     634                'banned' => array()
     635        );
     636
     637        if ( bp_group_has_members( array(
     638                'group_id' => $item->id,
     639                'exclude_admins_mods' => false,
     640                'exclude_banned' => false
     641        ) ) ) {
     642                // Get a list of admins and mods, to reduce lookups
     643                // We'll rekey them by user_id for convenience
     644                $admins = $mods = array();
     645
     646                foreach ( (array) groups_get_group_admins( $item->id ) as $admin_obj ) {
     647                        $admins[$admin_obj->user_id] = $admin_obj;
     648                }
     649
     650                foreach ( (array) groups_get_group_mods( $item->id ) as $admin_obj ) {
     651                        $mods[$admin_obj->user_id] = $admin_obj;
     652                }
     653
     654                while ( bp_group_members() ) {
     655                        bp_group_the_member();
     656                        if ( bp_get_group_member_is_banned() ) {
     657                                $members['banned'][] = $members_template->member;
     658                        } else if ( isset( $admins[ bp_get_group_member_id() ] ) ) {
     659                                $members['admin'][]  = $members_template->member;
     660                        } else if ( isset( $mods[ bp_get_group_member_id() ] ) ) {
     661                                $members['mod'][]    = $members_template->member;
     662                        } else {
     663                                $members['member'][] = $members_template->member;
     664                        }
     665
     666                        $member_ids[] = bp_get_group_member_id();
     667                }
     668        }
     669
     670        // Echo out the javascript variable
     671        $member_ids = ! empty( $member_ids ) ? implode( ',', $member_ids ) : '';
     672        echo '<script type="text/javascript">var group_members = "' . $member_ids . '";</script>';
     673
     674        // Loop through each member type
     675        foreach ( $members as $member_type => $type_users ) : ?>
     676
     677                <div class="bp-groups-member-type" id="bp-groups-member-type-<?php echo esc_attr( $member_type ) ?>">
     678
     679                        <h4>
     680                                <?php switch ( $member_type ) :
     681                                        case 'admin'  : _e( 'Administrators', 'buddypress' ); break;
     682                                        case 'mod'    : _e( 'Moderators',     'buddypress' ); break;
     683                                        case 'member' : _e( 'Members',        'buddypress' ); break;
     684                                        case 'banned' : _e( 'Banned Users',   'buddypress' ); break;
     685                                endswitch; ?>
     686                        </h4>
     687
     688                <?php if ( !empty( $type_users ) ) : ?>
     689
     690                        <table class="widefat bp-group-members">
     691                                <thead>
     692                                <tr>
     693                                        <th scope="col" class="uid-column"><?php _ex( 'ID', 'Group member user_id in group admin', 'buddypress' ) ?></th>
     694                                        <th scope="col" class="uname-column"><?php _ex( 'Name', 'Group member name in group admin', 'buddypress' ) ?></th>
     695                                        <th scope="col" class="urole-column"><?php _ex( 'Group Role', 'Group member role in group admin', 'buddypress' ) ?></th>
     696                                </tr>
     697                                </thead>
     698
     699                                <tbody>
     700                                <?php foreach ( $type_users as $type_user ) : ?>
     701                                        <?php $user_link = bp_core_get_user_domain( $type_user->user_id ); ?>
     702                                        <tr>
     703                                                <th scope="row" class="uid-column"><?php echo $type_user->user_id ?></th>
     704
     705                                                <td class="uname-column">
     706                                                        <a href="<?php echo $user_link ?>"><?php echo bp_core_fetch_avatar( array(
     707                                                                        'item_id' => $type_user->user_id,
     708                                                                        'width'   => '32',
     709                                                                        'height'  => '32'
     710                                                        ) ) ?></a>
     711
     712                                                        <?php echo bp_core_get_userlink( $type_user->user_id ) ?>
     713                                                </td>
     714
     715                                                <td class="urole-column">
     716                                                        <select class="bp-groups-role" id="bp-groups-role-<?php echo $type_user->user_id ?>" name="bp-groups-role[<?php echo $type_user->user_id ?>]">
     717                                                                <option value="admin" <?php selected( 'admin', $member_type ) ?>><?php _e( 'Administrator', 'buddypress' ) ?></option>
     718                                                                <option value="mod" <?php selected( 'mod', $member_type ) ?>><?php _e( 'Moderator', 'buddypress' ) ?></option>
     719                                                                <option value="member" <?php selected( 'member', $member_type ) ?>><?php _e( 'Member', 'buddypress' ) ?></option>
     720                                                                <option class="banned" value="banned" <?php selected( 'banned', $member_type ) ?>><?php _e( 'Banned', 'buddypress' ) ?></option>
     721                                                                <option class="remove" value="remove"><?php _e( 'Remove From Group', 'buddypress' ) ?></option>
     722                                                        </select>
     723
     724                                                        <?php /* Store the current role for this user, so we can easily detect changes */ ?>
     725                                                        <input type="hidden" name="bp-groups-existing-role[<?php echo $type_user->user_id ?>]" value="<?php echo $member_type ?>" />
     726                                                </td>
     727                                        </tr>
     728                                <?php endforeach; ?>
     729                                </tbody>
     730                        </table>
     731
     732                <?php else : ?>
     733
     734                        <p class="bp-groups-no-members description"><?php _e( 'No members of this type', 'buddypress' ) ?></p>
     735
     736                <?php endif; ?>
     737
     738                </div><!-- .bp-groups-member-type -->
     739
     740        <?php endforeach;
     741
     742}
     743
     744/**
     745 * Status metabox for the Groups admin edit screen
     746 *
     747 * @param object $item Group item
     748 * @since 1.7
     749 */
     750function bp_groups_admin_edit_metabox_status( $item ) {
     751        $base_url = add_query_arg( array(
     752                'page' => 'bp-groups',
     753                'gid'  => $item->id
     754        ), is_network_admin() ? network_admin_url( 'admin.php' ) : admin_url( 'admin.php' ) );
     755?>
     756        <div id="submitcomment" class="submitbox">
     757                <div id="major-publishing-actions">
     758                        <div id="delete-action">
     759                                <a onclick="javascript:return confirm('<?php echo esc_js( __( 'Are you sure?', 'buddypress' ) ) ?>');" class="submitdelete deletion" href="<?php echo wp_nonce_url( add_query_arg( 'action', 'delete', $base_url ), 'bp-groups-delete' ) ?>"><?php _e( 'Delete', 'buddypress' ) ?></a>
     760                        </div>
     761
     762                        <div id="publishing-action">
     763                                <?php submit_button( __( 'Save Changes', 'buddypress' ), 'primary', 'save', false, array( 'tabindex' => '4' ) ); ?>
     764                        </div>
     765                        <div class="clear"></div>
     766                </div><!-- #major-publishing-actions -->
     767
     768        </div><!-- #submitcomment -->
     769
     770<?php
     771}
     772
     773/**
     774 * Match a set of user ids up to a set of usernames
     775 *
     776 * @since 1.7
     777 */
     778function bp_groups_admin_get_usernames_from_ids( $user_ids ) {
     779        $usernames = array();
     780
     781        $users = new WP_User_Query( array( 'blog_id' => 0, 'include' => $user_ids ) );
     782        foreach ( $users->results as $user ) {
     783                $usernames[] = $user->user_login;
     784        }
     785
     786        return $usernames;
     787}
     788
     789/**
     790 * AJAX handler for group member autocomplete requests
     791 *
     792 * @since 1.7
     793 */
     794function bp_groups_admin_autocomplete_handler() {
     795        if ( ! current_user_can( 'bp_moderate' ) || is_multisite() && wp_is_large_network( 'users' ) )
     796                wp_die( -1 );
     797
     798        $return = array();
     799
     800        // Exclude current group members
     801        $group_members = isset( $_REQUEST['group_members'] ) ? wp_parse_id_list( $_REQUEST['group_members'] ) : array();
     802
     803        $users = get_users( array(
     804                'blog_id' => false,
     805                'search'  => '*' . $_REQUEST['term'] . '*',
     806                'exclude' => $group_members,
     807                'search_columns' => array( 'user_login', 'user_nicename', 'user_email', 'display_name' ),
     808                'number'  => 10
     809        ) );
     810
     811        foreach ( $users as $user ) {
     812                $return[] = array(
     813                        /* translators: 1: user_login, 2: user_email */
     814                        'label' => sprintf( __( '%1$s (%2$s)' ), $user->user_login, $user->user_email ),
     815                        'value' => $user->user_login,
     816                );
     817        }
     818
     819        wp_die( json_encode( $return ) );
     820}
     821add_action( 'wp_ajax_bp_group_admin_member_autocomplete', 'bp_groups_admin_autocomplete_handler' );
     822
     823/**
     824 * List table class for the Groups component admin page.
     825 *
     826 * @since 1.6
     827 */
     828class BP_Groups_List_Table extends WP_List_Table {
     829        /**
     830         * What type of view is being displayed? e.g. "All", "Pending", "Approved", "Spam"...
     831         *
     832         * @since 1.6
     833        */
     834        public $view = 'all';
     835
     836        /**
     837         * Group counts for each group type
     838         *
     839         * @since 1.6
     840         */
     841        public $group_counts = 0;
     842
     843        /**
     844         * Constructor
     845         *
     846         * @since 1.6
     847         */
     848        public function __construct() {
     849
     850                // Define singular and plural labels, as well as whether we support AJAX.
     851                parent::__construct( array(
     852                        'ajax'     => false,
     853                        'plural'   => 'activities',
     854                        'singular' => 'activity',
     855                ) );
     856        }
     857
     858        /**
     859         * Handle filtering of data, sorting, pagination, and any other data-manipulation required prior to rendering.
     860         *
     861         * @since 1.6
     862         */
     863        function prepare_items() {
     864                global $groups_template;
     865
     866                $screen = get_current_screen();
     867
     868                // Option defaults
     869                $include_id       = false;
     870                $search_terms     = false;
     871                $sort             = 'DESC';
     872
     873                // Set current page
     874                $page = $this->get_pagenum();
     875
     876                // Set per page from the screen options
     877                $per_page = $this->get_items_per_page( str_replace( '-', '_', "{$screen->id}_per_page" ) );
     878
     879                // Sort order. Note: not supported in bp_has_groups()
     880                $order = 'ASC';
     881                if ( !empty( $_REQUEST['order'] ) ) {
     882                        $order = 'desc' == strtolower( $_REQUEST['order'] ) ? 'DESC' : 'ASC';
     883                }
     884
     885                // Order by - default to newest
     886                $type = 'newest';
     887                if ( !empty( $_REQUEST['orderby'] ) ) {
     888                        switch ( $_REQUEST['orderby'] ) {
     889                                case 'name' :
     890                                        $type = 'alphabetical';
     891                                        break;
     892                                case 'id' :
     893                                        $type = 'newest';
     894                                        break;
     895                                case 'members' :
     896                                        $type = 'popular';
     897                                        break;
     898                        }
     899                }
     900
     901                // Are we doing a search?
     902                if ( !empty( $_REQUEST['s'] ) )
     903                        $search_terms = $_REQUEST['s'];
     904
     905                // Check if user has clicked on a specific group (if so, fetch only that group).
     906                if ( !empty( $_REQUEST['gid'] ) )
     907                        $include_id = (int) $_REQUEST['gid'];
     908
     909                // Set the current view
     910                if ( isset( $_GET['group_status'] ) && in_array( $_GET['group_status'], array( 'public', 'private', 'hidden' ) ) ) {
     911                        $this->view = $_GET['group_status'];
     912                }
     913
     914                // We'll use the ids of group types for the 'include' param
     915                $this->group_type_ids = BP_Groups_Group::get_group_type_ids();
     916
     917                $include = false;
     918                if ( 'all' != $this->view && isset( $this->group_type_ids[ $this->view ] ) ) {
     919                        // Pass a dummy array if there are no groups of this type
     920                        $include = ! empty( $this->group_type_ids[ $this->view ] ) ? $this->group_type_ids[ $this->view ] : array( 0 );
     921                }
     922
     923                // Get group type counts for display in the filter tabs
     924                $this->group_counts = array();
     925                foreach ( $this->group_type_ids as $group_type => $group_ids ) {
     926                        $this->group_counts[ $group_type ] = count( $group_ids );
     927                }
     928
     929                // If we're viewing a specific activity, flatten all activites into a single array.
     930                if ( $include_id ) {
     931                        $groups = array( (array) groups_get_group( 'group_id=' . $include_id ) );
     932                } else {
     933                        $groups_args = array(
     934                                'include'  => $include,
     935                                'per_page' => $per_page,
     936                                'page'     => $page,
     937                                'type'     => $type,
     938                                'order'    => $order
     939                        );
     940
     941                        $groups = array();
     942                        if ( bp_has_groups( $groups_args ) ) {
     943                                while ( bp_groups() ) {
     944                                        bp_the_group();
     945                                        $groups[] = (array) $groups_template->group;
     946                                }
     947                        }
     948                }
     949
     950                // Set raw data to display
     951                $this->items = $groups;
     952
     953                // Store information needed for handling table pagination
     954                $this->set_pagination_args( array(
     955                        'per_page'    => $per_page,
     956                        'total_items' => $groups_template->total_group_count,
     957                        'total_pages' => ceil( $groups_template->total_group_count / $per_page )
     958                ) );
     959        }
     960
     961        /**
     962         * Get an array of all the columns on the page
     963         *
     964         * @return array
     965         * @since 1.7
     966         */
     967        function get_column_info() {
     968                $this->_column_headers = array(
     969                        $this->get_columns(),
     970                        array(),
     971                        $this->get_sortable_columns(),
     972                );
     973
     974                return $this->_column_headers;
     975        }
     976
     977        /**
     978         * Displays a message on screen when no items are found (e.g. no search matches)
     979         *
     980         * @since 1.7
     981         */
     982        function no_items() {
     983                _e( 'No groups found.', 'buddypress' );
     984        }
     985
     986        /**
     987         * Outputs the Groups data table
     988         *
     989         * @since 1.7
     990        */
     991        function display() {
     992                extract( $this->_args );
     993
     994                $this->display_tablenav( 'top' );
     995        ?>
     996
     997                <table class="<?php echo implode( ' ', $this->get_table_classes() ); ?>" cellspacing="0">
     998                        <thead>
     999                                <tr>
     1000                                        <?php $this->print_column_headers(); ?>
     1001                                </tr>
     1002                        </thead>
     1003
     1004                        <tfoot>
     1005                                <tr>
     1006                                        <?php $this->print_column_headers( false ); ?>
     1007                                </tr>
     1008                        </tfoot>
     1009
     1010                        <tbody id="the-comment-list">
     1011                                <?php $this->display_rows_or_placeholder(); ?>
     1012                        </tbody>
     1013                </table>
     1014                <?php
     1015
     1016                $this->display_tablenav( 'bottom' );
     1017        }
     1018
     1019        /**
     1020         * Generates content for a single row of the table
     1021         *
     1022         * @param object $item The current item
     1023         * @since 1.7
     1024         */
     1025        function single_row( $item ) {
     1026                static $row_class = '';
     1027                $row_class = ( $row_class == '' ? ' class="alternate"' : '' );
     1028
     1029                echo '<tr' . $row_class . ' id="activity-' . esc_attr( $item['id'] ) . '" data-parent_id="' . esc_attr( $item['id'] ) . '" data-root_id="' . esc_attr( $item['id'] ) . '">';
     1030                echo $this->single_row_columns( $item );
     1031                echo '</tr>';
     1032        }
     1033
     1034        /**
     1035         * Get the list of views available on this table (e.g. "all", "public").
     1036         *
     1037         * @since 1.7
     1038         */
     1039        function get_views() {
     1040                $url_base = remove_query_arg( array( 'orderby', 'order', 'group_status' ), $_SERVER['REQUEST_URI'] );
     1041                //$redirect_to = remove_query_arg( array( 'activity_status', 'aid', 'deleted', 'error', 'spammed', 'unspammed', 'updated', ), $_SERVER['REQUEST_URI'] );
     1042        ?>
     1043                <ul class="subsubsub">
     1044                        <li class="all"><a href="<?php echo esc_attr( esc_url( $url_base ) ); ?>" class="<?php if ( 'all' == $this->view ) echo 'current'; ?>"><?php _e( 'All', 'buddypress' ); ?></a> |</li>
     1045                        <li class="public"><a href="<?php echo esc_attr( esc_url( add_query_arg( 'group_status', 'public', $url_base ) ) ); ?>" class="<?php if ( 'public' == $this->view ) echo 'current'; ?>"><?php printf( __( 'Public <span class="count">(%s)</span>', 'buddypress' ), number_format_i18n( $this->group_counts['public'] ) ); ?></a> |</li>
     1046                        <li class="private"><a href="<?php echo esc_attr( esc_url( add_query_arg( 'group_status', 'private', $url_base ) ) ); ?>" class="<?php if ( 'private' == $this->view ) echo 'current'; ?>"><?php printf( __( 'Private <span class="count">(%s)</span>', 'buddypress' ), number_format_i18n( $this->group_counts['private'] ) ); ?></a> |</li>
     1047                        <li class="hidden"><a href="<?php echo esc_attr( esc_url( add_query_arg( 'group_status', 'hidden', $url_base ) ) ); ?>" class="<?php if ( 'hidden' == $this->view ) echo 'current'; ?>"><?php printf( __( 'Hidden <span class="count">(%s)</span>', 'buddypress' ), number_format_i18n( $this->group_counts['hidden'] ) ); ?></a></li>
     1048
     1049                        <?php do_action( 'bp_groups_list_table_get_views', $url_base, $this->view ); ?>
     1050                </ul>
     1051        <?php
     1052        }
     1053
     1054        /**
     1055         * Get bulk actions
     1056         *
     1057         * @return array Key/value pairs for the bulk actions dropdown
     1058         * @since 1.7
     1059         */
     1060        function get_bulk_actions() {
     1061                $actions = array();
     1062                $actions['bulk_delete'] = __( 'Delete Permanently', 'buddypress' );
     1063
     1064                return apply_filters( 'bp_groups_list_table_get_bulk_actions', $actions );
     1065        }
     1066
     1067        /**
     1068         * Get the table column titles.
     1069         *
     1070         * @see WP_List_Table::single_row_columns()
     1071         * @return array
     1072         * @since 1.7
     1073         */
     1074        function get_columns() {
     1075                return array(
     1076                        'cb'          => '<input name type="checkbox" />',
     1077                        'gid'         => _x( 'ID', 'Groups admin Group ID column header', 'buddypress' ),
     1078                        'comment'     => _x( 'Name', 'Groups admin Group Name column header', 'buddypress' ),
     1079                        'description' => _x( 'Description', 'Groups admin Group Description column header', 'buddypress' ),
     1080                        'status'      => _x( 'Status', 'Groups admin Privacy Status column header', 'buddypress' ),
     1081                        'members'     => _x( '# Members', 'Groups admin Members column header', 'buddypress' ),
     1082                        'last_active' => _x( 'Last Active', 'Groups admin Last Active column header', 'buddypress' )
     1083                );
     1084        }
     1085
     1086        /**
     1087         * Get the column names for sortable columns
     1088         *
     1089         * @return array
     1090         * @since 1.7
     1091         */
     1092        function get_sortable_columns() {
     1093                return array(
     1094                        'gid'         => array( 'gid', false ),
     1095                        'comment'     => array( 'name', false ),
     1096                        'members'     => array( 'members', false ),
     1097                        'last_active' => array( 'last_active', false )
     1098                );
     1099        }
     1100
     1101        /**
     1102         * Checkbox column
     1103         *
     1104         * @param array $item A singular item (one full row)
     1105         * @see WP_List_Table::single_row_columns()
     1106         * @since 1.6
     1107         */
     1108        function column_cb( $item ) {
     1109                printf( '<input type="checkbox" name="aid[]" value="%d" />', (int) $item['id'] );
     1110        }
     1111
     1112        /**
     1113         * Group id column
     1114         *
     1115         * @param array $item A singular item (one full row)
     1116         * @see WP_List_Table::single_row_columns()
     1117         * @since 1.6
     1118         */
     1119        function column_gid( $item ) {
     1120                echo '<strong>' . $item['id'] . '</strong>';
     1121        }
     1122
     1123        /**
     1124         * Name column, and "quick admin" rollover actions.
     1125         *
     1126         * Called "comment" in the CSS so we can re-use some WP core CSS.
     1127         *
     1128         * @param array $item A singular item (one full row)
     1129         * @see WP_List_Table::single_row_columns()
     1130         * @since 1.7
     1131         */
     1132        function column_comment( $item ) {
     1133
     1134                // Preorder items: Visit | Edit | Delete Permanently
     1135                $actions = array(
     1136                        'visit'  => '',
     1137                        'edit'   => '',
     1138                        'delete' => '',
     1139                );
     1140
     1141                // We need the group object for some BP functions
     1142                $item_obj = (object) $item;
     1143
     1144                // Build actions URLs
     1145                $base_url   = network_admin_url( 'admin.php?page=bp-groups&amp;gid=' . $item['id'] );
     1146                $spam_nonce = esc_html( '_wpnonce=' . wp_create_nonce( 'spam-groups_' . $item['id'] ) );
     1147
     1148                $delete_url = $base_url . "&amp;action=delete&amp;$spam_nonce";
     1149                $edit_url   = $base_url . '&amp;action=edit';
     1150                $visit_url  = bp_get_group_permalink( $item_obj );
     1151
     1152                // Rollover actions
     1153
     1154                // Visit
     1155                $actions['visit'] = sprintf( '<a href="%s">%s</a>', $visit_url, __( 'Visit', 'buddypress' ) );
     1156
     1157                // Edit
     1158                $actions['edit'] = sprintf( '<a href="%s">%s</a>', $edit_url, __( 'Edit', 'buddypress' ) );
     1159
     1160                // Delete
     1161                $actions['delete'] = sprintf( '<a href="%s" onclick="%s">%s</a>', $delete_url, "javascript:return confirm('" . esc_js( __( 'Are you sure?', 'buddypress' ) ) . "'); ", __( 'Delete Permanently', 'buddypress' ) );
     1162
     1163                // Other plugins can filter which actions are shown
     1164                $actions = apply_filters( 'bp_activity_admin_comment_row_actions', array_filter( $actions ), $item );
     1165
     1166                // Get group name and avatar
     1167                $avatar  = bp_core_fetch_avatar( array(
     1168                        'item_id'    => $item['id'],
     1169                        'object'     => 'group',
     1170                        'type'       => 'thumb',
     1171                        'avatar_dir' => 'group-avatars',
     1172                        'alt'        => sprintf( __( 'Group logo of %s', 'buddypress' ), $item['name'] ),
     1173                        'width'      => '32',
     1174                        'height'     => '32',
     1175                        'title'      => $item['name']
     1176                ) );
     1177
     1178                $content = apply_filters_ref_array( 'bp_get_group_name', array( $item['name'], $item ) );
     1179
     1180                echo $avatar . ' ' . $content . ' ' . $this->row_actions( $actions );
     1181        }
     1182
     1183        /**
     1184         * Description column
     1185         *
     1186         * @since 1.7
     1187         */
     1188        function column_description( $item ) {
     1189                echo apply_filters_ref_array( 'bp_get_group_description', array( $item['description'], $item ) );
     1190        }
     1191
     1192        /**
     1193         * Status column
     1194         *
     1195         * @since 1.7
     1196         */
     1197        function column_status( $item ) {
     1198                $status = $item['status'];
     1199
     1200                $status_desc = '';
     1201
     1202                // @todo This should be abstracted out somewhere for the whole
     1203                // Groups component
     1204                switch ( $status ) {
     1205                        case 'public' :
     1206                                $status_desc = __( 'Public', 'buddypress' );
     1207                                break;
     1208                        case 'private' :
     1209                                $status_desc = __( 'Private', 'buddypress' );
     1210                                break;
     1211                        case 'hidden' :
     1212                                $status_desc = __( 'Hidden', 'buddypress' );
     1213                                break;
     1214                }
     1215
     1216                echo apply_filters_ref_array( 'bp_groups_admin_get_group_status', array( $status_desc, $item ) );
     1217        }
     1218
     1219        /**
     1220         * Number of Members column
     1221         *
     1222         * @since 1.7
     1223         */
     1224        function column_members( $item ) {
     1225                $count = groups_get_groupmeta( $item['id'], 'total_member_count' );
     1226                echo apply_filters_ref_array( 'bp_groups_admin_get_group_member_count', array( (int) $count, $item ) );
     1227        }
     1228
     1229        /**
     1230         * Last Active column
     1231         *
     1232         * @since 1.7
     1233         */
     1234        function column_last_active( $item ) {
     1235                $last_active = groups_get_groupmeta( $item['id'], 'last_activity' );
     1236                echo apply_filters_ref_array( 'bp_groups_admin_get_group_last_active', array( $last_active, $item ) );
     1237        }
     1238}
     1239
     1240?>
  • bp-groups/bp-groups-classes.php

    diff --git bp-groups/bp-groups-classes.php bp-groups/bp-groups-classes.php
    index 114339f..5df790b 100644
    class BP_Groups_Group { 
    5858        function populate() {
    5959                global $wpdb, $bp;
    6060
    61                 if ( $group = $wpdb->get_row( $wpdb->prepare( "SELECT g.* FROM {$bp->groups->table_name} g WHERE g.id = %d", $this->id ) ) ) {                 
     61                if ( $group = $wpdb->get_row( $wpdb->prepare( "SELECT g.* FROM {$bp->groups->table_name} g WHERE g.id = %d", $this->id ) ) ) {
    6262                        bp_groups_update_meta_cache( $this->id );
    63                                                
     63
    6464                        $this->id                 = $group->id;
    6565                        $this->creator_id         = $group->creator_id;
    6666                        $this->name               = stripslashes($group->name);
    class BP_Groups_Group { 
    7272                        $this->last_activity      = groups_get_groupmeta( $this->id, 'last_activity' );
    7373                        $this->total_member_count = groups_get_groupmeta( $this->id, 'total_member_count' );
    7474                        $this->is_member          = BP_Groups_Member::check_is_member( bp_loggedin_user_id(), $this->id );
    75                        
     75
    7676                        // If this is a private or hidden group, does the current user have access?
    7777                        if ( 'private' == $this->status || 'hidden' == $this->status ) {
    7878                                if ( $this->is_member && is_user_logged_in() || bp_current_user_can( 'bp_moderate' ) )
    class BP_Groups_Group { 
    159159                        $this->id = $wpdb->insert_id;
    160160
    161161                do_action_ref_array( 'groups_group_after_save', array( &$this ) );
    162                
     162
    163163                wp_cache_delete( 'bp_groups_group_' . $this->id, 'bp' );
    164164
    165165                return true;
    class BP_Groups_Group { 
    415415                foreach ( (array) $paged_groups as $group ) {
    416416                        $group_ids[] = $group->id;
    417417                }
    418                
     418
    419419                // Populate some extra information instead of querying each time in the loop
    420420                if ( !empty( $populate_extras ) ) {
    421421                        $group_ids = $wpdb->escape( join( ',', (array) $group_ids ) );
    422422                        $paged_groups = BP_Groups_Group::get_group_extras( $paged_groups, $group_ids, $type );
    423423                }
    424                
     424
    425425                // Grab all groupmeta
    426426                bp_groups_update_meta_cache( $group_ids );
    427427
    class BP_Groups_Group { 
    707707
    708708                return $wpdb->get_var( implode( ' ', $sql ) );
    709709        }
     710
     711        /**
     712         * Get an array containing ids for each group type
     713         *
     714         * A bit of a kludge workaround for some issues
     715         * with bp_has_groups()
     716         *
     717         * @since 1.7
     718         *
     719         * @return array
     720         */
     721        function get_group_type_ids() {
     722                global $wpdb, $bp;
     723
     724                $ids = array();
     725
     726                $ids['all']     = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$bp->groups->table_name}" ) );
     727                $ids['public']  = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$bp->groups->table_name} WHERE status = 'public'" ) );
     728                $ids['private'] = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$bp->groups->table_name} WHERE status = 'private'" ) );
     729                $ids['hidden']  = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$bp->groups->table_name} WHERE status = 'hidden'" ) );
     730
     731                return $ids;
     732        }
    710733}
    711734
    712735class BP_Groups_Member {
    class BP_Groups_Member { 
    799822                        if ( $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id = %d LIMIT 1", $this->user_id, $this->group_id ) ) ) {
    800823                                return false;
    801824                        }
    802                        
     825
    803826                        $sql = $wpdb->prepare( "INSERT INTO {$bp->groups->table_name_members} ( user_id, group_id, inviter_id, is_admin, is_mod, is_banned, user_title, date_modified, is_confirmed, comments, invite_sent ) VALUES ( %d, %d, %d, %d, %d, %d, %s, %s, %d, %s, %d )", $this->user_id, $this->group_id, $this->inviter_id, $this->is_admin, $this->is_mod, $this->is_banned, $this->user_title, $this->date_modified, $this->is_confirmed, $this->comments, $this->invite_sent );
    804827                }
    805828
    class BP_Groups_Member { 
    12531276class BP_Group_Extension {
    12541277        var $name = false;
    12551278        var $slug = false;
    1256        
     1279
    12571280        // The name/slug of the Group Admin tab for this extension
    12581281        var $admin_name = '';
    12591282        var $admin_slug = '';
    class BP_Group_Extension { 
    12951318
    12961319        function _register() {
    12971320                global $bp;
    1298                
     1321
    12991322                // If admin/create names and slugs are not provided, they fall back on the main
    13001323                // name and slug for the extension
    13011324                if ( !$this->admin_name ) {
    13021325                        $this->admin_name = $this->name;
    13031326                }
    1304                
     1327
    13051328                if ( !$this->admin_slug ) {
    13061329                        $this->admin_slug = $this->slug;
    13071330                }
    1308                
     1331
    13091332                if ( !$this->create_name ) {
    13101333                        $this->create_name = $this->name;
    13111334                }
    1312                
     1335
    13131336                if ( !$this->create_slug ) {
    13141337                        $this->create_slug = $this->slug;
    13151338                }
    function bp_register_group_extension( $group_extension_class ) { 
    13821405        add_action( 'bp_init', create_function( '', '$extension = new ' . $group_extension_class . '; add_action( "bp_actions", array( &$extension, "_register" ), 8 );' ), 11 );
    13831406}
    13841407
    1385 ?>
    1386  No newline at end of file
     1408?>
  • bp-groups/bp-groups-loader.php

    diff --git bp-groups/bp-groups-loader.php bp-groups/bp-groups-loader.php
    index d1a9368..1d36c7b 100644
    class BP_Groups_Component extends BP_Component { 
    9898                        'classes',
    9999                        'widgets',
    100100                        'activity',
     101                        'admin',
    101102                        'template',
    102103                        'buddybar',
    103104                        'adminbar',
  • bp-groups/bp-groups-template.php

    diff --git bp-groups/bp-groups-template.php bp-groups/bp-groups-template.php
    index e471241..3e1f998 100644
    function bp_groups_current_create_step() { 
    22092209         */
    22102210        function bp_get_groups_current_create_step() {
    22112211                global $bp;
    2212                
     2212
    22132213                if ( !empty( $bp->groups->current_create_step ) ) {
    22142214                        $current_create_step = $bp->groups->current_create_step;
    22152215                } else {
    22162216                        $current_create_step = '';
    22172217                }
    2218                
     2218
    22192219                return apply_filters( 'bp_get_groups_current_create_step', $current_create_step );
    22202220        }
    22212221
    function bp_group_current_admin_tab() { 
    23792379                } else {
    23802380                        $tab = '';
    23812381                }
    2382                
     2382
    23832383                return apply_filters( 'bp_get_current_group_admin_tab', $tab );
    23842384        }
    23852385
    function bp_groups_action_link( $action = '', $query_args = '', $nonce = false ) 
    28962896                if ( !empty( $url ) )
    28972897                        return $url;
    28982898        }
    2899 ?>
    2900  No newline at end of file
     2899?>