Skip to:
Content

BuddyPress.org

Changeset 10520


Ignore:
Timestamp:
02/05/2016 04:55:58 AM (5 years ago)
Author:
boonebgorges
Message:

Move bp-groups classes to their own files.

See #6870.

Location:
trunk/src/bp-groups
Files:
5 edited
8 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-groups/bp-groups-admin.php

    r10462 r10520  
    1616// Include WP's list table class.
    1717if ( !class_exists( 'WP_List_Table' ) ) require( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
     18
     19require dirname( __FILE__ ) . '/classes/class-bp-groups-list-table.php';
    1820
    1921// The per_page screen option. Has to be hooked in extremely early.
     
    11261128}
    11271129add_action( 'wp_ajax_bp_group_admin_member_autocomplete', 'bp_groups_admin_autocomplete_handler' );
    1128 
    1129 /**
    1130  * List table class for the Groups component admin page.
    1131  *
    1132  * @since 1.7.0
    1133  */
    1134 class BP_Groups_List_Table extends WP_List_Table {
    1135 
    1136     /**
    1137      * The type of view currently being displayed.
    1138      *
    1139      * E.g. "All", "Pending", "Approved", "Spam"...
    1140      *
    1141      * @since 1.7.0
    1142      * @var string
    1143      */
    1144     public $view = 'all';
    1145 
    1146     /**
    1147      * Group counts for each group type.
    1148      *
    1149      * @since 1.7.0
    1150      * @var int
    1151      */
    1152     public $group_counts = 0;
    1153 
    1154     /**
    1155      * Multidimensional array of group visibility types and their groups.
    1156      *
    1157      * @link https://buddypress.trac.wordpress.org/ticket/6277
    1158      * @var array
    1159      */
    1160     public $group_type_ids = array();
    1161 
    1162     /**
    1163      * Constructor
    1164      *
    1165      * @since 1.7.0
    1166      */
    1167     public function __construct() {
    1168 
    1169         // Define singular and plural labels, as well as whether we support AJAX.
    1170         parent::__construct( array(
    1171             'ajax'     => false,
    1172             'plural'   => 'groups',
    1173             'singular' => 'group',
    1174         ) );
    1175     }
    1176 
    1177     /**
    1178      * Set up items for display in the list table.
    1179      *
    1180      * Handles filtering of data, sorting, pagination, and any other data
    1181      * manipulation required prior to rendering.
    1182      *
    1183      * @since 1.7.0
    1184      */
    1185     public function prepare_items() {
    1186         global $groups_template;
    1187 
    1188         $screen = get_current_screen();
    1189 
    1190         // Option defaults.
    1191         $include_id   = false;
    1192         $search_terms = false;
    1193 
    1194         // Set current page.
    1195         $page = $this->get_pagenum();
    1196 
    1197         // Set per page from the screen options.
    1198         $per_page = $this->get_items_per_page( str_replace( '-', '_', "{$screen->id}_per_page" ) );
    1199 
    1200         // Sort order.
    1201         $order = 'DESC';
    1202         if ( !empty( $_REQUEST['order'] ) ) {
    1203             $order = ( 'desc' == strtolower( $_REQUEST['order'] ) ) ? 'DESC' : 'ASC';
    1204         }
    1205 
    1206         // Order by - default to newest.
    1207         $orderby = 'last_activity';
    1208         if ( ! empty( $_REQUEST['orderby'] ) ) {
    1209             switch ( $_REQUEST['orderby'] ) {
    1210                 case 'name' :
    1211                     $orderby = 'name';
    1212                     break;
    1213                 case 'id' :
    1214                     $orderby = 'date_created';
    1215                     break;
    1216                 case 'members' :
    1217                     $orderby = 'total_member_count';
    1218                     break;
    1219                 case 'last_active' :
    1220                     $orderby = 'last_activity';
    1221                     break;
    1222             }
    1223         }
    1224 
    1225         // Are we doing a search?
    1226         if ( !empty( $_REQUEST['s'] ) )
    1227             $search_terms = $_REQUEST['s'];
    1228 
    1229         // Check if user has clicked on a specific group (if so, fetch only that group).
    1230         if ( !empty( $_REQUEST['gid'] ) )
    1231             $include_id = (int) $_REQUEST['gid'];
    1232 
    1233         // Set the current view.
    1234         if ( isset( $_GET['group_status'] ) && in_array( $_GET['group_status'], array( 'public', 'private', 'hidden' ) ) ) {
    1235             $this->view = $_GET['group_status'];
    1236         }
    1237 
    1238         // We'll use the ids of group types for the 'include' param.
    1239         $this->group_type_ids = BP_Groups_Group::get_group_type_ids();
    1240 
    1241         // Pass a dummy array if there are no groups of this type.
    1242         $include = false;
    1243         if ( 'all' != $this->view && isset( $this->group_type_ids[ $this->view ] ) ) {
    1244             $include = ! empty( $this->group_type_ids[ $this->view ] ) ? $this->group_type_ids[ $this->view ] : array( 0 );
    1245         }
    1246 
    1247         // Get group type counts for display in the filter tabs.
    1248         $this->group_counts = array();
    1249         foreach ( $this->group_type_ids as $group_type => $group_ids ) {
    1250             $this->group_counts[ $group_type ] = count( $group_ids );
    1251         }
    1252 
    1253         // If we're viewing a specific group, flatten all activities into a single array.
    1254         if ( $include_id ) {
    1255             $groups = array( (array) groups_get_group( 'group_id=' . $include_id ) );
    1256         } else {
    1257             $groups_args = array(
    1258                 'include'  => $include,
    1259                 'per_page' => $per_page,
    1260                 'page'     => $page,
    1261                 'orderby'  => $orderby,
    1262                 'order'    => $order
    1263             );
    1264 
    1265             $groups = array();
    1266             if ( bp_has_groups( $groups_args ) ) {
    1267                 while ( bp_groups() ) {
    1268                     bp_the_group();
    1269                     $groups[] = (array) $groups_template->group;
    1270                 }
    1271             }
    1272         }
    1273 
    1274         // Set raw data to display.
    1275         $this->items = $groups;
    1276 
    1277         // Store information needed for handling table pagination.
    1278         $this->set_pagination_args( array(
    1279             'per_page'    => $per_page,
    1280             'total_items' => $groups_template->total_group_count,
    1281             'total_pages' => ceil( $groups_template->total_group_count / $per_page )
    1282         ) );
    1283     }
    1284 
    1285     /**
    1286      * Get an array of all the columns on the page.
    1287      *
    1288      * @since 1.7.0
    1289      *
    1290      * @return array Array of column headers.
    1291      */
    1292     public function get_column_info() {
    1293         $this->_column_headers = array(
    1294             $this->get_columns(),
    1295             array(),
    1296             $this->get_sortable_columns(),
    1297             $this->get_default_primary_column_name(),
    1298         );
    1299 
    1300         return $this->_column_headers;
    1301     }
    1302 
    1303     /**
    1304      * Get name of default primary column
    1305      *
    1306      * @since 2.3.3
    1307      *
    1308      * @return string
    1309      */
    1310     protected function get_default_primary_column_name() {
    1311         // Comment column is mapped to Group's name.
    1312         return 'comment';
    1313     }
    1314 
    1315     /**
    1316      * Display a message on screen when no items are found ("No groups found").
    1317      *
    1318      * @since 1.7.0
    1319      */
    1320     public function no_items() {
    1321         _e( 'No groups found.', 'buddypress' );
    1322     }
    1323 
    1324     /**
    1325      * Output the Groups data table.
    1326      *
    1327      * @since 1.7.0
    1328      */
    1329     public function display() {
    1330         $this->display_tablenav( 'top' ); ?>
    1331 
    1332         <h2 class="screen-reader-text"><?php _e( 'Groups list', 'buddypress' ); ?></h2>
    1333 
    1334         <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>" cellspacing="0">
    1335             <thead>
    1336                 <tr>
    1337                     <?php $this->print_column_headers(); ?>
    1338                 </tr>
    1339             </thead>
    1340 
    1341             <tfoot>
    1342                 <tr>
    1343                     <?php $this->print_column_headers( false ); ?>
    1344                 </tr>
    1345             </tfoot>
    1346 
    1347             <tbody id="the-comment-list">
    1348                 <?php $this->display_rows_or_placeholder(); ?>
    1349             </tbody>
    1350         </table>
    1351         <?php
    1352 
    1353         $this->display_tablenav( 'bottom' );
    1354     }
    1355 
    1356     /**
    1357      * Generate content for a single row of the table.
    1358      *
    1359      * @since 1.7.0
    1360      *
    1361      * @param object|array $item The current group item in the loop.
    1362      */
    1363     public function single_row( $item = array() ) {
    1364         static $even = false;
    1365 
    1366         $row_classes = array();
    1367 
    1368         if ( $even ) {
    1369             $row_classes = array( 'even' );
    1370         } else {
    1371             $row_classes = array( 'alternate', 'odd' );
    1372         }
    1373 
    1374         /**
    1375          * Filters the classes applied to a single row in the groups list table.
    1376          *
    1377          * @since 1.9.0
    1378          *
    1379          * @param array  $row_classes Array of classes to apply to the row.
    1380          * @param string $value       ID of the current group being displayed.
    1381          */
    1382         $row_classes = apply_filters( 'bp_groups_admin_row_class', $row_classes, $item['id'] );
    1383         $row_class = ' class="' . implode( ' ', $row_classes ) . '"';
    1384 
    1385         echo '<tr' . $row_class . ' id="group-' . esc_attr( $item['id'] ) . '" data-parent_id="' . esc_attr( $item['id'] ) . '" data-root_id="' . esc_attr( $item['id'] ) . '">';
    1386         echo $this->single_row_columns( $item );
    1387         echo '</tr>';
    1388 
    1389         $even = ! $even;
    1390     }
    1391 
    1392     /**
    1393      * Get the list of views available on this table (e.g. "all", "public").
    1394      *
    1395      * @since 1.7.0
    1396      */
    1397     public function get_views() {
    1398         $url_base = bp_get_admin_url( 'admin.php?page=bp-groups' ); ?>
    1399 
    1400         <h2 class="screen-reader-text"><?php _e( 'Filter groups list', 'buddypress' ); ?></h2>
    1401 
    1402         <ul class="subsubsub">
    1403             <li class="all"><a href="<?php echo esc_url( $url_base ); ?>" class="<?php if ( 'all' == $this->view ) echo 'current'; ?>"><?php _e( 'All', 'buddypress' ); ?></a> |</li>
    1404             <li class="public"><a href="<?php echo esc_url( add_query_arg( 'group_status', 'public', $url_base ) ); ?>" class="<?php if ( 'public' == $this->view ) echo 'current'; ?>"><?php printf( _n( 'Public <span class="count">(%s)</span>', 'Public <span class="count">(%s)</span>', $this->group_counts['public'], 'buddypress' ), number_format_i18n( $this->group_counts['public'] ) ); ?></a> |</li>
    1405             <li class="private"><a href="<?php echo esc_url( add_query_arg( 'group_status', 'private', $url_base ) ); ?>" class="<?php if ( 'private' == $this->view ) echo 'current'; ?>"><?php printf( _n( 'Private <span class="count">(%s)</span>', 'Private <span class="count">(%s)</span>', $this->group_counts['private'], 'buddypress' ), number_format_i18n( $this->group_counts['private'] ) ); ?></a> |</li>
    1406             <li class="hidden"><a href="<?php echo esc_url( add_query_arg( 'group_status', 'hidden', $url_base ) ); ?>" class="<?php if ( 'hidden' == $this->view ) echo 'current'; ?>"><?php printf( _n( 'Hidden <span class="count">(%s)</span>', 'Hidden <span class="count">(%s)</span>', $this->group_counts['hidden'], 'buddypress' ), number_format_i18n( $this->group_counts['hidden'] ) ); ?></a></li>
    1407 
    1408             <?php
    1409 
    1410             /**
    1411              * Fires inside listing of views so plugins can add their own.
    1412              *
    1413              * @since 1.7.0
    1414              *
    1415              * @param string $url_base Current URL base for view.
    1416              * @param string $view     Current view being displayed.
    1417              */
    1418             do_action( 'bp_groups_list_table_get_views', $url_base, $this->view ); ?>
    1419         </ul>
    1420     <?php
    1421     }
    1422 
    1423     /**
    1424      * Get bulk actions for single group row.
    1425      *
    1426      * @since 1.7.0
    1427      *
    1428      * @return array Key/value pairs for the bulk actions dropdown.
    1429      */
    1430     public function get_bulk_actions() {
    1431 
    1432         /**
    1433          * Filters the list of bulk actions to display on a single group row.
    1434          *
    1435          * @since 1.7.0
    1436          *
    1437          * @param array $value Array of bulk actions to display.
    1438          */
    1439         return apply_filters( 'bp_groups_list_table_get_bulk_actions', array(
    1440             'delete' => __( 'Delete', 'buddypress' )
    1441         ) );
    1442     }
    1443 
    1444     /**
    1445      * Get the table column titles.
    1446      *
    1447      * @since 1.7.0
    1448      *
    1449      * @see WP_List_Table::single_row_columns()
    1450      *
    1451      * @return array Array of column titles.
    1452      */
    1453     public function get_columns() {
    1454 
    1455         /**
    1456          * Filters the titles for the columns for the groups list table.
    1457          *
    1458          * @since 2.0.0
    1459          *
    1460          * @param array $value Array of slugs and titles for the columns.
    1461          */
    1462         return apply_filters( 'bp_groups_list_table_get_columns', array(
    1463             'cb'          => '<input name type="checkbox" />',
    1464             'comment'     => _x( 'Name', 'Groups admin Group Name column header',               'buddypress' ),
    1465             'description' => _x( 'Description', 'Groups admin Group Description column header', 'buddypress' ),
    1466             'status'      => _x( 'Status', 'Groups admin Privacy Status column header',         'buddypress' ),
    1467             'members'     => _x( '# Members', 'Groups admin Members column header',             'buddypress' ),
    1468             'last_active' => _x( 'Last Active', 'Groups admin Last Active column header',       'buddypress' )
    1469         ) );
    1470     }
    1471 
    1472     /**
    1473      * Get the column names for sortable columns.
    1474      *
    1475      * Note: It's not documented in WP, but the second item in the
    1476      * nested arrays below is $desc_first. Normally, we would set
    1477      * last_active to be desc_first (since you're generally interested in
    1478      * the *most* recently active group, not the *least*). But because
    1479      * the default sort for the Groups admin screen is DESC by last_active,
    1480      * we want the first click on the Last Active column header to switch
    1481      * the sort order - ie, to make it ASC. Thus last_active is set to
    1482      * $desc_first = false.
    1483      *
    1484      * @since 1.7.0
    1485      *
    1486      * @return array Array of sortable column names.
    1487      */
    1488     public function get_sortable_columns() {
    1489         return array(
    1490             'gid'         => array( 'gid', false ),
    1491             'comment'     => array( 'name', false ),
    1492             'members'     => array( 'members', false ),
    1493             'last_active' => array( 'last_active', false ),
    1494         );
    1495     }
    1496 
    1497     /**
    1498      * Override WP_List_Table::row_actions().
    1499      *
    1500      * Basically a duplicate of the row_actions() method, but removes the
    1501      * unnecessary <button> addition.
    1502      *
    1503      * @since 2.3.3
    1504      * @since 2.3.4 Visibility set to public for compatibility with WP < 4.0.0.
    1505      *
    1506      * @param array $actions        The list of actions.
    1507      * @param bool  $always_visible Whether the actions should be always visible.
    1508      * @return string
    1509      */
    1510     public function row_actions( $actions, $always_visible = false ) {
    1511         $action_count = count( $actions );
    1512         $i = 0;
    1513 
    1514         if ( !$action_count )
    1515             return '';
    1516 
    1517         $out = '<div class="' . ( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">';
    1518         foreach ( $actions as $action => $link ) {
    1519             ++$i;
    1520             ( $i == $action_count ) ? $sep = '' : $sep = ' | ';
    1521             $out .= "<span class='$action'>$link$sep</span>";
    1522         }
    1523         $out .= '</div>';
    1524 
    1525         return $out;
    1526     }
    1527 
    1528     /**
    1529      * Markup for the Checkbox column.
    1530      *
    1531      * @since 1.7.0
    1532      *
    1533      * @see WP_List_Table::single_row_columns()
    1534      *
    1535      * @param array $item A singular item (one full row).
    1536      */
    1537     public function column_cb( $item = array() ) {
    1538         printf( '<label class="screen-reader-text" for="gid-%1$d">' . __( 'Select group %1$d', 'buddypress' ) . '</label><input type="checkbox" name="gid[]" value="%1$d" id="gid-%1$d" />', $item['id'] );
    1539     }
    1540 
    1541     /**
    1542      * Markup for the Group ID column.
    1543      *
    1544      * @since 1.7.0
    1545      *
    1546      * @see WP_List_Table::single_row_columns()
    1547      *
    1548      * @param array $item A singular item (one full row).
    1549      */
    1550     public function column_gid( $item = array() ) {
    1551         echo '<strong>' . absint( $item['id'] ) . '</strong>';
    1552     }
    1553 
    1554     /**
    1555      * Name column, and "quick admin" rollover actions.
    1556      *
    1557      * Called "comment" in the CSS so we can re-use some WP core CSS.
    1558      *
    1559      * @since 1.7.0
    1560      *
    1561      * @see WP_List_Table::single_row_columns()
    1562      *
    1563      * @param array $item A singular item (one full row).
    1564      */
    1565     public function column_comment( $item = array() ) {
    1566 
    1567         // Preorder items: Edit | Delete | View.
    1568         $actions = array(
    1569             'edit'   => '',
    1570             'delete' => '',
    1571             'view'   => '',
    1572         );
    1573 
    1574         // We need the group object for some BP functions.
    1575         $item_obj = (object) $item;
    1576 
    1577         // Build actions URLs.
    1578         $base_url   = bp_get_admin_url( 'admin.php?page=bp-groups&amp;gid=' . $item['id'] );
    1579         $delete_url = wp_nonce_url( $base_url . "&amp;action=delete", 'bp-groups-delete' );
    1580         $edit_url   = $base_url . '&amp;action=edit';
    1581         $view_url   = bp_get_group_permalink( $item_obj );
    1582 
    1583         /**
    1584          * Filters the group name for a group's column content.
    1585          *
    1586          * @since 1.7.0
    1587          *
    1588          * @param string $value Name of the group being rendered.
    1589          * @param array  $item  Array for the current group item.
    1590          */
    1591         $group_name = apply_filters_ref_array( 'bp_get_group_name', array( $item['name'] ), $item );
    1592 
    1593         // Rollover actions.
    1594         // Edit.
    1595         $actions['edit']   = sprintf( '<a href="%s">%s</a>', esc_url( $edit_url   ), __( 'Edit',   'buddypress' ) );
    1596 
    1597         // Delete.
    1598         $actions['delete'] = sprintf( '<a href="%s">%s</a>', esc_url( $delete_url ), __( 'Delete', 'buddypress' ) );
    1599 
    1600         // Visit.
    1601         $actions['view']   = sprintf( '<a href="%s">%s</a>', esc_url( $view_url   ), __( 'View',   'buddypress' ) );
    1602 
    1603         /**
    1604          * Filters the actions that will be shown for the column content.
    1605          *
    1606          * @since 1.7.0
    1607          *
    1608          * @param array $value Array of actions to be displayed for the column content.
    1609          * @param array $item  The current group item in the loop.
    1610          */
    1611         $actions = apply_filters( 'bp_groups_admin_comment_row_actions', array_filter( $actions ), $item );
    1612 
    1613         // Get group name and avatar.
    1614         $avatar = '';
    1615 
    1616         if ( buddypress()->avatar->show_avatars ) {
    1617             $avatar  = bp_core_fetch_avatar( array(
    1618                 'item_id'    => $item['id'],
    1619                 'object'     => 'group',
    1620                 'type'       => 'thumb',
    1621                 'avatar_dir' => 'group-avatars',
    1622                 'alt'        => sprintf( __( 'Group logo of %s', 'buddypress' ), $group_name ),
    1623                 'width'      => '32',
    1624                 'height'     => '32',
    1625                 'title'      => $group_name
    1626             ) );
    1627         }
    1628 
    1629         $content = sprintf( '<strong><a href="%s">%s</a></strong>', esc_url( $edit_url ), $group_name );
    1630 
    1631         echo $avatar . ' ' . $content . ' ' . $this->row_actions( $actions );
    1632     }
    1633 
    1634     /**
    1635      * Markup for the Description column.
    1636      *
    1637      * @since 1.7.0
    1638      *
    1639      * @param array $item Information about the current row.
    1640      */
    1641     public function column_description( $item = array() ) {
    1642 
    1643         /**
    1644          * Filters the markup for the Description column.
    1645          *
    1646          * @since 1.0.0
    1647          *
    1648          * @param string $value Markup for the Description column.
    1649          * @param array  $item  The current group item in the loop.
    1650          */
    1651         echo apply_filters_ref_array( 'bp_get_group_description', array( $item['description'], $item ) );
    1652     }
    1653 
    1654     /**
    1655      * Markup for the Status column.
    1656      *
    1657      * @since 1.7.0
    1658      *
    1659      * @param array $item Information about the current row.
    1660      */
    1661     public function column_status( $item = array() ) {
    1662         $status      = $item['status'];
    1663         $status_desc = '';
    1664 
    1665         // @todo This should be abstracted out somewhere for the whole
    1666         // Groups component.
    1667         switch ( $status ) {
    1668             case 'public' :
    1669                 $status_desc = __( 'Public', 'buddypress' );
    1670                 break;
    1671             case 'private' :
    1672                 $status_desc = __( 'Private', 'buddypress' );
    1673                 break;
    1674             case 'hidden' :
    1675                 $status_desc = __( 'Hidden', 'buddypress' );
    1676                 break;
    1677         }
    1678 
    1679         /**
    1680          * Filters the markup for the Status column.
    1681          *
    1682          * @since 1.7.0
    1683          *
    1684          * @param string $status_desc Markup for the Status column.
    1685          * @parma array  $item        The current group item in the loop.
    1686          */
    1687         echo apply_filters_ref_array( 'bp_groups_admin_get_group_status', array( $status_desc, $item ) );
    1688     }
    1689 
    1690     /**
    1691      * Markup for the Number of Members column.
    1692      *
    1693      * @since 1.7.0
    1694      *
    1695      * @param array $item Information about the current row.
    1696      */
    1697     public function column_members( $item = array() ) {
    1698         $count = groups_get_groupmeta( $item['id'], 'total_member_count' );
    1699 
    1700         /**
    1701          * Filters the markup for the number of Members column.
    1702          *
    1703          * @since 1.7.0
    1704          *
    1705          * @param int   $count Markup for the number of Members column.
    1706          * @parma array $item  The current group item in the loop.
    1707          */
    1708         echo apply_filters_ref_array( 'bp_groups_admin_get_group_member_count', array( (int) $count, $item ) );
    1709     }
    1710 
    1711     /**
    1712      * Markup for the Last Active column.
    1713      *
    1714      * @since 1.7.0
    1715      *
    1716      * @param array $item Information about the current row.
    1717      */
    1718     public function column_last_active( $item = array() ) {
    1719         $last_active = groups_get_groupmeta( $item['id'], 'last_activity' );
    1720 
    1721         /**
    1722          * Filters the markup for the Last Active column.
    1723          *
    1724          * @since 1.7.0
    1725          *
    1726          * @param string $last_active Markup for the Last Active column.
    1727          * @parma array  $item        The current group item in the loop.
    1728          */
    1729         echo apply_filters_ref_array( 'bp_groups_admin_get_group_last_active', array( $last_active, $item ) );
    1730     }
    1731 
    1732     /**
    1733      * Allow plugins to add their custom column.
    1734      *
    1735      * @since 2.0.0
    1736      *
    1737      * @param array  $item        Information about the current row.
    1738      * @param string $column_name The column name.
    1739      * @return string
    1740      */
    1741     public function column_default( $item = array(), $column_name = '' ) {
    1742 
    1743         /**
    1744          * Filters a string to allow plugins to add custom column content.
    1745          *
    1746          * @since 2.0.0
    1747          *
    1748          * @param string $value       Empty string.
    1749          * @param string $column_name Name of the column being rendered.
    1750          * @param array  $item        The current group item in the loop.
    1751          */
    1752         return apply_filters( 'bp_groups_admin_get_group_custom_column', '', $column_name, $item );
    1753     }
    1754 }
  • trunk/src/bp-groups/bp-groups-loader.php

    r10454 r10520  
    1515defined( 'ABSPATH' ) || exit;
    1616
    17 /**
    18  * Creates our Groups component.
    19  *
    20  * @since 1.5.0
    21  */
    22 class BP_Groups_Component extends BP_Component {
    23 
    24     /**
    25      * Auto-join group when non group member performs group activity.
    26      *
    27      * @since 1.5.0
    28      * @var bool
    29      */
    30     public $auto_join;
    31 
    32     /**
    33      * The group being currently accessed.
    34      *
    35      * @since 1.5.0
    36      * @var BP_Groups_Group
    37      */
    38     public $current_group;
    39 
    40     /**
    41      * Default group extension.
    42      *
    43      * @since 1.6.0
    44      * @todo Is this used anywhere? Is this a duplicate of $default_extension?
    45      * @var string
    46      */
    47     var $default_component;
    48 
    49     /**
    50      * Default group extension.
    51      *
    52      * @since 1.6.0
    53      * @var string
    54      */
    55     public $default_extension;
    56 
    57     /**
    58      * Illegal group names/slugs.
    59      *
    60      * @since 1.5.0
    61      * @var array
    62      */
    63     public $forbidden_names;
    64 
    65     /**
    66      * Group creation/edit steps (e.g. Details, Settings, Avatar, Invites).
    67      *
    68      * @since 1.5.0
    69      * @var array
    70      */
    71     public $group_creation_steps;
    72 
    73     /**
    74      * Types of group statuses (Public, Private, Hidden).
    75      *
    76      * @since 1.5.0
    77      * @var array
    78      */
    79     public $valid_status;
    80 
    81     /**
    82      * Start the groups component creation process.
    83      *
    84      * @since 1.5.0
    85      */
    86     public function __construct() {
    87         parent::start(
    88             'groups',
    89             _x( 'User Groups', 'Group screen page <title>', 'buddypress' ),
    90             buddypress()->plugin_dir,
    91             array(
    92                 'adminbar_myaccount_order' => 70,
    93                 'search_query_arg' => 'groups_search',
    94             )
    95         );
    96     }
    97 
    98     /**
    99      * Include Groups component files.
    100      *
    101      * @since 1.5.0
    102      *
    103      * @see BP_Component::includes() for a description of arguments.
    104      *
    105      * @param array $includes See BP_Component::includes() for a description.
    106      */
    107     public function includes( $includes = array() ) {
    108         $includes = array(
    109             'cache',
    110             'forums',
    111             'actions',
    112             'filters',
    113             'screens',
    114             'classes',
    115             'widgets',
    116             'activity',
    117             'template',
    118             'adminbar',
    119             'functions',
    120             'notifications'
    121         );
    122 
    123         if ( is_admin() ) {
    124             $includes[] = 'admin';
    125         }
    126 
    127         parent::includes( $includes );
    128     }
    129 
    130     /**
    131      * Set up component global data.
    132      *
    133      * The BP_GROUPS_SLUG constant is deprecated, and only used here for
    134      * backwards compatibility.
    135      *
    136      * @since 1.5.0
    137      *
    138      * @see BP_Component::setup_globals() for a description of arguments.
    139      *
    140      * @param array $args See BP_Component::setup_globals() for a description.
    141      */
    142     public function setup_globals( $args = array() ) {
    143         $bp = buddypress();
    144 
    145         // Define a slug, if necessary.
    146         if ( ! defined( 'BP_GROUPS_SLUG' ) ) {
    147             define( 'BP_GROUPS_SLUG', $this->id );
    148         }
    149 
    150         // Global tables for groups component.
    151         $global_tables = array(
    152             'table_name'           => $bp->table_prefix . 'bp_groups',
    153             'table_name_members'   => $bp->table_prefix . 'bp_groups_members',
    154             'table_name_groupmeta' => $bp->table_prefix . 'bp_groups_groupmeta'
    155         );
    156 
    157         // Metadata tables for groups component.
    158         $meta_tables = array(
    159             'group' => $bp->table_prefix . 'bp_groups_groupmeta',
    160         );
    161 
    162         // All globals for groups component.
    163         // Note that global_tables is included in this array.
    164         $args = array(
    165             'slug'                  => BP_GROUPS_SLUG,
    166             'root_slug'             => isset( $bp->pages->groups->slug ) ? $bp->pages->groups->slug : BP_GROUPS_SLUG,
    167             'has_directory'         => true,
    168             'directory_title'       => _x( 'Groups', 'component directory title', 'buddypress' ),
    169             'notification_callback' => 'groups_format_notifications',
    170             'search_string'         => _x( 'Search Groups...', 'Component directory search', 'buddypress' ),
    171             'global_tables'         => $global_tables,
    172             'meta_tables'           => $meta_tables,
    173         );
    174 
    175         parent::setup_globals( $args );
    176 
    177         /* Single Group Globals **********************************************/
    178 
    179         // Are we viewing a single group?
    180         if ( bp_is_groups_component() && $group_id = BP_Groups_Group::group_exists( bp_current_action() ) ) {
    181 
    182             $bp->is_single_item  = true;
    183 
    184             /**
    185              * Filters the current PHP Class being used.
    186              *
    187              * @since 1.5.0
    188              *
    189              * @param string $value Name of the class being used.
    190              */
    191             $current_group_class = apply_filters( 'bp_groups_current_group_class', 'BP_Groups_Group' );
    192 
    193             if ( $current_group_class == 'BP_Groups_Group' ) {
    194                 $this->current_group = groups_get_group( array(
    195                     'group_id'        => $group_id,
    196                     'populate_extras' => true,
    197                 ) );
    198 
    199             } else {
    200 
    201                 /**
    202                  * Filters the current group object being instantiated from previous filter.
    203                  *
    204                  * @since 1.5.0
    205                  *
    206                  * @param object $value Newly instantiated object for the group.
    207                  */
    208                 $this->current_group = apply_filters( 'bp_groups_current_group_object', new $current_group_class( $group_id ) );
    209             }
    210 
    211             // When in a single group, the first action is bumped down one because of the
    212             // group name, so we need to adjust this and set the group name to current_item.
    213             $bp->current_item   = bp_current_action();
    214             $bp->current_action = bp_action_variable( 0 );
    215             array_shift( $bp->action_variables );
    216 
    217             // Using "item" not "group" for generic support in other components.
    218             if ( bp_current_user_can( 'bp_moderate' ) ) {
    219                 bp_update_is_item_admin( true, 'groups' );
    220             } else {
    221                 bp_update_is_item_admin( groups_is_user_admin( bp_loggedin_user_id(), $this->current_group->id ), 'groups' );
    222             }
    223 
    224             // If the user is not an admin, check if they are a moderator.
    225             if ( ! bp_is_item_admin() ) {
    226                 bp_update_is_item_mod  ( groups_is_user_mod  ( bp_loggedin_user_id(), $this->current_group->id ), 'groups' );
    227             }
    228 
    229             // Is the logged in user a member of the group?
    230             if ( ( is_user_logged_in() && groups_is_user_member( bp_loggedin_user_id(), $this->current_group->id ) ) ) {
    231                 $this->current_group->is_user_member = true;
    232             } else {
    233                 $this->current_group->is_user_member = false;
    234             }
    235 
    236             // Should this group be visible to the logged in user?
    237             if ( 'public' == $this->current_group->status || $this->current_group->is_user_member ) {
    238                 $this->current_group->is_visible = true;
    239             } else {
    240                 $this->current_group->is_visible = false;
    241             }
    242 
    243             // If this is a private or hidden group, does the user have access?
    244             if ( 'private' == $this->current_group->status || 'hidden' == $this->current_group->status ) {
    245                 if ( $this->current_group->is_user_member && is_user_logged_in() || bp_current_user_can( 'bp_moderate' ) ) {
    246                     $this->current_group->user_has_access = true;
    247                 } else {
    248                     $this->current_group->user_has_access = false;
    249                 }
    250             } else {
    251                 $this->current_group->user_has_access = true;
    252             }
    253 
    254             // Check once if the current group has a custom front template.
    255             $this->current_group->front_template = bp_groups_get_front_template( $this->current_group );
    256 
    257         // Set current_group to 0 to prevent debug errors.
    258         } else {
    259             $this->current_group = 0;
    260         }
    261 
    262         /**
    263          * Filters the list of illegal groups names/slugs.
    264          *
    265          * @since 1.0.0
    266          *
    267          * @param array $value Array of illegal group names/slugs.
    268          */
    269         $this->forbidden_names = apply_filters( 'groups_forbidden_names', array(
    270             'my-groups',
    271             'create',
    272             'invites',
    273             'send-invites',
    274             'forum',
    275             'delete',
    276             'add',
    277             'admin',
    278             'request-membership',
    279             'members',
    280             'settings',
    281             'avatar',
    282             $this->slug,
    283             $this->root_slug,
    284         ) );
    285 
    286         // If the user was attempting to access a group, but no group by that name was found, 404.
    287         if ( bp_is_groups_component() && empty( $this->current_group ) && bp_current_action() && !in_array( bp_current_action(), $this->forbidden_names ) ) {
    288             bp_do_404();
    289             return;
    290         }
    291 
    292         /**
    293          * Filters the preconfigured groups creation steps.
    294          *
    295          * @since 1.1.0
    296          *
    297          * @param array $value Array of preconfigured group creation steps.
    298          */
    299         $this->group_creation_steps = apply_filters( 'groups_create_group_steps', array(
    300             'group-details'  => array(
    301                 'name'       => _x( 'Details', 'Group screen nav', 'buddypress' ),
    302                 'position'   => 0
    303             ),
    304             'group-settings' => array(
    305                 'name'       => _x( 'Settings', 'Group screen nav', 'buddypress' ),
    306                 'position'   => 10
    307             )
    308         ) );
    309 
    310         // If avatar uploads are not disabled, add avatar option.
    311         $disabled_avatar_uploads = (int) bp_disable_group_avatar_uploads();
    312         if ( ! $disabled_avatar_uploads && $bp->avatar->show_avatars ) {
    313             $this->group_creation_steps['group-avatar'] = array(
    314                 'name'     => _x( 'Photo', 'Group screen nav', 'buddypress' ),
    315                 'position' => 20
    316             );
    317         }
    318 
    319         if ( bp_group_use_cover_image_header() ) {
    320             $this->group_creation_steps['group-cover-image'] = array(
    321                 'name'     => _x( 'Cover Image', 'Group screen nav', 'buddypress' ),
    322                 'position' => 25
    323             );
    324         }
    325 
    326         // If friends component is active, add invitations.
    327         if ( bp_is_active( 'friends' ) ) {
    328             $this->group_creation_steps['group-invites'] = array(
    329                 'name'     => _x( 'Invites',  'Group screen nav', 'buddypress' ),
    330                 'position' => 30
    331             );
    332         }
    333 
    334         /**
    335          * Filters the list of valid groups statuses.
    336          *
    337          * @since 1.1.0
    338          *
    339          * @param array $value Array of valid group statuses.
    340          */
    341         $this->valid_status = apply_filters( 'groups_valid_status', array(
    342             'public',
    343             'private',
    344             'hidden'
    345         ) );
    346 
    347         // Auto join group when non group member performs group activity.
    348         $this->auto_join = defined( 'BP_DISABLE_AUTO_GROUP_JOIN' ) && BP_DISABLE_AUTO_GROUP_JOIN ? false : true;
    349     }
    350 
    351     /**
    352      * Set up canonical stack for this component.
    353      *
    354      * @since 2.1.0
    355      */
    356     public function setup_canonical_stack() {
    357         if ( ! bp_is_groups_component() ) {
    358             return;
    359         }
    360 
    361         if ( empty( $this->current_group ) ) {
    362             return;
    363         }
    364 
    365         /**
    366          * Filters the default groups extension.
    367          *
    368          * @since 1.6.0
    369          *
    370          * @param string $value BP_GROUPS_DEFAULT_EXTENSION constant if defined,
    371          *                      else 'home'.
    372          */
    373         $this->default_extension = apply_filters( 'bp_groups_default_extension', defined( 'BP_GROUPS_DEFAULT_EXTENSION' ) ? BP_GROUPS_DEFAULT_EXTENSION : 'home' );
    374 
    375         $bp = buddypress();
    376 
    377         // If the activity component is not active and the current group has no custom front, members are displayed in the home nav.
    378         if ( 'members' === $this->default_extension && ! bp_is_active( 'activity' ) && ! $this->current_group->front_template ) {
    379             $this->default_extension = 'home';
    380         }
    381 
    382         if ( ! bp_current_action() ) {
    383             $bp->current_action = $this->default_extension;
    384         }
    385 
    386         // Prepare for a redirect to the canonical URL.
    387         $bp->canonical_stack['base_url'] = bp_get_group_permalink( $this->current_group );
    388 
    389         if ( bp_current_action() ) {
    390             $bp->canonical_stack['action'] = bp_current_action();
    391         }
    392 
    393         /**
    394          * If there's no custom front.php template for the group, we need to make sure the canonical stack action
    395          * is set to 'home' in these 2 cases:
    396          *
    397          * - the current action is 'activity' (eg: site.url/groups/single/activity) and the Activity component is active
    398          * - the current action is 'members' (eg: site.url/groups/single/members) and the Activity component is *not* active.
    399          */
    400         if ( ! $this->current_group->front_template && ( bp_is_current_action( 'activity' ) || ( ! bp_is_active( 'activity' ) && bp_is_current_action( 'members' ) ) ) ) {
    401             $bp->canonical_stack['action'] = 'home';
    402         }
    403 
    404         if ( ! empty( $bp->action_variables ) ) {
    405             $bp->canonical_stack['action_variables'] = bp_action_variables();
    406         }
    407 
    408         // When viewing the default extension, the canonical URL should not have
    409         // that extension's slug, unless more has been tacked onto the URL via
    410         // action variables.
    411         if ( bp_is_current_action( $this->default_extension ) && empty( $bp->action_variables ) )  {
    412             unset( $bp->canonical_stack['action'] );
    413         }
    414     }
    415 
    416     /**
    417      * Set up component navigation.
    418      *
    419      * @since 1.5.0
    420      *
    421      * @see BP_Component::setup_nav() for a description of arguments.
    422      *
    423      * @param array $main_nav Optional. See BP_Component::setup_nav() for description.
    424      * @param array $sub_nav  Optional. See BP_Component::setup_nav() for description.
    425      */
    426     public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
    427 
    428         // Determine user to use.
    429         if ( bp_displayed_user_domain() ) {
    430             $user_domain = bp_displayed_user_domain();
    431         } elseif ( bp_loggedin_user_domain() ) {
    432             $user_domain = bp_loggedin_user_domain();
    433         } else {
    434             $user_domain = false;
    435         }
    436 
    437         // Only grab count if we're on a user page.
    438         if ( bp_is_user() ) {
    439             $class    = ( 0 === groups_total_groups_for_user( bp_displayed_user_id() ) ) ? 'no-count' : 'count';
    440             $nav_name = sprintf( _x( 'Groups <span class="%s">%s</span>', 'Group screen nav with counter', 'buddypress' ), esc_attr( $class ), bp_get_total_group_count_for_user() );
    441         } else {
    442             $nav_name = _x( 'Groups', 'Group screen nav without counter', 'buddypress' );
    443         }
    444 
    445         $slug = bp_get_groups_slug();
    446 
    447         // Add 'Groups' to the main navigation.
    448         $main_nav = array(
    449             'name'                => $nav_name,
    450             'slug'                => $slug,
    451             'position'            => 70,
    452             'screen_function'     => 'groups_screen_my_groups',
    453             'default_subnav_slug' => 'my-groups',
    454             'item_css_id'         => $this->id
    455         );
    456 
    457         if ( ! empty( $user_domain ) ) {
    458             $access      = bp_core_can_edit_settings();
    459             $groups_link = trailingslashit( $user_domain . $slug );
    460 
    461             // Add the My Groups nav item.
    462             $sub_nav[] = array(
    463                 'name'            => __( 'Memberships', 'buddypress' ),
    464                 'slug'            => 'my-groups',
    465                 'parent_url'      => $groups_link,
    466                 'parent_slug'     => $slug,
    467                 'screen_function' => 'groups_screen_my_groups',
    468                 'position'        => 10,
    469                 'item_css_id'     => 'groups-my-groups'
    470             );
    471 
    472             // Add the Group Invites nav item.
    473             $sub_nav[] = array(
    474                 'name'            => __( 'Invitations', 'buddypress' ),
    475                 'slug'            => 'invites',
    476                 'parent_url'      => $groups_link,
    477                 'parent_slug'     => $slug,
    478                 'screen_function' => 'groups_screen_group_invites',
    479                 'user_has_access' => $access,
    480                 'position'        => 30
    481             );
    482 
    483             parent::setup_nav( $main_nav, $sub_nav );
    484         }
    485 
    486         if ( bp_is_groups_component() && bp_is_single_item() ) {
    487 
    488             // Reset sub nav.
    489             $sub_nav = array();
    490 
    491             // Add 'Groups' to the main navigation.
    492             $main_nav = array(
    493                 'name'                => __( 'Memberships', 'buddypress' ),
    494                 'slug'                => $this->current_group->slug,
    495                 'position'            => -1, // Do not show in BuddyBar.
    496                 'screen_function'     => 'groups_screen_group_home',
    497                 'default_subnav_slug' => $this->default_extension,
    498                 'item_css_id'         => $this->id
    499             );
    500 
    501             $group_link = bp_get_group_permalink( $this->current_group );
    502 
    503             // Add the "Home" subnav item, as this will always be present.
    504             $sub_nav[] = array(
    505                 'name'            =>  _x( 'Home', 'Group screen navigation title', 'buddypress' ),
    506                 'slug'            => 'home',
    507                 'parent_url'      => $group_link,
    508                 'parent_slug'     => $this->current_group->slug,
    509                 'screen_function' => 'groups_screen_group_home',
    510                 'position'        => 10,
    511                 'item_css_id'     => 'home'
    512             );
    513 
    514             // If this is a private group, and the user is not a
    515             // member and does not have an outstanding invitation,
    516             // show a "Request Membership" nav item.
    517             if ( is_user_logged_in() &&
    518                  ! $this->current_group->is_user_member &&
    519                  ! groups_check_for_membership_request( bp_loggedin_user_id(), $this->current_group->id ) &&
    520                  $this->current_group->status == 'private' &&
    521                  ! groups_check_user_has_invite( bp_loggedin_user_id(), $this->current_group->id )
    522                 ) {
    523 
    524                 $sub_nav[] = array(
    525                     'name'            => _x( 'Request Membership','Group screen nav', 'buddypress' ),
    526                     'slug'            => 'request-membership',
    527                     'parent_url'      => $group_link,
    528                     'parent_slug'     => $this->current_group->slug,
    529                     'screen_function' => 'groups_screen_group_request_membership',
    530                     'position'        => 30
    531                 );
    532             }
    533 
    534             // Forums are enabled and turned on.
    535             if ( $this->current_group->enable_forum && bp_is_active( 'forums' ) ) {
    536                 $sub_nav[] = array(
    537                     'name'            => _x( 'Forum', 'My Group screen nav', 'buddypress' ),
    538                     'slug'            => 'forum',
    539                     'parent_url'      => $group_link,
    540                     'parent_slug'     => $this->current_group->slug,
    541                     'screen_function' => 'groups_screen_group_forum',
    542                     'position'        => 40,
    543                     'user_has_access' => $this->current_group->user_has_access,
    544                     'item_css_id'     => 'forums'
    545                 );
    546             }
    547 
    548             if ( $this->current_group->front_template || bp_is_active( 'activity' ) ) {
    549                 /**
    550                  * If the theme is using a custom front, create activity subnav.
    551                  */
    552                 if ( $this->current_group->front_template && bp_is_active( 'activity' ) ) {
    553                     $sub_nav[] = array(
    554                         'name'            => _x( 'Activity', 'My Group screen nav', 'buddypress' ),
    555                         'slug'            => 'activity',
    556                         'parent_url'      => $group_link,
    557                         'parent_slug'     => $this->current_group->slug,
    558                         'screen_function' => 'groups_screen_group_activity',
    559                         'position'        => 11,
    560                         'user_has_access' => $this->current_group->user_has_access,
    561                         'item_css_id'     => 'activity',
    562                         'no_access_url'   => $group_link,
    563                     );
    564                 }
    565 
    566                 /**
    567                  * Only add the members subnav if it's not the home's nav.
    568                  */
    569                 $sub_nav[] = array(
    570                     'name'            => sprintf( _x( 'Members %s', 'My Group screen nav', 'buddypress' ), '<span>' . number_format( $this->current_group->total_member_count ) . '</span>' ),
    571                     'slug'            => 'members',
    572                     'parent_url'      => $group_link,
    573                     'parent_slug'     => $this->current_group->slug,
    574                     'screen_function' => 'groups_screen_group_members',
    575                     'position'        => 60,
    576                     'user_has_access' => $this->current_group->user_has_access,
    577                     'item_css_id'     => 'members',
    578                     'no_access_url'   => $group_link,
    579                 );
    580             }
    581 
    582             if ( bp_is_active( 'friends' ) && bp_groups_user_can_send_invites() ) {
    583                 $sub_nav[] = array(
    584                     'name'            => _x( 'Send Invites', 'My Group screen nav', 'buddypress' ),
    585                     'slug'            => 'send-invites',
    586                     'parent_url'      => $group_link,
    587                     'parent_slug'     => $this->current_group->slug,
    588                     'screen_function' => 'groups_screen_group_invite',
    589                     'item_css_id'     => 'invite',
    590                     'position'        => 70,
    591                     'user_has_access' => $this->current_group->user_has_access,
    592                     'no_access_url'   => $group_link,
    593                 );
    594             }
    595 
    596             // If the user is a group admin, then show the group admin nav item.
    597             if ( bp_is_item_admin() ) {
    598                 $sub_nav[] = array(
    599                     'name'            => _x( 'Manage', 'My Group screen nav', 'buddypress' ),
    600                     'slug'            => 'admin',
    601                     'parent_url'      => $group_link,
    602                     'parent_slug'     => $this->current_group->slug,
    603                     'screen_function' => 'groups_screen_group_admin',
    604                     'position'        => 1000,
    605                     'user_has_access' => true,
    606                     'item_css_id'     => 'admin',
    607                     'no_access_url'   => $group_link,
    608                 );
    609 
    610                 $admin_link = trailingslashit( $group_link . 'admin' );
    611 
    612                 // Common params to all nav items.
    613                 $default_params = array(
    614                     'parent_url'        => $admin_link,
    615                     'parent_slug'       => $this->current_group->slug . '_manage',
    616                     'screen_function'   => 'groups_screen_group_admin',
    617                     'user_has_access'   => bp_is_item_admin(),
    618                     'show_in_admin_bar' => true,
    619                 );
    620 
    621                 $sub_nav[] = array_merge( array(
    622                     'name'     => __( 'Details', 'buddypress' ),
    623                     'slug'     => 'edit-details',
    624                     'position' => 0,
    625                 ), $default_params );
    626 
    627                 $sub_nav[] = array_merge( array(
    628                     'name'     => __( 'Settings', 'buddypress' ),
    629                     'slug'     => 'group-settings',
    630                     'position' => 10,
    631                 ), $default_params );
    632 
    633                 if ( ! bp_disable_group_avatar_uploads() && buddypress()->avatar->show_avatars ) {
    634                     $sub_nav[] = array_merge( array(
    635                         'name'     => __( 'Photo', 'buddypress' ),
    636                         'slug'     => 'group-avatar',
    637                         'position' => 20,
    638                     ), $default_params );
    639                 }
    640 
    641                 if ( bp_group_use_cover_image_header() ) {
    642                     $sub_nav[] = array_merge( array(
    643                         'name'     => __( 'Cover Image', 'buddypress' ),
    644                         'slug'     => 'group-cover-image',
    645                         'position' => 25,
    646                     ), $default_params );
    647                 }
    648 
    649                 $sub_nav[] = array_merge( array(
    650                     'name'     => __( 'Members', 'buddypress' ),
    651                     'slug'     => 'manage-members',
    652                     'position' => 30,
    653                 ), $default_params );
    654 
    655                 if ( 'private' == $this->current_group->status ) {
    656                     $sub_nav[] = array_merge( array(
    657                         'name'     => __( 'Requests', 'buddypress' ),
    658                         'slug'     => 'membership-requests',
    659                         'position' => 40,
    660                     ), $default_params );
    661                 }
    662 
    663                 $sub_nav[] = array_merge( array(
    664                     'name'     => __( 'Delete', 'buddypress' ),
    665                     'slug'     => 'delete-group',
    666                     'position' => 1000,
    667                 ), $default_params );
    668             }
    669 
    670             parent::setup_nav( $main_nav, $sub_nav );
    671         }
    672 
    673         if ( isset( $this->current_group->user_has_access ) ) {
    674 
    675             /**
    676              * Fires at the end of the groups navigation setup if user has access.
    677              *
    678              * @since 1.0.2
    679              *
    680              * @param bool $user_has_access Whether or not user has access.
    681              */
    682             do_action( 'groups_setup_nav', $this->current_group->user_has_access );
    683         } else {
    684 
    685             /** This action is documented in bp-groups/bp-groups-loader.php */
    686             do_action( 'groups_setup_nav');
    687         }
    688     }
    689 
    690     /**
    691      * Set up the component entries in the WordPress Admin Bar.
    692      *
    693      * @since 1.5.0
    694      *
    695      * @see BP_Component::setup_nav() for a description of the $wp_admin_nav
    696      *      parameter array.
    697      *
    698      * @param array $wp_admin_nav See BP_Component::setup_admin_bar() for a description.
    699      */
    700     public function setup_admin_bar( $wp_admin_nav = array() ) {
    701 
    702         // Menus for logged in user.
    703         if ( is_user_logged_in() ) {
    704 
    705             // Setup the logged in user variables.
    706             $groups_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() );
    707 
    708             // Pending group invites.
    709             $count   = groups_get_invite_count_for_user();
    710             $title   = _x( 'Groups', 'My Account Groups', 'buddypress' );
    711             $pending = _x( 'No Pending Invites', 'My Account Groups sub nav', 'buddypress' );
    712 
    713             if ( ! empty( $count['total'] ) ) {
    714                 $title   = sprintf( _x( 'Groups <span class="count">%s</span>',          'My Account Groups nav',     'buddypress' ), bp_core_number_format( $count ) );
    715                 $pending = sprintf( _x( 'Pending Invites <span class="count">%s</span>', 'My Account Groups sub nav', 'buddypress' ), bp_core_number_format( $count ) );
    716             }
    717 
    718             // Add the "My Account" sub menus.
    719             $wp_admin_nav[] = array(
    720                 'parent' => buddypress()->my_account_menu_id,
    721                 'id'     => 'my-account-' . $this->id,
    722                 'title'  => $title,
    723                 'href'   => $groups_link
    724             );
    725 
    726             // My Groups.
    727             $wp_admin_nav[] = array(
    728                 'parent' => 'my-account-' . $this->id,
    729                 'id'     => 'my-account-' . $this->id . '-memberships',
    730                 'title'  => _x( 'Memberships', 'My Account Groups sub nav', 'buddypress' ),
    731                 'href'   => $groups_link
    732             );
    733 
    734             // Invitations.
    735             $wp_admin_nav[] = array(
    736                 'parent' => 'my-account-' . $this->id,
    737                 'id'     => 'my-account-' . $this->id . '-invites',
    738                 'title'  => $pending,
    739                 'href'   => trailingslashit( $groups_link . 'invites' )
    740             );
    741 
    742             // Create a Group.
    743             if ( bp_user_can_create_groups() ) {
    744                 $wp_admin_nav[] = array(
    745                     'parent' => 'my-account-' . $this->id,
    746                     'id'     => 'my-account-' . $this->id . '-create',
    747                     'title'  => _x( 'Create a Group', 'My Account Groups sub nav', 'buddypress' ),
    748                     'href'   => trailingslashit( bp_get_groups_directory_permalink() . 'create' )
    749                 );
    750             }
    751         }
    752 
    753         parent::setup_admin_bar( $wp_admin_nav );
    754     }
    755 
    756     /**
    757      * Set up the title for pages and <title>.
    758      *
    759      * @since 1.5.0
    760      */
    761     public function setup_title() {
    762 
    763         if ( bp_is_groups_component() ) {
    764             $bp = buddypress();
    765 
    766             if ( bp_is_my_profile() && !bp_is_single_item() ) {
    767                 $bp->bp_options_title = _x( 'Memberships', 'My Groups page <title>', 'buddypress' );
    768 
    769             } elseif ( !bp_is_my_profile() && !bp_is_single_item() ) {
    770                 $bp->bp_options_avatar = bp_core_fetch_avatar( array(
    771                     'item_id' => bp_displayed_user_id(),
    772                     'type'    => 'thumb',
    773                     'alt'     => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_get_displayed_user_fullname() )
    774                 ) );
    775                 $bp->bp_options_title = bp_get_displayed_user_fullname();
    776 
    777             // We are viewing a single group, so set up the
    778             // group navigation menu using the $this->current_group global.
    779             } elseif ( bp_is_single_item() ) {
    780                 $bp->bp_options_title  = $this->current_group->name;
    781                 $bp->bp_options_avatar = bp_core_fetch_avatar( array(
    782                     'item_id'    => $this->current_group->id,
    783                     'object'     => 'group',
    784                     'type'       => 'thumb',
    785                     'avatar_dir' => 'group-avatars',
    786                     'alt'        => __( 'Group Profile Photo', 'buddypress' )
    787                 ) );
    788 
    789                 if ( empty( $bp->bp_options_avatar ) ) {
    790                     $bp->bp_options_avatar = '<img src="' . esc_url( bp_core_avatar_default_thumb() ) . '" alt="' . esc_attr__( 'No Group Profile Photo', 'buddypress' ) . '" class="avatar" />';
    791                 }
    792             }
    793         }
    794 
    795         parent::setup_title();
    796     }
    797 
    798     /**
    799      * Setup cache groups
    800      *
    801      * @since 2.2.0
    802      */
    803     public function setup_cache_groups() {
    804 
    805         // Global groups.
    806         wp_cache_add_global_groups( array(
    807             'bp_groups',
    808             'bp_group_admins',
    809             'bp_group_invite_count',
    810             'group_meta'
    811         ) );
    812 
    813         parent::setup_cache_groups();
    814     }
    815 }
     17require dirname( __FILE__ ) . '/classes/class-bp-groups-component.php';
    81618
    81719/**
  • trunk/src/bp-groups/bp-groups-screens.php

    r10454 r10520  
    1414// Exit if accessed directly.
    1515defined( 'ABSPATH' ) || exit;
     16
     17require dirname( __FILE__ ) . '/classes/class-bp-groups-theme-compat.php';
    1618
    1719/**
     
    14761478/** Theme Compatibility *******************************************************/
    14771479
    1478 /**
    1479  * The main theme compat class for BuddyPress Groups.
    1480  *
    1481  * This class sets up the necessary theme compatibility actions to safely output
    1482  * group template parts to the_title and the_content areas of a theme.
    1483  *
    1484  * @since 1.7.0
    1485  */
    1486 class BP_Groups_Theme_Compat {
    1487 
    1488     /**
    1489      * Set up theme compatibility for the Groups component.
    1490      *
    1491      * @since 1.7.0
    1492      */
    1493     public function __construct() {
    1494         add_action( 'bp_setup_theme_compat', array( $this, 'is_group' ) );
    1495     }
    1496 
    1497     /**
    1498      * Are we looking at something that needs group theme compatibility?
    1499      *
    1500      * @since 1.7.0
    1501      */
    1502     public function is_group() {
    1503 
    1504         // Bail if not looking at a group.
    1505         if ( ! bp_is_groups_component() )
    1506             return;
    1507 
    1508         // Group Directory.
    1509         if ( ! bp_current_action() && ! bp_current_item() ) {
    1510             bp_update_is_directory( true, 'groups' );
    1511 
    1512             /**
    1513              * Fires at the start of the group theme compatibility setup.
    1514              *
    1515              * @since 1.1.0
    1516              */
    1517             do_action( 'groups_directory_groups_setup' );
    1518 
    1519             add_filter( 'bp_get_buddypress_template',                array( $this, 'directory_template_hierarchy' ) );
    1520             add_action( 'bp_template_include_reset_dummy_post_data', array( $this, 'directory_dummy_post' ) );
    1521             add_filter( 'bp_replace_the_content',                    array( $this, 'directory_content'    ) );
    1522 
    1523         // Creating a group.
    1524         } elseif ( bp_is_groups_component() && bp_is_current_action( 'create' ) ) {
    1525             add_filter( 'bp_get_buddypress_template',                array( $this, 'create_template_hierarchy' ) );
    1526             add_action( 'bp_template_include_reset_dummy_post_data', array( $this, 'create_dummy_post' ) );
    1527             add_filter( 'bp_replace_the_content',                    array( $this, 'create_content'    ) );
    1528 
    1529         // Group page.
    1530         } elseif ( bp_is_single_item() ) {
    1531             add_filter( 'bp_get_buddypress_template',                array( $this, 'single_template_hierarchy' ) );
    1532             add_action( 'bp_template_include_reset_dummy_post_data', array( $this, 'single_dummy_post' ) );
    1533             add_filter( 'bp_replace_the_content',                    array( $this, 'single_content'    ) );
    1534 
    1535         }
    1536     }
    1537 
    1538     /** Directory *********************************************************/
    1539 
    1540     /**
    1541      * Add template hierarchy to theme compat for the group directory page.
    1542      *
    1543      * This is to mirror how WordPress has
    1544      * {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
    1545      *
    1546      * @since 1.8.0
    1547      *
    1548      * @param string $templates The templates from bp_get_theme_compat_templates().
    1549      * @return array $templates Array of custom templates to look for.
    1550      */
    1551     public function directory_template_hierarchy( $templates ) {
    1552 
    1553         /**
    1554          * Filters the Groups directory page template hierarchy based on priority.
    1555          *
    1556          * @since 1.8.0
    1557          *
    1558          * @param array $value Array of default template files to use.
    1559          */
    1560         $new_templates = apply_filters( 'bp_template_hierarchy_groups_directory', array(
    1561             'groups/index-directory.php'
    1562         ) );
    1563 
    1564         // Merge new templates with existing stack.
    1565         // @see bp_get_theme_compat_templates().
    1566         $templates = array_merge( (array) $new_templates, $templates );
    1567 
    1568         return $templates;
    1569     }
    1570 
    1571     /**
    1572      * Update the global $post with directory data.
    1573      *
    1574      * @since 1.7.0
    1575      */
    1576     public function directory_dummy_post() {
    1577         bp_theme_compat_reset_post( array(
    1578             'ID'             => 0,
    1579             'post_title'     => bp_get_directory_title( 'groups' ),
    1580             'post_author'    => 0,
    1581             'post_date'      => 0,
    1582             'post_content'   => '',
    1583             'post_type'      => 'page',
    1584             'post_status'    => 'publish',
    1585             'is_page'        => true,
    1586             'comment_status' => 'closed'
    1587         ) );
    1588     }
    1589 
    1590     /**
    1591      * Filter the_content with the groups index template part.
    1592      *
    1593      * @since 1.7.0
    1594      */
    1595     public function directory_content() {
    1596         return bp_buffer_template_part( 'groups/index', null, false );
    1597     }
    1598 
    1599     /** Create ************************************************************/
    1600 
    1601     /**
    1602      * Add custom template hierarchy to theme compat for the group create page.
    1603      *
    1604      * This is to mirror how WordPress has
    1605      * {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
    1606      *
    1607      * @since 1.8.0
    1608      *
    1609      * @param string $templates The templates from bp_get_theme_compat_templates().
    1610      * @return array $templates Array of custom templates to look for.
    1611      */
    1612     public function create_template_hierarchy( $templates ) {
    1613 
    1614         /**
    1615          * Filters the Groups create page template hierarchy based on priority.
    1616          *
    1617          * @since 1.8.0
    1618          *
    1619          * @param array $value Array of default template files to use.
    1620          */
    1621         $new_templates = apply_filters( 'bp_template_hierarchy_groups_create', array(
    1622             'groups/index-create.php'
    1623         ) );
    1624 
    1625         // Merge new templates with existing stack.
    1626         // @see bp_get_theme_compat_templates().
    1627         $templates = array_merge( $new_templates, $templates );
    1628 
    1629         return $templates;
    1630     }
    1631 
    1632     /**
    1633      * Update the global $post with create screen data.
    1634      *
    1635      * @since 1.7.0
    1636      */
    1637     public function create_dummy_post() {
    1638 
    1639         $title = _x( 'Groups', 'Group creation page', 'buddypress' );
    1640 
    1641         bp_theme_compat_reset_post( array(
    1642             'ID'             => 0,
    1643             'post_title'     => $title,
    1644             'post_author'    => 0,
    1645             'post_date'      => 0,
    1646             'post_content'   => '',
    1647             'post_type'      => 'page',
    1648             'post_status'    => 'publish',
    1649             'is_page'        => true,
    1650             'comment_status' => 'closed'
    1651         ) );
    1652     }
    1653 
    1654     /**
    1655      * Filter the_content with the create screen template part.
    1656      *
    1657      * @since 1.7.0
    1658      */
    1659     public function create_content() {
    1660         return bp_buffer_template_part( 'groups/create', null, false );
    1661     }
    1662 
    1663     /** Single ************************************************************/
    1664 
    1665     /**
    1666      * Add custom template hierarchy to theme compat for group pages.
    1667      *
    1668      * This is to mirror how WordPress has
    1669      * {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
    1670      *
    1671      * @since 1.8.0
    1672      *
    1673      * @param string $templates The templates from bp_get_theme_compat_templates().
    1674      * @return array $templates Array of custom templates to look for.
    1675      */
    1676     public function single_template_hierarchy( $templates ) {
    1677         // Setup some variables we're going to reference in our custom templates.
    1678         $group = groups_get_current_group();
    1679 
    1680         /**
    1681          * Filters the Groups single pages template hierarchy based on priority.
    1682          *
    1683          * @since 1.8.0
    1684          *
    1685          * @param array $value Array of default template files to use.
    1686          */
    1687         $new_templates = apply_filters( 'bp_template_hierarchy_groups_single_item', array(
    1688             'groups/single/index-id-'     . sanitize_file_name( bp_get_current_group_id() )   . '.php',
    1689             'groups/single/index-slug-'   . sanitize_file_name( bp_get_current_group_slug() ) . '.php',
    1690             'groups/single/index-action-' . sanitize_file_name( bp_current_action() )         . '.php',
    1691             'groups/single/index-status-' . sanitize_file_name( $group->status )              . '.php',
    1692             'groups/single/index.php'
    1693         ) );
    1694 
    1695         // Merge new templates with existing stack.
    1696         // @see bp_get_theme_compat_templates().
    1697         $templates = array_merge( (array) $new_templates, $templates );
    1698 
    1699         return $templates;
    1700     }
    1701 
    1702     /**
    1703      * Update the global $post with single group data.
    1704      *
    1705      * @since 1.7.0
    1706      */
    1707     public function single_dummy_post() {
    1708         bp_theme_compat_reset_post( array(
    1709             'ID'             => 0,
    1710             'post_title'     => bp_get_current_group_name(),
    1711             'post_author'    => 0,
    1712             'post_date'      => 0,
    1713             'post_content'   => '',
    1714             'post_type'      => 'page',
    1715             'post_status'    => 'publish',
    1716             'is_page'        => true,
    1717             'comment_status' => 'closed'
    1718         ) );
    1719     }
    1720 
    1721     /**
    1722      * Filter the_content with the single group template part.
    1723      *
    1724      * @since 1.7.0
    1725      */
    1726     public function single_content() {
    1727         return bp_buffer_template_part( 'groups/single/home', null, false );
    1728     }
    1729 }
    17301480new BP_Groups_Theme_Compat();
  • trunk/src/bp-groups/bp-groups-template.php

    r10454 r10520  
    1111defined( 'ABSPATH' ) || exit;
    1212
     13require dirname( __FILE__ ) . '/classes/class-bp-groups-template.php';
     14require dirname( __FILE__ ) . '/classes/class-bp-groups-group-members-template.php';
     15require dirname( __FILE__ ) . '/classes/class-bp-groups-memberships-requests-template.php';
     16require dirname( __FILE__ ) . '/classes/class-bp-groups-invite-template.php';
     17
    1318/**
    1419 * Output the groups component slug.
     
    9196        return apply_filters( 'bp_get_groups_directory_permalink', trailingslashit( bp_get_root_domain() . '/' . bp_get_groups_root_slug() ) );
    9297    }
    93 
    94 /**
    95  * The main Groups template loop class.
    96  *
    97  * Responsible for loading a group of groups into a loop for display.
    98  *
    99  * @since 1.2.0
    100  */
    101 class BP_Groups_Template {
    102 
    103     /**
    104      * The loop iterator.
    105      *
    106      * @var int
    107      * @since 1.2.0
    108      */
    109     public $current_group = -1;
    110 
    111     /**
    112      * The number of groups returned by the paged query.
    113      *
    114      * @var int
    115      * @since 1.2.0
    116      */
    117     public $group_count;
    118 
    119     /**
    120      * Array of groups located by the query.
    121      *
    122      * @var array
    123      * @since 1.2.0
    124      */
    125     public $groups;
    126 
    127     /**
    128      * The group object currently being iterated on.
    129      *
    130      * @var object
    131      * @since 1.2.0
    132      */
    133     public $group;
    134 
    135     /**
    136      * A flag for whether the loop is currently being iterated.
    137      *
    138      * @var bool
    139      * @since 1.2.0
    140      */
    141     public $in_the_loop;
    142 
    143     /**
    144      * The page number being requested.
    145      *
    146      * @var string
    147      * @since 1.2.0
    148      */
    149     public $pag_page;
    150 
    151     /**
    152      * The number of items being requested per page.
    153      *
    154      * @var string
    155      * @since 1.2.0
    156      */
    157     public $pag_num;
    158 
    159     /**
    160      * An HTML string containing pagination links.
    161      *
    162      * @var string
    163      * @since 1.2.0
    164      */
    165     public $pag_links;
    166 
    167     /**
    168      * The total number of groups matching the query parameters.
    169      *
    170      * @var int
    171      * @since 1.2.0
    172      */
    173     public $total_group_count;
    174 
    175     /**
    176      * Whether the template loop is for a single group page.
    177      *
    178      * @var bool
    179      * @since 1.2.0
    180      */
    181     public $single_group = false;
    182 
    183     /**
    184      * Field to sort by.
    185      *
    186      * @var string
    187      * @since 1.2.0
    188      */
    189     public $sort_by;
    190 
    191     /**
    192      * Sort order.
    193      *
    194      * @var string
    195      * @since 1.2.0
    196      */
    197     public $order;
    198 
    199     /**
    200      * Constructor method.
    201      *
    202      * @see BP_Groups_Group::get() for an in-depth description of arguments.
    203      *
    204      * @param array $args {
    205      *     Array of arguments. Accepts all arguments accepted by
    206      *     {@link BP_Groups_Group::get()}. In cases where the default
    207      *     values of the params differ, they have been discussed below.
    208      *     @type int $per_page Default: 20.
    209      *     @type int $page Default: 1.
    210      * }
    211      */
    212     function __construct( $args = array() ){
    213 
    214         // Backward compatibility with old method of passing arguments.
    215         if ( ! is_array( $args ) || func_num_args() > 1 ) {
    216             _deprecated_argument( __METHOD__, '1.7', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
    217 
    218             $old_args_keys = array(
    219                 0  => 'user_id',
    220                 1  => 'type',
    221                 2  => 'page',
    222                 3  => 'per_page',
    223                 4  => 'max',
    224                 5  => 'slug',
    225                 6  => 'search_terms',
    226                 7  => 'populate_extras',
    227                 8  => 'include',
    228                 9  => 'exclude',
    229                 10 => 'show_hidden',
    230                 11 => 'page_arg',
    231             );
    232 
    233             $func_args = func_get_args();
    234             $args      = bp_core_parse_args_array( $old_args_keys, $func_args );
    235         }
    236 
    237         $defaults = array(
    238             'page'              => 1,
    239             'per_page'          => 20,
    240             'page_arg'          => 'grpage',
    241             'max'               => false,
    242             'type'              => 'active',
    243             'order'             => 'DESC',
    244             'orderby'           => 'date_created',
    245             'show_hidden'       => false,
    246             'user_id'           => 0,
    247             'slug'              => false,
    248             'include'           => false,
    249             'exclude'           => false,
    250             'search_terms'      => '',
    251             'meta_query'        => false,
    252             'populate_extras'   => true,
    253             'update_meta_cache' => true,
    254         );
    255 
    256         $r = wp_parse_args( $args, $defaults );
    257         extract( $r );
    258 
    259         $this->pag_arg  = sanitize_key( $r['page_arg'] );
    260         $this->pag_page = bp_sanitize_pagination_arg( $this->pag_arg, $r['page']     );
    261         $this->pag_num  = bp_sanitize_pagination_arg( 'num',          $r['per_page'] );
    262 
    263         if ( bp_current_user_can( 'bp_moderate' ) || ( is_user_logged_in() && $user_id == bp_loggedin_user_id() ) ) {
    264             $show_hidden = true;
    265         }
    266 
    267         if ( 'invites' == $type ) {
    268             $this->groups = groups_get_invites_for_user( $user_id, $this->pag_num, $this->pag_page, $exclude );
    269         } elseif ( 'single-group' == $type ) {
    270             $this->single_group = true;
    271 
    272             if ( groups_get_current_group() ) {
    273                 $group = groups_get_current_group();
    274 
    275             } else {
    276                 $group = groups_get_group( array(
    277                     'group_id'        => BP_Groups_Group::get_id_from_slug( $r['slug'] ),
    278                     'populate_extras' => $r['populate_extras'],
    279                 ) );
    280             }
    281 
    282             // Backwards compatibility - the 'group_id' variable is not part of the
    283             // BP_Groups_Group object, but we add it here for devs doing checks against it
    284             //
    285             // @see https://buddypress.trac.wordpress.org/changeset/3540
    286             //
    287             // this is subject to removal in a future release; devs should check against
    288             // $group->id instead.
    289             $group->group_id = $group->id;
    290 
    291             $this->groups = array( $group );
    292 
    293         } else {
    294             $this->groups = groups_get_groups( array(
    295                 'type'              => $type,
    296                 'order'             => $order,
    297                 'orderby'           => $orderby,
    298                 'per_page'          => $this->pag_num,
    299                 'page'              => $this->pag_page,
    300                 'user_id'           => $user_id,
    301                 'search_terms'      => $search_terms,
    302                 'meta_query'        => $meta_query,
    303                 'include'           => $include,
    304                 'exclude'           => $exclude,
    305                 'populate_extras'   => $populate_extras,
    306                 'update_meta_cache' => $update_meta_cache,
    307                 'show_hidden'       => $show_hidden
    308             ) );
    309         }
    310 
    311         if ( 'invites' == $type ) {
    312             $this->total_group_count = (int) $this->groups['total'];
    313             $this->group_count       = (int) $this->groups['total'];
    314             $this->groups            = $this->groups['groups'];
    315         } elseif ( 'single-group' == $type ) {
    316             if ( empty( $group->id ) ) {
    317                 $this->total_group_count = 0;
    318                 $this->group_count       = 0;
    319             } else {
    320                 $this->total_group_count = 1;
    321                 $this->group_count       = 1;
    322             }
    323         } else {
    324             if ( empty( $max ) || $max >= (int) $this->groups['total'] ) {
    325                 $this->total_group_count = (int) $this->groups['total'];
    326             } else {
    327                 $this->total_group_count = (int) $max;
    328             }
    329 
    330             $this->groups = $this->groups['groups'];
    331 
    332             if ( !empty( $max ) ) {
    333                 if ( $max >= count( $this->groups ) ) {
    334                     $this->group_count = count( $this->groups );
    335                 } else {
    336                     $this->group_count = (int) $max;
    337                 }
    338             } else {
    339                 $this->group_count = count( $this->groups );
    340             }
    341         }
    342 
    343         // Build pagination links.
    344         if ( (int) $this->total_group_count && (int) $this->pag_num ) {
    345             $pag_args = array(
    346                 $this->pag_arg => '%#%'
    347             );
    348 
    349             if ( defined( 'DOING_AJAX' ) && true === (bool) DOING_AJAX ) {
    350                 $base = remove_query_arg( 's', wp_get_referer() );
    351             } else {
    352                 $base = '';
    353             }
    354 
    355             $add_args = array(
    356                 'num'     => $this->pag_num,
    357                 'sortby'  => $this->sort_by,
    358                 'order'   => $this->order,
    359             );
    360 
    361             if ( ! empty( $search_terms ) ) {
    362                 $query_arg = bp_core_get_component_search_query_arg( 'groups' );
    363                 $add_args[ $query_arg ] = urlencode( $search_terms );
    364             }
    365 
    366             $this->pag_links = paginate_links( array(
    367                 'base'      => add_query_arg( $pag_args, $base ),
    368                 'format'    => '',
    369                 'total'     => ceil( (int) $this->total_group_count / (int) $this->pag_num ),
    370                 'current'   => $this->pag_page,
    371                 'prev_text' => _x( '&larr;', 'Group pagination previous text', 'buddypress' ),
    372                 'next_text' => _x( '&rarr;', 'Group pagination next text', 'buddypress' ),
    373                 'mid_size'  => 1,
    374                 'add_args'  => $add_args,
    375             ) );
    376         }
    377     }
    378 
    379     /**
    380      * Whether there are groups available in the loop.
    381      *
    382      * @since 1.2.0
    383      *
    384      * @see bp_has_groups()
    385      *
    386      * @return bool True if there are items in the loop, otherwise false.
    387      */
    388     function has_groups() {
    389         if ( $this->group_count ) {
    390             return true;
    391         }
    392 
    393         return false;
    394     }
    395 
    396     /**
    397      * Set up the next group and iterate index.
    398      *
    399      * @since 1.2.0
    400      *
    401      * @return object The next group to iterate over.
    402      */
    403     function next_group() {
    404         $this->current_group++;
    405         $this->group = $this->groups[$this->current_group];
    406 
    407         return $this->group;
    408     }
    409 
    410     /**
    411      * Rewind the groups and reset member index.
    412      *
    413      * @since 1.2.0
    414      */
    415     function rewind_groups() {
    416         $this->current_group = -1;
    417         if ( $this->group_count > 0 ) {
    418             $this->group = $this->groups[0];
    419         }
    420     }
    421 
    422     /**
    423      * Whether there are groups left in the loop to iterate over.
    424      *
    425      * This method is used by {@link bp_groups()} as part of the while loop
    426      * that controls iteration inside the groups loop, eg:
    427      *     while ( bp_groups() ) { ...
    428      *
    429      * @since 1.2.0
    430      *
    431      * @see bp_groups()
    432      *
    433      * @return bool True if there are more groups to show, otherwise false.
    434      */
    435     function groups() {
    436         if ( $this->current_group + 1 < $this->group_count ) {
    437             return true;
    438         } elseif ( $this->current_group + 1 == $this->group_count ) {
    439 
    440             /**
    441              * Fires right before the rewinding of groups list.
    442              *
    443              * @since 1.5.0
    444              */
    445             do_action('group_loop_end');
    446             // Do some cleaning up after the loop.
    447             $this->rewind_groups();
    448         }
    449 
    450         $this->in_the_loop = false;
    451         return false;
    452     }
    453 
    454     /**
    455      * Set up the current group inside the loop.
    456      *
    457      * Used by {@link bp_the_group()} to set up the current group data
    458      * while looping, so that template tags used during that iteration make
    459      * reference to the current member.
    460      *
    461      * @since 1.2.0
    462      *
    463      * @see bp_the_group()
    464      */
    465     function the_group() {
    466         $this->in_the_loop = true;
    467         $this->group       = $this->next_group();
    468 
    469         if ( 0 == $this->current_group ) {
    470 
    471             /**
    472              * Fires if the current group item is the first in the loop.
    473              *
    474              * @since 1.1.0
    475              */
    476             do_action( 'group_loop_start' );
    477         }
    478     }
    479 }
    48098
    48199/**
     
    39743592
    39753593/**
    3976  * Class BP_Groups_Group_Members_Template
    3977  *
    3978  * @since 1.0.0
    3979  */
    3980 class BP_Groups_Group_Members_Template {
    3981 
    3982     /**
    3983      * @since 1.0.0
    3984      * @var int
    3985      */
    3986     public $current_member = -1;
    3987 
    3988     /**
    3989      * @since 1.0.0
    3990      * @var int
    3991      */
    3992     public $member_count;
    3993 
    3994     /**
    3995      * @since 1.0.0
    3996      * @var array
    3997      */
    3998     public $members;
    3999 
    4000     /**
    4001      * @since 1.0.0
    4002      * @var object
    4003      */
    4004     public $member;
    4005 
    4006     /**
    4007      * @since 1.0.0
    4008      * @var bool
    4009      */
    4010     public $in_the_loop;
    4011 
    4012     /**
    4013      * @since 1.0.0
    4014      * @var int
    4015      */
    4016     public $pag_page;
    4017 
    4018     /**
    4019      * @since 1.0.0
    4020      * @var int
    4021      */
    4022     public $pag_num;
    4023 
    4024     /**
    4025      * @since 1.0.0
    4026      * @var array|string|void
    4027      */
    4028     public $pag_links;
    4029 
    4030     /**
    4031      * @since 1.0.0
    4032      * @var int
    4033      */
    4034     public $total_group_count;
    4035 
    4036     /**
    4037      * Constructor.
    4038      *
    4039      * @since 1.5.0
    4040      *
    4041      * @param array $args {
    4042      *     An array of optional arguments.
    4043      *     @type int      $group_id           ID of the group whose members are being
    4044      *                                        queried. Default: current group ID.
    4045      *     @type int      $page               Page of results to be queried. Default: 1.
    4046      *     @type int      $per_page           Number of items to return per page of
    4047      *                                        results. Default: 20.
    4048      *     @type int      $max                Optional. Max number of items to return.
    4049      *     @type array    $exclude            Optional. Array of user IDs to exclude.
    4050      *     @type bool|int $exclude_admin_mods True (or 1) to exclude admins and mods from
    4051      *                                        results. Default: 1.
    4052      *     @type bool|int $exclude_banned     True (or 1) to exclude banned users from results.
    4053      *                                        Default: 1.
    4054      *     @type array    $group_role         Optional. Array of group roles to include.
    4055      *     @type string   $search_terms       Optional. Search terms to match.
    4056      * }
    4057      */
    4058     public function __construct( $args = array() ) {
    4059 
    4060         // Backward compatibility with old method of passing arguments.
    4061         if ( ! is_array( $args ) || func_num_args() > 1 ) {
    4062             _deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
    4063 
    4064             $old_args_keys = array(
    4065                 0 => 'group_id',
    4066                 1 => 'per_page',
    4067                 2 => 'max',
    4068                 3 => 'exclude_admins_mods',
    4069                 4 => 'exclude_banned',
    4070                 5 => 'exclude',
    4071                 6 => 'group_role',
    4072             );
    4073 
    4074             $func_args = func_get_args();
    4075             $args      = bp_core_parse_args_array( $old_args_keys, $func_args );
    4076         }
    4077 
    4078         $r = wp_parse_args( $args, array(
    4079             'group_id'            => bp_get_current_group_id(),
    4080             'page'                => 1,
    4081             'per_page'            => 20,
    4082             'page_arg'            => 'mlpage',
    4083             'max'                 => false,
    4084             'exclude'             => false,
    4085             'exclude_admins_mods' => 1,
    4086             'exclude_banned'      => 1,
    4087             'group_role'          => false,
    4088             'search_terms'        => false,
    4089             'type'                => 'last_joined',
    4090         ) );
    4091 
    4092         $this->pag_arg  = sanitize_key( $r['page_arg'] );
    4093         $this->pag_page = bp_sanitize_pagination_arg( $this->pag_arg, $r['page']     );
    4094         $this->pag_num  = bp_sanitize_pagination_arg( 'num',          $r['per_page'] );
    4095 
    4096         /**
    4097          * Check the current group is the same as the supplied group ID.
    4098          * It can differ when using {@link bp_group_has_members()} outside the Groups screens.
    4099          */
    4100         $current_group = groups_get_current_group();
    4101         if ( empty( $current_group ) || ( $current_group && $current_group->id !== bp_get_current_group_id() ) ) {
    4102             $current_group = groups_get_group( array( 'group_id' => $r['group_id'] ) );
    4103         }
    4104 
    4105         // Assemble the base URL for pagination.
    4106         $base_url = trailingslashit( bp_get_group_permalink( $current_group ) . bp_current_action() );
    4107         if ( bp_action_variable() ) {
    4108             $base_url = trailingslashit( $base_url . bp_action_variable() );
    4109         }
    4110 
    4111         $members_args = $r;
    4112 
    4113         $members_args['page']     = $this->pag_page;
    4114         $members_args['per_page'] = $this->pag_num;
    4115 
    4116         // Get group members for this loop.
    4117         $this->members = groups_get_group_members( $members_args );
    4118 
    4119         if ( empty( $r['max'] ) || ( $r['max'] >= (int) $this->members['count'] ) ) {
    4120             $this->total_member_count = (int) $this->members['count'];
    4121         } else {
    4122             $this->total_member_count = (int) $r['max'];
    4123         }
    4124 
    4125         // Reset members array for subsequent looping.
    4126         $this->members = $this->members['members'];
    4127 
    4128         if ( empty( $r['max'] ) || ( $r['max'] >= count( $this->members ) ) ) {
    4129             $this->member_count = (int) count( $this->members );
    4130         } else {
    4131             $this->member_count = (int) $r['max'];
    4132         }
    4133 
    4134         $this->pag_links = paginate_links( array(
    4135             'base'      => add_query_arg( array( $this->pag_arg => '%#%' ), $base_url ),
    4136             'format'    => '',
    4137             'total'     => ! empty( $this->pag_num ) ? ceil( $this->total_member_count / $this->pag_num ) : $this->total_member_count,
    4138             'current'   => $this->pag_page,
    4139             'prev_text' => '&larr;',
    4140             'next_text' => '&rarr;',
    4141             'mid_size'  => 1,
    4142             'add_args'  => array(),
    4143         ) );
    4144     }
    4145 
    4146     /**
    4147      * Whether or not there are members to display.
    4148      *
    4149      * @since 1.0.0
    4150      *
    4151      * @return bool
    4152      */
    4153     public function has_members() {
    4154         if ( ! empty( $this->member_count ) ) {
    4155             return true;
    4156         }
    4157 
    4158         return false;
    4159     }
    4160 
    4161     /**
    4162      * Increments to the next member to display.
    4163      *
    4164      * @since 1.0.0
    4165      *
    4166      * @return object
    4167      */
    4168     public function next_member() {
    4169         $this->current_member++;
    4170         $this->member = $this->members[ $this->current_member ];
    4171 
    4172         return $this->member;
    4173     }
    4174 
    4175     /**
    4176      * Rewinds to the first member to display.
    4177      *
    4178      * @since 1.0.0
    4179      */
    4180     public function rewind_members() {
    4181         $this->current_member = -1;
    4182         if ( $this->member_count > 0 ) {
    4183             $this->member = $this->members[0];
    4184         }
    4185     }
    4186 
    4187     /**
    4188      * Finishes up the members for display.
    4189      *
    4190      * @since 1.0.0
    4191      *
    4192      * @return bool
    4193      */
    4194     public function members() {
    4195         $tick = intval( $this->current_member + 1 );
    4196         if ( $tick < $this->member_count ) {
    4197             return true;
    4198         } elseif ( $tick == $this->member_count ) {
    4199 
    4200             /**
    4201              * Fires right before the rewinding of members list.
    4202              *
    4203              * @since 1.0.0
    4204              * @since 2.3.0 `$this` parameter added.
    4205              *
    4206              * @param BP_Groups_Group_Members_Template $this Instance of the current Members template.
    4207              */
    4208             do_action( 'loop_end', $this );
    4209 
    4210             // Do some cleaning up after the loop.
    4211             $this->rewind_members();
    4212         }
    4213 
    4214         $this->in_the_loop = false;
    4215         return false;
    4216     }
    4217 
    4218     /**
    4219      * Sets up the member to display.
    4220      *
    4221      * @since 1.0.0
    4222      */
    4223     public function the_member() {
    4224         $this->in_the_loop = true;
    4225         $this->member      = $this->next_member();
    4226 
    4227         // Loop has just started.
    4228         if ( 0 == $this->current_member ) {
    4229 
    4230             /**
    4231              * Fires if the current member item is the first in the members list.
    4232              *
    4233              * @since 1.0.0
    4234              * @since 2.3.0 `$this` parameter added.
    4235              *
    4236              * @param BP_Groups_Group_Members_Template $this Instance of the current Members template.
    4237              */
    4238             do_action( 'loop_start', $this );
    4239         }
    4240     }
    4241 }
    4242 
    4243 /**
    42443594 * Initialize a group member query loop.
    42453595 *
     
    58675217
    58685218/**
    5869  * Class BP_Groups_Membership_Requests_Template
    5870  *
    5871  * @since 1.0.0
    5872  */
    5873 class BP_Groups_Membership_Requests_Template {
    5874 
    5875     /**
    5876      * @since 1.0.0
    5877      * @var int
    5878      */
    5879     public $current_request = -1;
    5880 
    5881     /**
    5882      * @since 1.0.0
    5883      * @var int
    5884      */
    5885     public $request_count;
    5886 
    5887     /**
    5888      * @since 1.0.0
    5889      * @var array
    5890      */
    5891     public $requests;
    5892 
    5893     /**
    5894      * @since 1.0.0
    5895      * @var object
    5896      */
    5897     public $request;
    5898 
    5899     /**
    5900      * @sine 1.0.0
    5901      * @var bool
    5902      */
    5903     public $in_the_loop;
    5904 
    5905     /**
    5906      * @since 1.0.0
    5907      * @var int
    5908      */
    5909     public $pag_page;
    5910 
    5911     /**
    5912      * @since 1.0.0
    5913      * @var int
    5914      */
    5915     public $pag_num;
    5916 
    5917     /**
    5918      * @since 1.0.0
    5919      * @var array|string|void
    5920      */
    5921     public $pag_links;
    5922 
    5923     /**
    5924      * @since 1.0.0
    5925      * @var int
    5926      */
    5927     public $total_request_count;
    5928 
    5929     /**
    5930      * Constructor method.
    5931      *
    5932      * @since 1.5.0
    5933      *
    5934      * @param array $args {
    5935      *     @type int $group_id ID of the group whose membership requests
    5936      *                         are being queried. Default: current group id.
    5937      *     @type int $per_page Number of records to return per page of
    5938      *                         results. Default: 10.
    5939      *     @type int $page     Page of results to show. Default: 1.
    5940      *     @type int $max      Max items to return. Default: false (show all)
    5941      * }
    5942      */
    5943     public function __construct( $args = array() ) {
    5944 
    5945         // Backward compatibility with old method of passing arguments.
    5946         if ( ! is_array( $args ) || func_num_args() > 1 ) {
    5947             _deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
    5948 
    5949             $old_args_keys = array(
    5950                 0 => 'group_id',
    5951                 1 => 'per_page',
    5952                 2 => 'max',
    5953             );
    5954 
    5955             $func_args = func_get_args();
    5956             $args      = bp_core_parse_args_array( $old_args_keys, $func_args );
    5957         }
    5958 
    5959         $r = wp_parse_args( $args, array(
    5960             'page'     => 1,
    5961             'per_page' => 10,
    5962             'page_arg' => 'mrpage',
    5963             'max'      => false,
    5964             'type'     => 'first_joined',
    5965             'group_id' => bp_get_current_group_id(),
    5966         ) );
    5967 
    5968         $this->pag_arg  = sanitize_key( $r['page_arg'] );
    5969         $this->pag_page = bp_sanitize_pagination_arg( $this->pag_arg, $r['page']     );
    5970         $this->pag_num  = bp_sanitize_pagination_arg( 'num',          $r['per_page'] );
    5971 
    5972         $mquery = new BP_Group_Member_Query( array(
    5973             'group_id' => $r['group_id'],
    5974             'type'     => $r['type'],
    5975             'per_page' => $this->pag_num,
    5976             'page'     => $this->pag_page,
    5977 
    5978             // These filters ensure we only get pending requests.
    5979             'is_confirmed' => false,
    5980             'inviter_id'   => 0,
    5981         ) );
    5982 
    5983         $this->requests      = array_values( $mquery->results );
    5984         $this->request_count = count( $this->requests );
    5985 
    5986         // Compatibility with legacy format of request data objects.
    5987         foreach ( $this->requests as $rk => $rv ) {
    5988             // For legacy reasons, the 'id' property of each
    5989             // request must match the membership id, not the ID of
    5990             // the user (as it's returned by BP_Group_Member_Query).
    5991             $this->requests[ $rk ]->user_id = $rv->ID;
    5992             $this->requests[ $rk ]->id      = $rv->membership_id;
    5993 
    5994             // Miscellaneous values.
    5995             $this->requests[ $rk ]->group_id   = $r['group_id'];
    5996         }
    5997 
    5998         if ( empty( $r['max'] ) || ( $r['max'] >= (int) $mquery->total_users ) ) {
    5999             $this->total_request_count = (int) $mquery->total_users;
    6000         } else {
    6001             $this->total_request_count = (int) $r['max'];
    6002         }
    6003 
    6004         if ( empty( $r['max'] ) || ( $r['max'] >= count( $this->requests ) ) ) {
    6005             $this->request_count = count( $this->requests );
    6006         } else {
    6007             $this->request_count = (int) $r['max'];
    6008         }
    6009 
    6010         $this->pag_links = paginate_links( array(
    6011             'base'      => add_query_arg( $this->pag_arg, '%#%' ),
    6012             'format'    => '',
    6013             'total'     => ceil( $this->total_request_count / $this->pag_num ),
    6014             'current'   => $this->pag_page,
    6015             'prev_text' => '&larr;',
    6016             'next_text' => '&rarr;',
    6017             'mid_size'  => 1,
    6018             'add_args'  => array(),
    6019         ) );
    6020     }
    6021 
    6022     /**
    6023      * Whether or not there are requests to show.
    6024      *
    6025      * @since 1.0.0
    6026      *
    6027      * @return bool
    6028      */
    6029     public function has_requests() {
    6030         if ( ! empty( $this->request_count ) ) {
    6031             return true;
    6032         }
    6033 
    6034         return false;
    6035     }
    6036 
    6037     /**
    6038      * Moves up to the next request.
    6039      *
    6040      * @since 1.0.0
    6041      *
    6042      * @return object
    6043      */
    6044     public function next_request() {
    6045         $this->current_request++;
    6046         $this->request = $this->requests[ $this->current_request ];
    6047 
    6048         return $this->request;
    6049     }
    6050 
    6051     /**
    6052      * Rewinds the requests to the first in the list.
    6053      *
    6054      * @since 1.0.0
    6055      */
    6056     public function rewind_requests() {
    6057         $this->current_request = -1;
    6058 
    6059         if ( $this->request_count > 0 ) {
    6060             $this->request = $this->requests[0];
    6061         }
    6062     }
    6063 
    6064     /**
    6065      * Finishes up the requests to display.
    6066      *
    6067      * @since 1.0.0
    6068      *
    6069      * @return bool
    6070      */
    6071     public function requests() {
    6072         $tick = intval( $this->current_request + 1 );
    6073         if ( $tick < $this->request_count ) {
    6074             return true;
    6075         } elseif ( $tick == $this->request_count ) {
    6076 
    6077             /**
    6078              * Fires right before the rewinding of group membership requests list.
    6079              *
    6080              * @since 1.5.0
    6081              */
    6082             do_action( 'group_request_loop_end' );
    6083             // Do some cleaning up after the loop.
    6084             $this->rewind_requests();
    6085         }
    6086 
    6087         $this->in_the_loop = false;
    6088         return false;
    6089     }
    6090 
    6091     /**
    6092      * Sets up the request to display.
    6093      *
    6094      * @since 1.0.0
    6095      */
    6096     public function the_request() {
    6097         $this->in_the_loop = true;
    6098         $this->request     = $this->next_request();
    6099 
    6100         // Loop has just started.
    6101         if ( 0 == $this->current_request ) {
    6102 
    6103             /**
    6104              * Fires if the current group membership request item is the first in the loop.
    6105              *
    6106              * @since 1.1.0
    6107              */
    6108             do_action( 'group_request_loop_start' );
    6109         }
    6110     }
    6111 }
    6112 
    6113 /**
    61145219 * Initialize a group membership request template loop.
    61155220 *
     
    63645469
    63655470/** Group Invitations *********************************************************/
    6366 
    6367 /**
    6368  * Class BP_Groups_Invite_Template
    6369  *
    6370  * @since 1.1.0
    6371  */
    6372 class BP_Groups_Invite_Template {
    6373 
    6374     /**
    6375      * @since 1.1.0
    6376      * @var int
    6377      */
    6378     public $current_invite = -1;
    6379 
    6380     /**
    6381      * @since 1.1.0
    6382      * @var int
    6383      */
    6384     public $invite_count;
    6385 
    6386     /**
    6387      * @since 1.1.0
    6388      * @var array
    6389      */
    6390     public $invites;
    6391 
    6392     /**
    6393      * @since 1.1.0
    6394      * @var object
    6395      */
    6396     public $invite;
    6397 
    6398     /**
    6399      * @since 1.1.0
    6400      * @var bool
    6401      */
    6402     public $in_the_loop;
    6403 
    6404     /**
    6405      * @since 1.1.0
    6406      * @var int
    6407      */
    6408     public $pag_page;
    6409 
    6410     /**
    6411      * @since 1.1.0
    6412      * @var int
    6413      */
    6414     public $pag_num;
    6415 
    6416     /**
    6417      * @since 1.1.0
    6418      * @var string
    6419      */
    6420     public $pag_links;
    6421 
    6422     /**
    6423      * @since 1.1.0
    6424      * @var int
    6425      */
    6426     public $total_invite_count;
    6427 
    6428     /**
    6429      * BP_Groups_Invite_Template constructor.
    6430      *
    6431      * @since 1.5.0
    6432      *
    6433      * @param array $args
    6434      */
    6435     public function __construct( $args = array() ) {
    6436 
    6437         // Backward compatibility with old method of passing arguments.
    6438         if ( ! is_array( $args ) || func_num_args() > 1 ) {
    6439             _deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
    6440 
    6441             $old_args_keys = array(
    6442                 0  => 'user_id',
    6443                 1  => 'group_id',
    6444             );
    6445 
    6446             $func_args = func_get_args();
    6447             $args      = bp_core_parse_args_array( $old_args_keys, $func_args );
    6448         }
    6449 
    6450         $r = wp_parse_args( $args, array(
    6451             'page'     => 1,
    6452             'per_page' => 10,
    6453             'page_arg' => 'invitepage',
    6454             'user_id'  => bp_loggedin_user_id(),
    6455             'group_id' => bp_get_current_group_id(),
    6456         ) );
    6457 
    6458         $this->pag_arg  = sanitize_key( $r['page_arg'] );
    6459         $this->pag_page = bp_sanitize_pagination_arg( $this->pag_arg, $r['page']     );
    6460         $this->pag_num  = bp_sanitize_pagination_arg( 'num',          $r['per_page'] );
    6461 
    6462         $iquery = new BP_Group_Member_Query( array(
    6463             'group_id' => $r['group_id'],
    6464             'type'     => 'first_joined',
    6465             'per_page' => $this->pag_num,
    6466             'page'     => $this->pag_page,
    6467 
    6468             // These filters ensure we get only pending invites.
    6469             'is_confirmed' => false,
    6470             'inviter_id'   => $r['user_id'],
    6471         ) );
    6472 
    6473         $this->invite_data        = $iquery->results;
    6474         $this->total_invite_count = $iquery->total_users;
    6475         $this->invites            = array_values( wp_list_pluck( $this->invite_data, 'ID' ) );
    6476         $this->invite_count       = count( $this->invites );
    6477 
    6478         // If per_page is set to 0 (show all results), don't generate
    6479         // pag_links.
    6480         if ( ! empty( $this->pag_num ) ) {
    6481             $this->pag_links = paginate_links( array(
    6482                 'base'      => add_query_arg( $this->pag_arg, '%#%' ),
    6483                 'format'    => '',
    6484                 'total'     => ceil( $this->total_invite_count / $this->pag_num ),
    6485                 'current'   => $this->pag_page,
    6486                 'prev_text' => '&larr;',
    6487                 'next_text' => '&rarr;',
    6488                 'mid_size'  => 1,
    6489                 'add_args'  => array(),
    6490             ) );
    6491         } else {
    6492             $this->pag_links = '';
    6493         }
    6494     }
    6495 
    6496     /**
    6497      * Whether or not there are invites to show.
    6498      *
    6499      * @since 1.1.0
    6500      *
    6501      * @return bool
    6502      */
    6503     public function has_invites() {
    6504         if ( ! empty( $this->invite_count ) ) {
    6505             return true;
    6506         }
    6507 
    6508         return false;
    6509     }
    6510 
    6511     /**
    6512      * Increments up to the next invite to show.
    6513      *
    6514      * @since 1.1.0
    6515      *
    6516      * @return object
    6517      */
    6518     public function next_invite() {
    6519         $this->current_invite++;
    6520         $this->invite = $this->invites[ $this->current_invite ];
    6521 
    6522         return $this->invite;
    6523     }
    6524 
    6525     /**
    6526      * Rewinds to the first invite to show.
    6527      *
    6528      * @since 1.1.0
    6529      */
    6530     public function rewind_invites() {
    6531         $this->current_invite = -1;
    6532         if ( $this->invite_count > 0 ) {
    6533             $this->invite = $this->invites[0];
    6534         }
    6535     }
    6536 
    6537     /**
    6538      * Finishes up the invites to show.
    6539      *
    6540      * @since 1.1.0
    6541      *
    6542      * @return bool
    6543      */
    6544     public function invites() {
    6545         $tick = intval( $this->current_invite + 1 );
    6546         if ( $tick < $this->invite_count ) {
    6547             return true;
    6548         } elseif ( $tick == $this->invite_count ) {
    6549 
    6550             /**
    6551              * Fires right before the rewinding of invites list.
    6552              *
    6553              * @since 1.1.0
    6554              * @since 2.3.0 `$this` parameter added.
    6555              *
    6556              * @param BP_Groups_Invite_Template $this Instance of the current Invites template.
    6557              */
    6558             do_action( 'loop_end', $this );
    6559 
    6560             // Do some cleaning up after the loop
    6561             $this->rewind_invites();
    6562         }
    6563 
    6564         $this->in_the_loop = false;
    6565         return false;
    6566     }
    6567 
    6568     /**
    6569      * Sets up the invite to show.
    6570      *
    6571      * @since 1.1.0
    6572      */
    6573     public function the_invite() {
    6574         global $group_id;
    6575 
    6576         $this->in_the_loop  = true;
    6577         $user_id            = $this->next_invite();
    6578 
    6579         $this->invite       = new stdClass;
    6580         $this->invite->user = $this->invite_data[ $user_id ];
    6581 
    6582         // This method previously populated the user object with
    6583         // BP_Core_User. We manually configure BP_Core_User data for
    6584         // backward compatibility.
    6585         if ( bp_is_active( 'xprofile' ) ) {
    6586             $this->invite->user->profile_data = BP_XProfile_ProfileData::get_all_for_user( $user_id );
    6587         }
    6588 
    6589         $this->invite->user->avatar       = bp_core_fetch_avatar( array( 'item_id' => $user_id, 'type' => 'full',  'alt' => sprintf( __( 'Profile photo of %s', 'buddypress' ), $this->invite->user->fullname ) ) );
    6590         $this->invite->user->avatar_thumb = bp_core_fetch_avatar( array( 'item_id' => $user_id, 'type' => 'thumb', 'alt' => sprintf( __( 'Profile photo of %s', 'buddypress' ), $this->invite->user->fullname ) ) );
    6591         $this->invite->user->avatar_mini  = bp_core_fetch_avatar( array( 'item_id' => $user_id, 'type' => 'thumb', 'alt' => sprintf( __( 'Profile photo of %s', 'buddypress' ), $this->invite->user->fullname ), 'width' => 30, 'height' => 30 ) );
    6592         $this->invite->user->email        = $this->invite->user->user_email;
    6593         $this->invite->user->user_url     = bp_core_get_user_domain( $user_id, $this->invite->user->user_nicename, $this->invite->user->user_login );
    6594         $this->invite->user->user_link    = "<a href='{$this->invite->user->user_url}' title='{$this->invite->user->fullname}'>{$this->invite->user->fullname}</a>";
    6595         $this->invite->user->last_active  = bp_core_get_last_activity( $this->invite->user->last_activity, __( 'active %s', 'buddypress' ) );
    6596 
    6597         if ( bp_is_active( 'groups' ) ) {
    6598             $total_groups = BP_Groups_Member::total_group_count( $user_id );
    6599             $this->invite->user->total_groups = sprintf( _n( '%d group', '%d groups', $total_groups, 'buddypress' ), $total_groups );
    6600         }
    6601 
    6602         if ( bp_is_active( 'friends' ) ) {
    6603             $this->invite->user->total_friends = BP_Friends_Friendship::total_friend_count( $user_id );
    6604         }
    6605 
    6606         $this->invite->user->total_blogs = null;
    6607 
    6608         // Global'ed in bp_group_has_invites()
    6609         $this->invite->group_id = $group_id;
    6610 
    6611         // loop has just started
    6612         if ( 0 == $this->current_invite ) {
    6613 
    6614             /**
    6615              * Fires if the current invite item is the first in the loop.
    6616              *
    6617              * @since 1.1.0
    6618              * @since 2.3.0 `$this` parameter added.
    6619              *
    6620              * @param BP_Groups_Invite_Template $this Instance of the current Invites template.
    6621              */
    6622             do_action( 'loop_start', $this );
    6623         }
    6624     }
    6625 }
    66265471
    66275472/**
  • trunk/src/bp-groups/bp-groups-widgets.php

    r10454 r10520  
    1111defined( 'ABSPATH' ) || exit;
    1212
     13require dirname( __FILE__ ) . '/classes/class-bp-groups-widget.php';
     14
    1315/**
    1416 * Register widgets for groups component.
     
    2022}
    2123add_action( 'bp_register_widgets', 'groups_register_widgets' );
    22 
    23 /**
    24  * Groups widget.
    25  *
    26  * @since 1.0.3
    27  */
    28 class BP_Groups_Widget extends WP_Widget {
    29 
    30     /**
    31      * Working as a group, we get things done better.
    32      *
    33      * @since 1.0.3
    34      */
    35     public function __construct() {
    36         $widget_ops = array(
    37             'description' => __( 'A dynamic list of recently active, popular, and newest groups', 'buddypress' ),
    38             'classname' => 'widget_bp_groups_widget buddypress widget',
    39         );
    40         parent::__construct( false, _x( '(BuddyPress) Groups', 'widget name', 'buddypress' ), $widget_ops );
    41 
    42         if ( is_active_widget( false, false, $this->id_base ) && ! is_admin() && ! is_network_admin() ) {
    43             $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
    44             wp_enqueue_script( 'groups_widget_groups_list-js', buddypress()->plugin_url . "bp-groups/js/widget-groups{$min}.js", array( 'jquery' ), bp_get_version() );
    45         }
    46     }
    47 
    48     /**
    49      * Extends our frontend output method.
    50      *
    51      * @since 1.0.3
    52      *
    53      * @param array $args     Array of arguments for the widget.
    54      * @param array $instance Widget instance data.
    55      */
    56     public function widget( $args, $instance ) {
    57 
    58         /**
    59          * Filters the user ID to use with the widget instance.
    60          *
    61          * @since 1.5.0
    62          *
    63          * @param string $value Empty user ID.
    64          */
    65         $user_id = apply_filters( 'bp_group_widget_user_id', '0' );
    66 
    67         extract( $args );
    68 
    69         if ( empty( $instance['group_default'] ) ) {
    70             $instance['group_default'] = 'popular';
    71         }
    72 
    73         if ( empty( $instance['title'] ) ) {
    74             $instance['title'] = __( 'Groups', 'buddypress' );
    75         }
    76 
    77         /**
    78          * Filters the title of the Groups widget.
    79          *
    80          * @since 1.8.0
    81          * @since 2.3.0 Added 'instance' and 'id_base' to arguments passed to filter.
    82          *
    83          * @param string $title    The widget title.
    84          * @param array  $instance The settings for the particular instance of the widget.
    85          * @param string $id_base  Root ID for all widgets of this type.
    86          */
    87         $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
    88 
    89         /**
    90          * Filters the separator of the group widget links.
    91          *
    92          * @since 2.4.0
    93          *
    94          * @param string $separator Separator string. Default '|'.
    95          */
    96         $separator = apply_filters( 'bp_groups_widget_separator', '|' );
    97 
    98         echo $before_widget;
    99 
    100         $title = ! empty( $instance['link_title'] ) ? '<a href="' . bp_get_groups_directory_permalink() . '">' . $title . '</a>' : $title;
    101 
    102         echo $before_title . $title . $after_title;
    103 
    104         $max_groups = ! empty( $instance['max_groups'] ) ? (int) $instance['max_groups'] : 5;
    105 
    106         $group_args = array(
    107             'user_id'         => $user_id,
    108             'type'            => $instance['group_default'],
    109             'per_page'        => $max_groups,
    110             'max'             => $max_groups,
    111         );
    112 
    113         ?>
    114 
    115         <?php if ( bp_has_groups( $group_args ) ) : ?>
    116             <div class="item-options" id="groups-list-options">
    117                 <a href="<?php bp_groups_directory_permalink(); ?>" id="newest-groups"<?php if ( $instance['group_default'] == 'newest' ) : ?> class="selected"<?php endif; ?>><?php _e("Newest", 'buddypress') ?></a>
    118                 <span class="bp-separator" role="separator"><?php echo esc_html( $separator ); ?></span>
    119                 <a href="<?php bp_groups_directory_permalink(); ?>" id="recently-active-groups"<?php if ( $instance['group_default'] == 'active' ) : ?> class="selected"<?php endif; ?>><?php _e("Active", 'buddypress') ?></a>
    120                 <span class="bp-separator" role="separator"><?php echo esc_html( $separator ); ?></span>
    121                 <a href="<?php bp_groups_directory_permalink(); ?>" id="popular-groups" <?php if ( $instance['group_default'] == 'popular' ) : ?> class="selected"<?php endif; ?>><?php _e("Popular", 'buddypress') ?></a>
    122             </div>
    123 
    124             <ul id="groups-list" class="item-list">
    125                 <?php while ( bp_groups() ) : bp_the_group(); ?>
    126                     <li <?php bp_group_class(); ?>>
    127                         <div class="item-avatar">
    128                             <a href="<?php bp_group_permalink() ?>" title="<?php bp_group_name() ?>"><?php bp_group_avatar_thumb() ?></a>
    129                         </div>
    130 
    131                         <div class="item">
    132                             <div class="item-title"><a href="<?php bp_group_permalink() ?>" title="<?php bp_group_name() ?>"><?php bp_group_name() ?></a></div>
    133                             <div class="item-meta">
    134                                 <span class="activity">
    135                                 <?php
    136                                     if ( 'newest' == $instance['group_default'] ) {
    137                                         printf( __( 'created %s', 'buddypress' ), bp_get_group_date_created() );
    138                                     } elseif ( 'active' == $instance['group_default'] ) {
    139                                         printf( __( 'active %s', 'buddypress' ), bp_get_group_last_active() );
    140                                     } elseif ( 'popular' == $instance['group_default'] ) {
    141                                         bp_group_member_count();
    142                                     }
    143                                 ?>
    144                                 </span>
    145                             </div>
    146                         </div>
    147                     </li>
    148 
    149                 <?php endwhile; ?>
    150             </ul>
    151             <?php wp_nonce_field( 'groups_widget_groups_list', '_wpnonce-groups' ); ?>
    152             <input type="hidden" name="groups_widget_max" id="groups_widget_max" value="<?php echo esc_attr( $max_groups ); ?>" />
    153 
    154         <?php else: ?>
    155 
    156             <div class="widget-error">
    157                 <?php _e('There are no groups to display.', 'buddypress') ?>
    158             </div>
    159 
    160         <?php endif; ?>
    161 
    162         <?php echo $after_widget; ?>
    163     <?php
    164     }
    165 
    166     /**
    167      * Extends our update method.
    168      *
    169      * @since 1.0.3
    170      *
    171      * @param array $new_instance New instance data.
    172      * @param array $old_instance Original instance data.
    173      * @return array
    174      */
    175     public function update( $new_instance, $old_instance ) {
    176         $instance = $old_instance;
    177 
    178         $instance['title']         = strip_tags( $new_instance['title'] );
    179         $instance['max_groups']    = strip_tags( $new_instance['max_groups'] );
    180         $instance['group_default'] = strip_tags( $new_instance['group_default'] );
    181         $instance['link_title']    = (bool) $new_instance['link_title'];
    182 
    183         return $instance;
    184     }
    185 
    186     /**
    187      * Extends our form method.
    188      *
    189      * @since 1.0.3
    190      *
    191      * @param array $instance Current instance.
    192      * @return mixed
    193      */
    194     public function form( $instance ) {
    195         $defaults = array(
    196             'title'         => __( 'Groups', 'buddypress' ),
    197             'max_groups'    => 5,
    198             'group_default' => 'active',
    199             'link_title'    => false
    200         );
    201         $instance = wp_parse_args( (array) $instance, $defaults );
    202 
    203         $title         = strip_tags( $instance['title'] );
    204         $max_groups    = strip_tags( $instance['max_groups'] );
    205         $group_default = strip_tags( $instance['group_default'] );
    206         $link_title    = (bool) $instance['link_title'];
    207         ?>
    208 
    209         <p><label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e('Title:', 'buddypress'); ?> <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" style="width: 100%" /></label></p>
    210 
    211         <p><label for="<?php echo $this->get_field_id('link_title') ?>"><input type="checkbox" name="<?php echo $this->get_field_name('link_title') ?>" id="<?php echo $this->get_field_id('link_title') ?>" value="1" <?php checked( $link_title ) ?> /> <?php _e( 'Link widget title to Groups directory', 'buddypress' ) ?></label></p>
    212 
    213         <p><label for="<?php echo $this->get_field_id( 'max_groups' ); ?>"><?php _e('Max groups to show:', 'buddypress'); ?> <input class="widefat" id="<?php echo $this->get_field_id( 'max_groups' ); ?>" name="<?php echo $this->get_field_name( 'max_groups' ); ?>" type="text" value="<?php echo esc_attr( $max_groups ); ?>" style="width: 30%" /></label></p>
    214 
    215         <p>
    216             <label for="<?php echo $this->get_field_id( 'group_default' ); ?>"><?php _e('Default groups to show:', 'buddypress'); ?></label>
    217             <select name="<?php echo $this->get_field_name( 'group_default' ); ?>" id="<?php echo $this->get_field_id( 'group_default' ); ?>">
    218                 <option value="newest" <?php selected( $group_default, 'newest' ); ?>><?php _e( 'Newest', 'buddypress' ) ?></option>
    219                 <option value="active" <?php selected( $group_default, 'active' ); ?>><?php _e( 'Active', 'buddypress' ) ?></option>
    220                 <option value="popular"  <?php selected( $group_default, 'popular' ); ?>><?php _e( 'Popular', 'buddypress' ) ?></option>
    221             </select>
    222         </p>
    223     <?php
    224     }
    225 }
    22624
    22725/**
  • trunk/src/bp-groups/classes/class-bp-groups-component.php

    r10515 r10520  
    11<?php
    22/**
    3  * BuddyPress Groups Loader.
    4  *
    5  * A groups component, for users to group themselves together. Includes a
    6  * robust sub-component API that allows Groups to be extended.
    7  * Comes preconfigured with an activity stream, discussion forums, and settings.
     3 * BuddyPress Groups Component Class.
    84 *
    95 * @package BuddyPress
     
    814810    }
    815811}
    816 
    817 /**
    818  * Bootstrap the Notifications component.
    819  *
    820  * @since 1.5.0
    821  */
    822 function bp_setup_groups() {
    823     buddypress()->groups = new BP_Groups_Component();
    824 }
    825 add_action( 'bp_setup_components', 'bp_setup_groups', 6 );
  • trunk/src/bp-groups/classes/class-bp-groups-group-members-template.php

    r10515 r10520  
    11<?php
    22/**
    3  * BuddyPress Groups Template Functions.
     3 * BuddyPress Groups group members loop template class.
    44 *
    55 * @package BuddyPress
    6  * @subpackage GroupsTemplates
    7  * @since 1.5.0
     6 * @since 1.1.0
    87 */
    98
     
    1211
    1312/**
    14  * Output the groups component slug.
    15  *
    16  * @since 1.5.0
    17  */
    18 function bp_groups_slug() {
    19     echo bp_get_groups_slug();
    20 }
    21     /**
    22      * Return the groups component slug.
    23      *
    24      * @since 1.5.0
    25      *
    26      * @return string
    27      */
    28     function bp_get_groups_slug() {
    29 
    30         /**
    31          * Filters the groups component slug.
    32          *
    33          * @since 1.5.0
    34          *
    35          * @param string $slug Groups component slug.
    36          */
    37         return apply_filters( 'bp_get_groups_slug', buddypress()->groups->slug );
    38     }
    39 
    40 /**
    41  * Output the groups component root slug.
    42  *
    43  * @since 1.5.0
    44  */
    45 function bp_groups_root_slug() {
    46     echo bp_get_groups_root_slug();
    47 }
    48     /**
    49      * Return the groups component root slug.
    50      *
    51      * @since 1.5.0
    52      *
    53      * @return string
    54      */
    55     function bp_get_groups_root_slug() {
    56 
    57         /**
    58          * Filters the groups component root slug.
    59          *
    60          * @since 1.5.0
    61          *
    62          * @param string $root_slug Groups component root slug.
    63          */
    64         return apply_filters( 'bp_get_groups_root_slug', buddypress()->groups->root_slug );
    65     }
    66 
    67 /**
    68  * Output group directory permalink.
    69  *
    70  * @since 1.5.0
    71  */
    72 function bp_groups_directory_permalink() {
    73     echo esc_url( bp_get_groups_directory_permalink() );
    74 }
    75     /**
    76      * Return group directory permalink.
    77      *
    78      * @since 1.5.0
    79      *
    80      * @return string
    81      */
    82     function bp_get_groups_directory_permalink() {
    83 
    84         /**
    85          * Filters the group directory permalink.
    86          *
    87          * @since 1.5.0
    88          *
    89          * @param string $value Permalink for the group directory.
    90          */
    91         return apply_filters( 'bp_get_groups_directory_permalink', trailingslashit( bp_get_root_domain() . '/' . bp_get_groups_root_slug() ) );
    92     }
    93 
    94 /**
    95  * The main Groups template loop class.
    96  *
    97  * Responsible for loading a group of groups into a loop for display.
    98  *
    99  * @since 1.2.0
    100  */
    101 class BP_Groups_Template {
    102 
    103     /**
    104      * The loop iterator.
    105      *
    106      * @var int
    107      * @since 1.2.0
    108      */
    109     public $current_group = -1;
    110 
    111     /**
    112      * The number of groups returned by the paged query.
    113      *
    114      * @var int
    115      * @since 1.2.0
    116      */
    117     public $group_count;
    118 
    119     /**
    120      * Array of groups located by the query.
    121      *
    122      * @var array
    123      * @since 1.2.0
    124      */
    125     public $groups;
    126 
    127     /**
    128      * The group object currently being iterated on.
    129      *
    130      * @var object
    131      * @since 1.2.0
    132      */
    133     public $group;
    134 
    135     /**
    136      * A flag for whether the loop is currently being iterated.
    137      *
    138      * @var bool
    139      * @since 1.2.0
    140      */
    141     public $in_the_loop;
    142 
    143     /**
    144      * The page number being requested.
    145      *
    146      * @var string
    147      * @since 1.2.0
    148      */
    149     public $pag_page;
    150 
    151     /**
    152      * The number of items being requested per page.
    153      *
    154      * @var string
    155      * @since 1.2.0
    156      */
    157     public $pag_num;
    158 
    159     /**
    160      * An HTML string containing pagination links.
    161      *
    162      * @var string
    163      * @since 1.2.0
    164      */
    165     public $pag_links;
    166 
    167     /**
    168      * The total number of groups matching the query parameters.
    169      *
    170      * @var int
    171      * @since 1.2.0
    172      */
    173     public $total_group_count;
    174 
    175     /**
    176      * Whether the template loop is for a single group page.
    177      *
    178      * @var bool
    179      * @since 1.2.0
    180      */
    181     public $single_group = false;
    182 
    183     /**
    184      * Field to sort by.
    185      *
    186      * @var string
    187      * @since 1.2.0
    188      */
    189     public $sort_by;
    190 
    191     /**
    192      * Sort order.
    193      *
    194      * @var string
    195      * @since 1.2.0
    196      */
    197     public $order;
    198 
    199     /**
    200      * Constructor method.
    201      *
    202      * @see BP_Groups_Group::get() for an in-depth description of arguments.
    203      *
    204      * @param array $args {
    205      *     Array of arguments. Accepts all arguments accepted by
    206      *     {@link BP_Groups_Group::get()}. In cases where the default
    207      *     values of the params differ, they have been discussed below.
    208      *     @type int $per_page Default: 20.
    209      *     @type int $page Default: 1.
    210      * }
    211      */
    212     function __construct( $args = array() ){
    213 
    214         // Backward compatibility with old method of passing arguments.
    215         if ( ! is_array( $args ) || func_num_args() > 1 ) {
    216             _deprecated_argument( __METHOD__, '1.7', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
    217 
    218             $old_args_keys = array(
    219                 0  => 'user_id',
    220                 1  => 'type',
    221                 2  => 'page',
    222                 3  => 'per_page',
    223                 4  => 'max',
    224                 5  => 'slug',
    225                 6  => 'search_terms',
    226                 7  => 'populate_extras',
    227                 8  => 'include',
    228                 9  => 'exclude',
    229                 10 => 'show_hidden',
    230                 11 => 'page_arg',
    231             );
    232 
    233             $func_args = func_get_args();
    234             $args      = bp_core_parse_args_array( $old_args_keys, $func_args );
    235         }
    236 
    237         $defaults = array(
    238             'page'              => 1,
    239             'per_page'          => 20,
    240             'page_arg'          => 'grpage',
    241             'max'               => false,
    242             'type'              => 'active',
    243             'order'             => 'DESC',
    244             'orderby'           => 'date_created',
    245             'show_hidden'       => false,
    246             'user_id'           => 0,
    247             'slug'              => false,
    248             'include'           => false,
    249             'exclude'           => false,
    250             'search_terms'      => '',
    251             'meta_query'        => false,
    252             'populate_extras'   => true,
    253             'update_meta_cache' => true,
    254         );
    255 
    256         $r = wp_parse_args( $args, $defaults );
    257         extract( $r );
    258 
    259         $this->pag_arg  = sanitize_key( $r['page_arg'] );
    260         $this->pag_page = bp_sanitize_pagination_arg( $this->pag_arg, $r['page']     );
    261         $this->pag_num  = bp_sanitize_pagination_arg( 'num',          $r['per_page'] );
    262 
    263         if ( bp_current_user_can( 'bp_moderate' ) || ( is_user_logged_in() && $user_id == bp_loggedin_user_id() ) ) {
    264             $show_hidden = true;
    265         }
    266 
    267         if ( 'invites' == $type ) {
    268             $this->groups = groups_get_invites_for_user( $user_id, $this->pag_num, $this->pag_page, $exclude );
    269         } elseif ( 'single-group' == $type ) {
    270             $this->single_group = true;
    271 
    272             if ( groups_get_current_group() ) {
    273                 $group = groups_get_current_group();
    274 
    275             } else {
    276                 $group = groups_get_group( array(
    277                     'group_id'        => BP_Groups_Group::get_id_from_slug( $r['slug'] ),
    278                     'populate_extras' => $r['populate_extras'],
    279                 ) );
    280             }
    281 
    282             // Backwards compatibility - the 'group_id' variable is not part of the
    283             // BP_Groups_Group object, but we add it here for devs doing checks against it
    284             //
    285             // @see https://buddypress.trac.wordpress.org/changeset/3540
    286             //
    287             // this is subject to removal in a future release; devs should check against
    288             // $group->id instead.
    289             $group->group_id = $group->id;
    290 
    291             $this->groups = array( $group );
    292 
    293         } else {
    294             $this->groups = groups_get_groups( array(
    295                 'type'              => $type,
    296                 'order'             => $order,
    297                 'orderby'           => $orderby,
    298                 'per_page'          => $this->pag_num,
    299                 'page'              => $this->pag_page,
    300                 'user_id'           => $user_id,
    301                 'search_terms'      => $search_terms,
    302                 'meta_query'        => $meta_query,
    303                 'include'           => $include,
    304                 'exclude'           => $exclude,
    305                 'populate_extras'   => $populate_extras,
    306                 'update_meta_cache' => $update_meta_cache,
    307                 'show_hidden'       => $show_hidden
    308             ) );
    309         }
    310 
    311         if ( 'invites' == $type ) {
    312             $this->total_group_count = (int) $this->groups['total'];
    313             $this->group_count       = (int) $this->groups['total'];
    314             $this->groups            = $this->groups['groups'];
    315         } elseif ( 'single-group' == $type ) {
    316             if ( empty( $group->id ) ) {
    317                 $this->total_group_count = 0;
    318                 $this->group_count       = 0;
    319             } else {
    320                 $this->total_group_count = 1;
    321                 $this->group_count       = 1;
    322             }
    323         } else {
    324             if ( empty( $max ) || $max >= (int) $this->groups['total'] ) {
    325                 $this->total_group_count = (int) $this->groups['total'];
    326             } else {
    327                 $this->total_group_count = (int) $max;
    328             }
    329 
    330             $this->groups = $this->groups['groups'];
    331 
    332             if ( !empty( $max ) ) {
    333                 if ( $max >= count( $this->groups ) ) {
    334                     $this->group_count = count( $this->groups );
    335                 } else {
    336                     $this->group_count = (int) $max;
    337                 }
    338             } else {
    339                 $this->group_count = count( $this->groups );
    340             }
    341         }
    342 
    343         // Build pagination links.
    344         if ( (int) $this->total_group_count && (int) $this->pag_num ) {
    345             $pag_args = array(
    346                 $this->pag_arg => '%#%'
    347             );
    348 
    349             if ( defined( 'DOING_AJAX' ) && true === (bool) DOING_AJAX ) {
    350                 $base = remove_query_arg( 's', wp_get_referer() );
    351             } else {
    352                 $base = '';
    353             }
    354 
    355             $add_args = array(
    356                 'num'     => $this->pag_num,
    357                 'sortby'  => $this->sort_by,
    358                 'order'   => $this->order,
    359             );
    360 
    361             if ( ! empty( $search_terms ) ) {
    362                 $query_arg = bp_core_get_component_search_query_arg( 'groups' );
    363                 $add_args[ $query_arg ] = urlencode( $search_terms );
    364             }
    365 
    366             $this->pag_links = paginate_links( array(
    367                 'base'      => add_query_arg( $pag_args, $base ),
    368                 'format'    => '',
    369                 'total'     => ceil( (int) $this->total_group_count / (int) $this->pag_num ),
    370                 'current'   => $this->pag_page,
    371                 'prev_text' => _x( '&larr;', 'Group pagination previous text', 'buddypress' ),
    372                 'next_text' => _x( '&rarr;', 'Group pagination next text', 'buddypress' ),
    373                 'mid_size'  => 1,
    374                 'add_args'  => $add_args,
    375             ) );
    376         }
    377     }
    378 
    379     /**
    380      * Whether there are groups available in the loop.
    381      *
    382      * @since 1.2.0
    383      *
    384      * @see bp_has_groups()
    385      *
    386      * @return bool True if there are items in the loop, otherwise false.
    387      */
    388     function has_groups() {
    389         if ( $this->group_count ) {
    390             return true;
    391         }
    392 
    393         return false;
    394     }
    395 
    396     /**
    397      * Set up the next group and iterate index.
    398      *
    399      * @since 1.2.0
    400      *
    401      * @return object The next group to iterate over.
    402      */
    403     function next_group() {
    404         $this->current_group++;
    405         $this->group = $this->groups[$this->current_group];
    406 
    407         return $this->group;
    408     }
    409 
    410     /**
    411      * Rewind the groups and reset member index.
    412      *
    413      * @since 1.2.0
    414      */
    415     function rewind_groups() {
    416         $this->current_group = -1;
    417         if ( $this->group_count > 0 ) {
    418             $this->group = $this->groups[0];
    419         }
    420     }
    421 
    422     /**
    423      * Whether there are groups left in the loop to iterate over.
    424      *
    425      * This method is used by {@link bp_groups()} as part of the while loop
    426      * that controls iteration inside the groups loop, eg:
    427      *     while ( bp_groups() ) { ...
    428      *
    429      * @since 1.2.0
    430      *
    431      * @see bp_groups()
    432      *
    433      * @return bool True if there are more groups to show, otherwise false.
    434      */
    435     function groups() {
    436         if ( $this->current_group + 1 < $this->group_count ) {
    437             return true;
    438         } elseif ( $this->current_group + 1 == $this->group_count ) {
    439 
    440             /**
    441              * Fires right before the rewinding of groups list.
    442              *
    443              * @since 1.5.0
    444              */
    445             do_action('group_loop_end');
    446             // Do some cleaning up after the loop.
    447             $this->rewind_groups();
    448         }
    449 
    450         $this->in_the_loop = false;
    451         return false;
    452     }
    453 
    454     /**
    455      * Set up the current group inside the loop.
    456      *
    457      * Used by {@link bp_the_group()} to set up the current group data
    458      * while looping, so that template tags used during that iteration make
    459      * reference to the current member.
    460      *
    461      * @since 1.2.0
    462      *
    463      * @see bp_the_group()
    464      */
    465     function the_group() {
    466         $this->in_the_loop = true;
    467         $this->group       = $this->next_group();
    468 
    469         if ( 0 == $this->current_group ) {
    470 
    471             /**
    472              * Fires if the current group item is the first in the loop.
    473              *
    474              * @since 1.1.0
    475              */
    476             do_action( 'group_loop_start' );
    477         }
    478     }
    479 }
    480 
    481 /**
    482  * Start the Groups Template Loop.
    483  *
    484  * @since 1.0.0
    485  *
    486  * @param array|string $args {
    487  *     Array of parameters. All items are optional.
    488  *     @type string       $type              Shorthand for certain orderby/
    489  *                                           order combinations. 'newest',
    490  *                                           'active', 'popular', 'alphabetical',
    491  *                                           'random'. When present, will override
    492  *                                           orderby and order params. Default: null.
    493  *     @type string       $order             Sort order. 'ASC' or 'DESC'.
    494  *                                           Default: 'DESC'.
    495  *     @type string       $orderby           Property to sort by.
    496  *                                           'date_created', 'last_activity', 'total_member_count',
    497  *                                           'name', 'random'. Default: 'last_activity'.
    498  *     @type int          $page              Page offset of results to return.
    499  *                                           Default: 1 (first page of results).
    500  *     @type int          $per_page          Number of items to return per page
    501  *                                           of results. Default: 20.
    502  *     @type int          $max               Does NOT affect query. May change the
    503  *                                           reported number of total groups found,
    504  *                                           but not the actual number of found
    505  *                                           groups. Default: false.
    506  *     @type bool         $show_hidden       Whether to include hidden groups in
    507  *                                           results. Default: false.
    508  *     @type string       $page_arg          Query argument used for pagination.
    509  *                                           Default: 'grpage'.
    510  *     @type int          $user_id           If provided, results will be limited
    511  *                                           to groups of which the specified user
    512  *                                           is a member.
    513  *                                           Default: value of bp_displayed_user_id().
    514  *     @type string       $slug              If provided, only the group with the
    515  *                                           matching slug will be returned.
    516  *                                           Default: false.
    517  *     @type string       $search_terms      If provided, only groups whose names or
    518  *                                           descriptions match the search terms will
    519  *                                           be returned. Default: value of
    520  *                                           `$_REQUEST['groups_search']` or
    521  *                                           `$_REQUEST['s']`, if present. Otherwise false.
    522  *     @type array        $meta_query        An array of meta_query conditions.
    523  *                                           See {@link WP_Meta_Query::queries} for description.
    524  *     @type array|string $include           Array or comma-separated list of
    525  *                                           group IDs. Results will be limited
    526  *                                           to groups within the list. Default: false.
    527  *     @type bool         $populate_extras   Whether to fetch additional information
    528  *                                           (such as member count) about groups.
    529  *                                           Default: true.
    530  *     @type array|string $exclude           Array or comma-separated list of group IDs.
    531  *                                           Results will exclude the listed groups.
    532  *                                           Default: false.
    533  *     @type bool         $update_meta_cache Whether to fetch groupmeta for queried groups.
    534  *                                           Default: true.
    535  * }
    536  * @return bool True if there are groups to display that match the params
    537  */
    538 function bp_has_groups( $args = '' ) {
    539     global $groups_template;
    540 
    541     /*
    542      * Defaults based on the current page & overridden by parsed $args
    543      */
    544     $slug         = false;
    545     $type         = '';
    546     $search_terms = false;
    547 
    548     // When looking your own groups, check for two action variables.
    549     if ( bp_is_current_action( 'my-groups' ) ) {
    550         if ( bp_is_action_variable( 'most-popular', 0 ) ) {
    551             $type = 'popular';
    552         } elseif ( bp_is_action_variable( 'alphabetically', 0 ) ) {
    553             $type = 'alphabetical';
    554         }
    555 
    556     // When looking at invites, set type to invites.
    557     } elseif ( bp_is_current_action( 'invites' ) ) {
    558         $type = 'invites';
    559 
    560     // When looking at a single group, set the type and slug.
    561     } elseif ( bp_get_current_group_slug() ) {
    562         $type = 'single-group';
    563         $slug = bp_get_current_group_slug();
    564     }
    565 
    566     // Default search string (too soon to escape here).
    567     $search_query_arg = bp_core_get_component_search_query_arg( 'groups' );
    568     if ( ! empty( $_REQUEST[ $search_query_arg ] ) ) {
    569         $search_terms = stripslashes( $_REQUEST[ $search_query_arg ] );
    570     } elseif ( ! empty( $_REQUEST['group-filter-box'] ) ) {
    571         $search_terms = $_REQUEST['group-filter-box'];
    572     } elseif ( !empty( $_REQUEST['s'] ) ) {
    573         $search_terms = $_REQUEST['s'];
    574     }
    575 
    576     // Parse defaults and requested arguments.
    577     $r = bp_parse_args( $args, array(
    578         'type'              => $type,
    579         'order'             => 'DESC',
    580         'orderby'           => 'last_activity',
    581         'page'              => 1,
    582         'per_page'          => 20,
    583         'max'               => false,
    584         'show_hidden'       => false,
    585         'page_arg'          => 'grpage',
    586         'user_id'           => bp_displayed_user_id(),
    587         'slug'              => $slug,
    588         'search_terms'      => $search_terms,
    589         'meta_query'        => false,
    590         'include'           => false,
    591         'exclude'           => false,
    592         'populate_extras'   => true,
    593         'update_meta_cache' => true,
    594     ), 'has_groups' );
    595 
    596     // Setup the Groups template global.
    597     $groups_template = new BP_Groups_Template( array(
    598         'type'              => $r['type'],
    599         'order'             => $r['order'],
    600         'orderby'           => $r['orderby'],
    601         'page'              => (int) $r['page'],
    602         'per_page'          => (int) $r['per_page'],
    603         'max'               => (int) $r['max'],
    604         'show_hidden'       => $r['show_hidden'],
    605         'page_arg'          => $r['page_arg'],
    606         'user_id'           => (int) $r['user_id'],
    607         'slug'              => $r['slug'],
    608         'search_terms'      => $r['search_terms'],
    609         'meta_query'        => $r['meta_query'],
    610         'include'           => $r['include'],
    611         'exclude'           => $r['exclude'],
    612         'populate_extras'   => (bool) $r['populate_extras'],
    613         'update_meta_cache' => (bool) $r['update_meta_cache'],
    614     ) );
    615 
    616     /**
    617      * Filters whether or not there are groups to iterate over for the groups loop.
    618      *
    619      * @since 1.1.0
    620      *
    621      * @param bool               $value           Whether or not there are groups to iterate over.
    622      * @param BP_Groups_Template $groups_template BP_Groups_Template object based on parsed arguments.
    623      * @param array              $r               Array of parsed arguments for the query.
    624      */
    625     return apply_filters( 'bp_has_groups', $groups_template->has_groups(), $groups_template, $r );
    626 }
    627 
    628 /**
    629  * Check whether there are more groups to iterate over.
    630  *
    631  * @since 1.0.0
    632  *
    633  * @return bool
    634  */
    635 function bp_groups() {
    636     global $groups_template;
    637     return $groups_template->groups();
    638 }
    639 
    640 /**
    641  * Set up the current group inside the loop.
    642  *
    643  * @since 1.0.0
    644  *
    645  * @return object
    646  */
    647 function bp_the_group() {
    648     global $groups_template;
    649     return $groups_template->the_group();
    650 }
    651 
    652 /**
    653  * Is the group visible to the currently logged-in user?
    654  *
    655  * @since 1.0.0
    656  *
    657  * @param object|bool $group Optional. Group object. Default: current group in loop.
    658  * @return bool
    659  */
    660 function bp_group_is_visible( $group = false ) {
    661     global $groups_template;
    662 
    663     if ( bp_current_user_can( 'bp_moderate' ) ) {
    664         return true;
    665     }
    666 
    667     if ( empty( $group ) ) {
    668         $group =& $groups_template->group;
    669     }
    670 
    671     if ( 'public' == $group->status ) {
    672         return true;
    673     } else {
    674         if ( groups_is_user_member( bp_loggedin_user_id(), $group->id ) ) {
    675             return true;
    676         }
    677     }
    678 
    679     return false;
    680 }
    681 
    682 /**
    683  * Output the ID of the current group in the loop.
    684  *
    685  * @since 1.0.0
    686  *
    687  * @param object|bool $group Optional. Group object. Default: current group in loop.
    688  */
    689 function bp_group_id( $group = false ) {
    690     echo bp_get_group_id( $group );
    691 }
    692     /**
    693      * Get the ID of the current group in the loop.
    694      *
    695      * @since 1.0.0
    696      *
    697      * @param object|bool $group Optional. Group object.
    698      *                           Default: current group in loop.
    699      * @return int
    700      */
    701     function bp_get_group_id( $group = false ) {
    702         global $groups_template;
    703 
    704         if ( empty( $group ) ) {
    705             $group =& $groups_template->group;
    706         }
    707 
    708         /**
    709          * Filters the ID of the current group in the loop.
    710          *
    711          * @since 1.0.0
    712          * @since 2.5.0 Added the `$group` parameter.
    713          *
    714          * @param int    $id    ID of the current group in the loop.
    715          * @param object $group Group object.
    716          */
    717         return apply_filters( 'bp_get_group_id', $group->id, $group );
    718     }
    719 
    720 /**
    721  * Output the row class of the current group in the loop.
    722  *
    723  * @since 1.7.0
    724  *
    725  * @param array $classes Array of custom classes.
    726  */
    727 function bp_group_class( $classes = array() ) {
    728     echo bp_get_group_class( $classes );
    729 }
    730     /**
    731      * Get the row class of the current group in the loop.
    732      *
    733      * @since 1.7.0
    734      *
    735      * @param array $classes Array of custom classes.
    736      * @return string Row class of the group.
    737      */
    738     function bp_get_group_class( $classes = array() ) {
    739         global $groups_template;
    740 
    741         // Add even/odd classes, but only if there's more than 1 group.
    742         if ( $groups_template->group_count > 1 ) {
    743             $pos_in_loop = (int) $groups_template->current_group;
    744             $classes[]   = ( $pos_in_loop % 2 ) ? 'even' : 'odd';
    745 
    746         // If we've only one group in the loop, don't bother with odd and even.
    747         } else {
    748             $classes[] = 'bp-single-group';
    749         }
    750 
    751         // Group type - public, private, hidden.
    752         $classes[] = sanitize_key( $groups_template->group->status );
    753 
    754         // User's group role.
    755         if ( bp_is_user_active() ) {
    756 
    757             // Admin.
    758             if ( bp_group_is_admin() ) {
    759                 $classes[] = 'is-admin';
    760             }
    761 
    762             // Moderator.
    763             if ( bp_group_is_mod() ) {
    764                 $classes[] = 'is-mod';
    765             }
    766 
    767             // Member.
    768             if ( bp_group_is_member() ) {
    769                 $classes[] = 'is-member';
    770             }
    771         }
    772 
    773         // Whether a group avatar will appear.
    774         if ( bp_disable_group_avatar_uploads() || ! buddypress()->avatar->show_avatars ) {
    775             $classes[] = 'group-no-avatar';
    776         } else {
    777             $classes[] = 'group-has-avatar';
    778         }
    779 
    780         /**
    781          * Filters classes that will be applied to row class of the current group in the loop.
    782          *
    783          * @since 1.7.0
    784          *
    785          * @param array $classes Array of determined classes for the row.
    786          */
    787         $classes = apply_filters( 'bp_get_group_class', $classes );
    788         $classes = array_merge( $classes, array() );
    789         $retval = 'class="' . join( ' ', $classes ) . '"';
    790 
    791         return $retval;
    792     }
    793 
    794 /**
    795  * Output the name of the current group in the loop.
    796  *
    797  * @since 1.0.0
    798  *
    799  * @param object|bool $group Optional. Group object.
    800  *                           Default: current group in loop.
    801  */
    802 function bp_group_name( $group = false ) {
    803     echo bp_get_group_name( $group );
    804 }
    805     /**
    806      * Get the name of the current group in the loop.
    807      *
    808      * @since 1.0.0
    809      *
    810      * @param object|bool $group Optional. Group object.
    811      *                           Default: current group in loop.
    812      * @return string
    813      */
    814     function bp_get_group_name( $group = false ) {
    815         global $groups_template;
    816 
    817         if ( empty( $group ) ) {
    818             $group =& $groups_template->group;
    819         }
    820 
    821         /**
    822          * Filters the name of the current group in the loop.
    823          *
    824          * @since 1.0.0
    825          * @since 2.5.0 Added the `$group` parameter.
    826          *
    827          * @param string $name  Name of the current group in the loop.
    828          * @param object $group Group object.
    829          */
    830         return apply_filters( 'bp_get_group_name', $group->name, $group );
    831     }
    832 
    833 /**
    834  * Output the type of the current group in the loop.
    835  *
    836  * @since 1.0.0
    837  *
    838  * @param object|bool $group Optional. Group object.
    839  *                           Default: current group in loop.
    840  */
    841 function bp_group_type( $group = false ) {
    842     echo bp_get_group_type( $group );
    843 }
    844 
    845 /**
    846  * Get the type of the current group in the loop.
    847  *
    848  * @since 1.0.0
    849  *
    850  * @param object|bool $group Optional. Group object.
    851  *                           Default: current group in loop.
    852  * @return string
    853  */
    854 function bp_get_group_type( $group = false ) {
    855     global $groups_template;
    856 
    857     if ( empty( $group ) ) {
    858         $group =& $groups_template->group;
    859     }
    860 
    861     if ( 'public' == $group->status ) {
    862         $type = __( "Public Group", "buddypress" );
    863     } elseif ( 'hidden' == $group->status ) {
    864         $type = __( "Hidden Group", "buddypress" );
    865     } elseif ( 'private' == $group->status ) {
    866         $type = __( "Private Group", "buddypress" );
    867     } else {
    868         $type = ucwords( $group->status ) . ' ' . __( 'Group', 'buddypress' );
    869     }
    870 
    871     /**
    872      * Filters the type for the current group in the loop.
    873      *
    874      * @since 1.0.0
    875      * @since 2.5.0 Added the `$group` parameter.
    876      *
    877      * @param string $type  Type for the current group in the loop.
    878      * @param object $group Group object.
    879      */
    880     return apply_filters( 'bp_get_group_type', $type, $group );
    881 }
    882 /**
    883  * Output the status of the current group in the loop.
    884  *
    885  * @since 1.1.0
    886  *
    887  * @param object|bool $group Optional. Group object.
    888  *                           Default: current group in loop.
    889  */
    890 function bp_group_status( $group = false ) {
    891     echo bp_get_group_status( $group );
    892 }
    893     /**
    894      * Get the status of the current group in the loop.
    895      *
    896      * @since 1.1.0
    897      *
    898      * @param object|bool $group Optional. Group object.
    899      *                           Default: current group in loop.
    900      * @return string
    901      */
    902     function bp_get_group_status( $group = false ) {
    903         global $groups_template;
    904 
    905         if ( empty( $group ) ) {
    906             $group =& $groups_template->group;
    907         }
    908 
    909         /**
    910          * Filters the status of the current group in the loop.
    911          *
    912          * @since 1.0.0
    913          * @since 2.5.0 Added the `$group` parameter.
    914          *
    915          * @param string $status Status of the current group in the loop.
    916          * @param object $group  Group object.
    917          */
    918         return apply_filters( 'bp_get_group_status', $group->status, $group );
    919     }
    920 
    921 /**
    922  * Output the group avatar while in the groups loop.
    923  *
    924  * @since 1.0.0
    925  *
    926  * @param array|string $args {
    927  *      See {@link bp_get_group_avatar()} for description of arguments.
    928  * }
    929  */
    930 function bp_group_avatar( $args = '' ) {
    931     echo bp_get_group_avatar( $args );
    932 }
    933     /**
    934      * Get a group's avatar.
    935      *
    936      * @since 1.0.0
    937      *
    938      * @see bp_core_fetch_avatar() For a description of arguments and return values.
    939 
    940      * @param array|string $args {
    941      *     Arguments are listed here with an explanation of their defaults.
    942      *     For more information about the arguments, see {@link bp_core_fetch_avatar()}.
    943      *
    944      *     @type string   $alt     Default: 'Group logo of [group name]'.
    945      *     @type string   $class   Default: 'avatar'.
    946      *     @type string   $type    Default: 'full'.
    947      *     @type int|bool $width   Default: false.
    948      *     @type int|bool $height  Default: false.
    949      *     @type bool     $id      Passed to `$css_id` parameter.
    950      * }
    951      * @return string Group avatar string.
    952      */
    953     function bp_get_group_avatar( $args = '' ) {
    954         global $groups_template;
    955 
    956         // Bail if avatars are turned off.
    957         if ( bp_disable_group_avatar_uploads() || ! buddypress()->avatar->show_avatars ) {
    958             return false;
    959         }
    960 
    961         // Parse the arguments.
    962         $r = bp_parse_args( $args, array(
    963             'type'   => 'full',
    964             'width'  => false,
    965             'height' => false,
    966             'class'  => 'avatar',
    967             'id'     => false,
    968             'alt'    => sprintf( __( 'Group logo of %s', 'buddypress' ), $groups_template->group->name )
    969         ) );
    970 
    971         // Fetch the avatar from the folder.
    972         $avatar = bp_core_fetch_avatar( array(
    973             'item_id'    => $groups_template->group->id,
    974             'title'      => $groups_template->group->name,
    975             'avatar_dir' => 'group-avatars',
    976             'object'     => 'group',
    977             'type'       => $r['type'],
    978             'alt'        => $r['alt'],
    979             'css_id'     => $r['id'],
    980             'class'      => $r['class'],
    981             'width'      => $r['width'],
    982             'height'     => $r['height']
    983         ) );
    984 
    985         // If No avatar found, provide some backwards compatibility.
    986         if ( empty( $avatar ) ) {
    987             $avatar = '<img src="' . esc_url( $groups_template->group->avatar_thumb ) . '" class="avatar" alt="' . esc_attr( $groups_template->group->name ) . '" />';
    988         }
    989 
    990         /**
    991          * Filters the group avatar while in the groups loop.
    992          *
    993          * @since 1.0.0
    994          *
    995          * @param string $avatar HTML image element holding the group avatar.
    996          * @param array  $r      Array of parsed arguments for the group avatar.
    997          */
    998         return apply_filters( 'bp_get_group_avatar', $avatar, $r );
    999     }
    1000 
    1001 /**
    1002  * Output the group avatar thumbnail while in the groups loop.
    1003  *
    1004  * @since 1.0.0
    1005  *
    1006  * @param object|bool $group Optional. Group object.
    1007  *                           Default: current group in loop.
    1008  */
    1009 function bp_group_avatar_thumb( $group = false ) {
    1010     echo bp_get_group_avatar_thumb( $group );
    1011 }
    1012     /**
    1013      * Return the group avatar thumbnail while in the groups loop.
    1014      *
    1015      * @since 1.0.0
    1016      *
    1017      * @param object|bool $group Optional. Group object.
    1018      *                           Default: current group in loop.
    1019      * @return string
    1020      */
    1021     function bp_get_group_avatar_thumb( $group = false ) {
    1022         return bp_get_group_avatar( array(
    1023             'type' => 'thumb',
    1024             'id'   => ! empty( $group->id ) ? $group->id : false
    1025         ) );
    1026     }
    1027 
    1028 /**
    1029  * Output the miniature group avatar thumbnail while in the groups loop.
    1030  *
    1031  * @since 1.0.0
    1032  *
    1033  * @param object|bool $group Optional. Group object.
    1034  *                           Default: current group in loop.
    1035  */
    1036 function bp_group_avatar_mini( $group = false ) {
    1037     echo bp_get_group_avatar_mini( $group );
    1038 }
    1039     /**
    1040      * Return the miniature group avatar thumbnail while in the groups loop.
    1041      *
    1042      * @since 1.0.0
    1043      *
    1044      * @param object|bool $group Optional. Group object.
    1045      *                           Default: current group in loop.
    1046      * @return string
    1047      */
    1048     function bp_get_group_avatar_mini( $group = false ) {
    1049         return bp_get_group_avatar( array(
    1050             'type'   => 'thumb',
    1051             'width'  => 30,
    1052             'height' => 30,
    1053             'id'     => ! empty( $group->id ) ? $group->id : false
    1054         ) );
    1055     }
    1056 
    1057 /** Group cover image *********************************************************/
    1058 
    1059 /**
    1060  * Should we use the group's cover image header.
    1061  *
    1062  * @since 2.4.0
    1063  *
    1064  * @return bool True if the displayed user has a cover image,
    1065  *              False otherwise
    1066  */
    1067 function bp_group_use_cover_image_header() {
    1068     return (bool) bp_is_active( 'groups', 'cover_image' ) && ! bp_disable_group_cover_image_uploads() && bp_attachments_is_wp_version_supported();
    1069 }
    1070 
    1071 /**
    1072  * Output the 'last active' string for the current group in the loop.
    1073  *
    1074  * @since 1.0.0
    1075  *
    1076  * @param object|bool $group Optional. Group object.
    1077  *                           Default: current group in loop.
    1078  */
    1079 function bp_group_last_active( $group = false ) {
    1080     echo bp_get_group_last_active( $group );
    1081 }
    1082     /**
    1083      * Return the 'last active' string for the current group in the loop.
    1084      *
    1085      * @since 1.0.0
    1086      *
    1087      * @param object|bool $group Optional. Group object.
    1088      *                           Default: current group in loop.
    1089      * @return string
    1090      */
    1091     function bp_get_group_last_active( $group = false ) {
    1092         global $groups_template;
    1093 
    1094         if ( empty( $group ) ) {
    1095             $group =& $groups_template->group;
    1096         }
    1097 
    1098         $last_active = $group->last_activity;
    1099 
    1100         if ( !$last_active ) {
    1101             $last_active = groups_get_groupmeta( $group->id, 'last_activity' );
    1102         }
    1103 
    1104         if ( empty( $last_active ) ) {
    1105             return __( 'not yet active', 'buddypress' );
    1106         } else {
    1107 
    1108             /**
    1109              * Filters the 'last active' string for the current gorup in the loop.
    1110              *
    1111              * @since 1.0.0
    1112              * @since 2.5.0 Added the `$group` parameter.
    1113              *
    1114              * @param string $value Determined last active value for the current group.
    1115              * @param object $group Group object.
    1116              */
    1117             return apply_filters( 'bp_get_group_last_active', bp_core_time_since( $last_active ), $group );
    1118         }
    1119     }
    1120 
    1121 /**
    1122  * Output the permalink for the current group in the loop.
    1123  *
    1124  * @since 1.0.0
    1125  *
    1126  * @param object|bool $group Optional. Group object.
    1127  *                           Default: current group in loop.
    1128  */
    1129 function bp_group_permalink( $group = false ) {
    1130     echo bp_get_group_permalink( $group );
    1131 }
    1132     /**
    1133      * Return the permalink for the current group in the loop.
    1134      *
    1135      * @since 1.0.0
    1136      *
    1137      * @param object|bool $group Optional. Group object.
    1138      *                           Default: current group in loop.
    1139      * @return string
    1140      */
    1141     function bp_get_group_permalink( $group = false ) {
    1142         global $groups_template;
    1143 
    1144         if ( empty( $group ) ) {
    1145             $group =& $groups_template->group;
    1146         }
    1147 
    1148         /**
    1149          * Filters the permalink for the current group in the loop.
    1150          *
    1151          * @since 1.0.0
    1152          * @since 2.5.0 Added the `$group` parameter.
    1153          *
    1154          * @param string $value Permalink for the current group in the loop.
    1155          * @param object $group Group object.
    1156          */
    1157         return apply_filters( 'bp_get_group_permalink', trailingslashit( bp_get_groups_directory_permalink() . $group->slug . '/' ), $group );
    1158     }
    1159 
    1160 /**
    1161  * Output the permalink for the admin section of the current group in the loop.
    1162  *
    1163  * @since 1.0.0
    1164  *
    1165  * @param object|bool $group Optional. Group object.
    1166  *                           Default: current group in loop.
    1167  */
    1168 function bp_group_admin_permalink( $group = false ) {
    1169     echo bp_get_group_admin_permalink( $group );
    1170 }
    1171     /**
    1172      * Return the permalink for the admin section of the current group in the loop.
    1173      *
    1174      * @since 1.0.0
    1175      *
    1176      * @param object|bool $group Optional. Group object.
    1177      *                           Default: current group in loop.
    1178      * @return string
    1179      */
    1180     function bp_get_group_admin_permalink( $group = false ) {
    1181         global $groups_template;
    1182 
    1183         if ( empty( $group ) ) {
    1184             $group =& $groups_template->group;
    1185         }
    1186 
    1187         /**
    1188          * Filters the permalink for the admin section of the current group in the loop.
    1189          *
    1190          * @since 1.0.0
    1191          * @since 2.5.0 Added the `$group` parameter.
    1192          *
    1193          * @param string $value Permalink for the admin section of the current group in the loop.
    1194          * @param object $group Group object.
    1195          */
    1196         return apply_filters( 'bp_get_group_admin_permalink', trailingslashit( bp_get_group_permalink( $group ) . 'admin' ), $group );
    1197     }
    1198 
    1199 /**
    1200  * Return the slug for the current group in the loop.
    1201  *
    1202  * @since 1.0.0
    1203  *
    1204  * @param object|bool $group Optional. Group object.
    1205  *                           Default: current group in loop.
    1206  */
    1207 function bp_group_slug( $group = false ) {
    1208     echo bp_get_group_slug( $group );
    1209 }
    1210     /**
    1211      * Return the slug for the current group in the loop.
    1212      *
    1213      * @since 1.0.0
    1214      *
    1215      * @param object|bool $group Optional. Group object.
    1216      *                           Default: current group in loop.
    1217      * @return string
    1218      */
    1219     function bp_get_group_slug( $group = false ) {
    1220         global $groups_template;
    1221 
    1222         if ( empty( $group ) ) {
    1223             $group =& $groups_template->group;
    1224         }
    1225 
    1226         /**
    1227          * Filters the slug for the current group in the loop.
    1228          *
    1229          * @since 1.0.0
    1230          * @since 2.5.0 Added the `$group` parameter.
    1231          *
    1232          * @param string $slug  Slug for the current group in the loop.
    1233          * @param object $group Group object.
    1234          */
    1235         return apply_filters( 'bp_get_group_slug', $group->slug, $group );
    1236     }
    1237 
    1238 /**
    1239  * Output the description for the current group in the loop.
    1240  *
    1241  * @since 1.0.0
    1242  *
    1243  * @param object|bool $group Optional. Group object.
    1244  *                           Default: current group in loop.
    1245  */
    1246 function bp_group_description( $group = false ) {
    1247     echo bp_get_group_description( $group );
    1248 }
    1249     /**
    1250      * Return the description for the current group in the loop.
    1251      *
    1252      * @since 1.0.0
    1253      *
    1254      * @param object|bool $group Optional. Group object.
    1255      *                           Default: current group in loop.
    1256      * @return string
    1257      */
    1258     function bp_get_group_description( $group = false ) {
    1259         global $groups_template;
    1260 
    1261         if ( empty( $group ) ) {
    1262             $group =& $groups_template->group;
    1263         }
    1264 
    1265         /**
    1266          * Filters the description for the current group in the loop.
    1267          *
    1268          * @since 1.0.0
    1269          * @since 2.5.0 Added the `$group` parameter.
    1270          *
    1271          * @param string $value Description for the current group.
    1272          * @param object $group Group object.
    1273          */
    1274         return apply_filters( 'bp_get_group_description', stripslashes( $group->description ), $group );
    1275     }
    1276 
    1277 /**
    1278  * Output the description for the current group in the loop, for use in a textarea.
    1279  *
    1280  * @since 1.0.0
    1281  *
    1282  * @param object|bool $group Optional. Group object.
    1283  *                           Default: current group in loop.
    1284  */
    1285 function bp_group_description_editable( $group = false ) {
    1286     echo bp_get_group_description_editable( $group );
    1287 }
    1288     /**
    1289      * Return the permalink for the current group in the loop, for use in a textarea.
    1290      *
    1291      * 'bp_get_group_description_editable' does not have the formatting
    1292      * filters that 'bp_get_group_description' has, which makes it
    1293      * appropriate for "raw" editing.
    1294      *
    1295      * @since 1.0.0
    1296      *
    1297      * @param object|bool $group Optional. Group object.
    1298      *                           Default: current group in loop.
    1299      * @return string
    1300      */
    1301     function bp_get_group_description_editable( $group = false ) {
    1302         global $groups_template;
    1303 
    1304         if ( empty( $group ) ) {
    1305             $group =& $groups_template->group;
    1306         }
    1307 
    1308         /**
    1309          * Filters the permalink for the current group in the loop, for use in a textarea.
    1310          *
    1311          * 'bp_get_group_description_editable' does not have the formatting filters that
    1312          * 'bp_get_group_description' has, which makes it appropriate for "raw" editing.
    1313          *
    1314          * @since 1.0.0
    1315          * @since 2.5.0 Added the `$group` parameter.
    1316          *
    1317          * @param string $description Description for the current group in the loop.
    1318          * @param object $group       Group object.
    1319          */
    1320         return apply_filters( 'bp_get_group_description_editable', $group->description, $group );
    1321     }
    1322 
    1323 /**
    1324  * Output an excerpt of the group description.
    1325  *
    1326  * @since 1.0.0
    1327  *
    1328  * @param object|bool $group Optional. The group being referenced.
    1329  *                           Defaults to the group currently being
    1330  *                           iterated on in the groups loop.
    1331  */
    1332 function bp_group_description_excerpt( $group = false ) {
    1333     echo bp_get_group_description_excerpt( $group );
    1334 }
    1335     /**
    1336      * Get an excerpt of a group description.
    1337      *
    1338      * @since 1.0.0
    1339      *
    1340      * @param object|bool $group Optional. The group being referenced.
    1341      *                           Defaults to the group currently being
    1342      *                           iterated on in the groups loop.
    1343      * @return string Excerpt.
    1344      */
    1345     function bp_get_group_description_excerpt( $group = false ) {
    1346         global $groups_template;
    1347 
    1348         if ( empty( $group ) ) {
    1349             $group =& $groups_template->group;
    1350         }
    1351 
    1352         /**
    1353          * Filters the excerpt of a group description.
    1354          *
    1355          * @since 1.0.0
    1356          *
    1357          * @param string $value Excerpt of a group description.
    1358          * @param object $group Object for group whose description is made into an excerpt.
    1359          */
    1360         return apply_filters( 'bp_get_group_description_excerpt', bp_create_excerpt( $group->description ), $group );
    1361     }
    1362 
    1363 /**
    1364  * Output the status of the current group in the loop.
    1365  *
    1366  * Either 'Public' or 'Private'.
    1367  *
    1368  * @since 1.0.0
    1369  *
    1370  * @param object|bool $group Optional. Group object.
    1371  *                           Default: current group in loop.
    1372  */
    1373 function bp_group_public_status( $group = false ) {
    1374     echo bp_get_group_public_status( $group );
    1375 }
    1376     /**
    1377      * Return the status of the current group in the loop.
    1378      *
    1379      * Either 'Public' or 'Private'.
    1380      *
    1381      * @since 1.0.0
    1382      *
    1383      * @param object|bool $group Optional. Group object.
    1384      *                           Default: current group in loop.
    1385      * @return string
    1386      */
    1387     function bp_get_group_public_status( $group = false ) {
    1388         global $groups_template;
    1389 
    1390         if ( empty( $group ) ) {
    1391             $group =& $groups_template->group;
    1392         }
    1393 
    1394         if ( $group->is_public ) {
    1395             return __( 'Public', 'buddypress' );
    1396         } else {
    1397             return __( 'Private', 'buddypress' );
    1398         }
    1399     }
    1400 
    1401 /**
    1402  * Output whether the current group in the loop is public.
    1403  *
    1404  * No longer used in BuddyPress.
    1405  *
    1406  * @param object|bool $group Optional. Group object.
    1407  *                           Default: current group in loop.
    1408  */
    1409 function bp_group_is_public( $group = false ) {
    1410     echo bp_get_group_is_public( $group );
    1411 }
    1412     /**
    1413      * Return whether the current group in the loop is public.
    1414      *
    1415      * No longer used in BuddyPress.
    1416      *
    1417      * @param object|bool $group Optional. Group object.
    1418      *                           Default: current group in loop.
    1419      * @return mixed
    1420      */
    1421     function bp_get_group_is_public( $group = false ) {
    1422         global $groups_template;
    1423 
    1424         if ( empty( $group ) ) {
    1425             $group =& $groups_template->group;
    1426         }
    1427 
    1428         /**
    1429          * Filters whether the current group in the loop is public.
    1430          *
    1431          * @since 2.5.0 Added the `$group` parameter.
    1432          *
    1433          * @param bool   $public True if the group is public.
    1434          * @param object $group Group object.
    1435          */
    1436         return apply_filters( 'bp_get_group_is_public', $group->is_public, $group );
    1437     }
    1438 
    1439 /**
    1440  * Output the created date of the current group in the loop.
    1441  *
    1442  * @since 1.0.0
    1443  *
    1444  * @param object|bool $group Optional. Group object.
    1445  *                           Default: current group in loop.
    1446  */
    1447 function bp_group_date_created( $group = false ) {
    1448     echo bp_get_group_date_created( $group );
    1449 }
    1450     /**
    1451      * Return the created date of the current group in the loop.
    1452      *
    1453      * @since 1.0.0
    1454      *
    1455      * @param object|bool $group Optional. Group object.
    1456      *                           Default: current group in loop.
    1457      * @return string
    1458      */
    1459     function bp_get_group_date_created( $group = false ) {
    1460         global $groups_template;
    1461 
    1462         if ( empty( $group ) ) {
    1463             $group =& $groups_template->group;
    1464         }
    1465 
    1466         /**
    1467          * Filters the created date of the current group in the loop.
    1468          *
    1469          * @since 1.0.0
    1470          * @since 2.5.0 Added the `$group` parameter.
    1471          *
    1472          * @param string $value Created date for the current group.
    1473          * @param object $group Group object.
    1474          */
    1475         return apply_filters( 'bp_get_group_date_created', bp_core_time_since( strtotime( $group->date_created ) ), $group );
    1476     }
    1477 
    1478 /**
    1479  * Output the username of the creator of the current group in the loop.
    1480  *
    1481  * @since 1.7.0
    1482  *
    1483  * @param object|bool $group Optional. Group object.
    1484  *                           Default: current group in loop.
    1485  */
    1486 function bp_group_creator_username( $group = false ) {
    1487     echo bp_get_group_creator_username( $group );
    1488 }
    1489     /**
    1490      * Return the username of the creator of the current group in the loop.
    1491      *
    1492      * @since 1.7.0
    1493      *
    1494      * @param object|bool $group Optional. Group object.
    1495      *                           Default: current group in loop.
    1496      * @return string
    1497      */
    1498     function bp_get_group_creator_username( $group = false ) {
    1499         global $groups_template;
    1500 
    1501         if ( empty( $group ) ) {
    1502             $group =& $groups_template->group;
    1503         }
    1504 
    1505         /**
    1506          * Filters the username of the creator of the current group in the loop.
    1507          *
    1508          * @since 1.7.0
    1509          * @since 2.5.0 Added the `$group` parameter.
    1510          *
    1511          * @param string $value Username of the group creator.
    1512          * @param object $group Group object.
    1513          */
    1514         return apply_filters( 'bp_get_group_creator_username', bp_core_get_user_displayname( $group->creator_id ), $group );
    1515     }
    1516 
    1517 /**
    1518  * Output the user ID of the creator of the current group in the loop.
    1519  *
    1520  * @since 1.7.0
    1521  *
    1522  * @param object|bool $group Optional. Group object.
    1523  *                           Default: current group in loop.
    1524  */
    1525 function bp_group_creator_id( $group = false ) {
    1526     echo bp_get_group_creator_id( $group );
    1527 }
    1528     /**
    1529      * Return the user ID of the creator of the current group in the loop.
    1530      *
    1531      * @since 1.7.0
    1532      *
    1533      * @param object|bool $group Optional. Group object.
    1534      *                           Default: current group in loop.
    1535      * @return int
    1536      */
    1537     function bp_get_group_creator_id( $group = false ) {
    1538         global $groups_template;
    1539 
    1540         if ( empty( $group ) ) {
    1541             $group =& $groups_template->group;
    1542         }
    1543 
    1544         /**
    1545          * Filters the user ID of the creator of the current group in the loop.
    1546          *
    1547          * @since 1.7.0
    1548          * @since 2.5.0 Added the `$group` parameter.
    1549          *
    1550          * @param int $creator_id User ID of the group creator.
    1551          * @param object $group Group object.
    1552          */
    1553         return apply_filters( 'bp_get_group_creator_id', $group->creator_id, $group );
    1554     }
    1555 
    1556 /**
    1557  * Output the permalink of the creator of the current group in the loop.
    1558  *
    1559  * @since 1.7.0
    1560  *
    1561  * @param object|bool $group Optional. Group object.
    1562  *                           Default: current group in loop.
    1563  */
    1564 function bp_group_creator_permalink( $group = false ) {
    1565     echo bp_get_group_creator_permalink( $group );
    1566 }
    1567     /**
    1568      * Return the permalink of the creator of the current group in the loop.
    1569      *
    1570      * @since 1.7.0
    1571      *
    1572      * @param object|bool $group Optional. Group object.
    1573      *                           Default: current group in loop.
    1574      * @return string
    1575      */
    1576     function bp_get_group_creator_permalink( $group = false ) {
    1577         global $groups_template;
    1578 
    1579         if ( empty( $group ) ) {
    1580             $group =& $groups_template->group;
    1581         }
    1582 
    1583         /**
    1584          * Filters the permalink of the creator of the current group in the loop.
    1585          *
    1586          * @since 1.7.0
    1587          * @since 2.5.0 Added the `$group` parameter.
    1588          *
    1589          * @param string $value Permalink of the group creator.
    1590          * @param object $group Group object.
    1591          */
    1592         return apply_filters( 'bp_get_group_creator_permalink', bp_core_get_user_domain( $group->creator_id ), $group );
    1593     }
    1594 
    1595 /**
    1596  * Determine whether a user is the creator of the current group in the loop.
    1597  *
    1598  * @since 1.7.0
    1599  *
    1600  * @param object|bool $group   Optional. Group object.
    1601  *                             Default: current group in loop.
    1602  * @param int         $user_id ID of the user.
    1603  * @return bool
    1604  */
    1605 function bp_is_group_creator( $group = false, $user_id = 0 ) {
    1606     global $groups_template;
    1607 
    1608     if ( empty( $group ) ) {
    1609         $group =& $groups_template->group;
    1610     }
    1611 
    1612     if ( empty( $user_id ) ) {
    1613         $user_id = bp_loggedin_user_id();
    1614     }
    1615 
    1616     return (bool) ( $group->creator_id == $user_id );
    1617 }
    1618 
    1619 /**
    1620  * Output the avatar of the creator of the current group in the loop.
    1621  *
    1622  * @since 1.7.0
    1623  *
    1624  * @param object|bool $group Optional. Group object.
    1625  *                           Default: current group in loop.
    1626  * @param array       $args {
    1627  *     Array of optional arguments. See {@link bp_get_group_creator_avatar()}
    1628  *     for description.
    1629  * }
    1630  */
    1631 function bp_group_creator_avatar( $group = false, $args = array() ) {
    1632     echo bp_get_group_creator_avatar( $group, $args );
    1633 }
    1634     /**
    1635      * Return the avatar of the creator of the current group in the loop.
    1636      *
    1637      * @since 1.7.0
    1638      *
    1639      * @param object|bool $group Optional. Group object.
    1640      *                           Default: current group in loop.
    1641      * @param array       $args {
    1642      *     Array of optional arguments. See {@link bp_core_fetch_avatar()}
    1643      *     for detailed description of arguments.
    1644      *     @type string $type   Default: 'full'.
    1645      *     @type int    $width  Default: false.
    1646      *     @type int    $height Default: false.
    1647      *     @type int    $class  Default: 'avatar'.
    1648      *     @type string $id     Passed to 'css_id'. Default: false.
    1649      *     @type string $alt    Alt text. Default: 'Group creator profile
    1650      *                          photo of [user display name]'.
    1651      * }
    1652      * @return string
    1653      */
    1654     function bp_get_group_creator_avatar( $group = false, $args = array() ) {
    1655         global $groups_template;
    1656 
    1657         if ( empty( $group ) ) {
    1658             $group =& $groups_template->group;
    1659         }
    1660 
    1661         $defaults = array(
    1662             'type'   => 'full',
    1663             'width'  => false,
    1664             'height' => false,
    1665             'class'  => 'avatar',
    1666             'id'     => false,
    1667             'alt'    => sprintf( __( 'Group creator profile photo of %s', 'buddypress' ),  bp_core_get_user_displayname( $group->creator_id ) )
    1668         );
    1669 
    1670         $r = wp_parse_args( $args, $defaults );
    1671         extract( $r, EXTR_SKIP );
    1672 
    1673         $avatar = bp_core_fetch_avatar( array( 'item_id' => $group->creator_id, 'type' => $type, 'css_id' => $id, 'class' => $class, 'width' => $width, 'height' => $height, 'alt' => $alt ) );
    1674 
    1675         /**
    1676          * Filters the avatar of the creator of the current group in the loop.
    1677          *
    1678          * @since 1.7.0
    1679          * @since 2.5.0 Added the `$group` parameter.
    1680          *
    1681          * @param string $avatar Avatar of the group creator.
    1682          * @param object $group  Group object.
    1683          */
    1684         return apply_filters( 'bp_get_group_creator_avatar', $avatar, $group );
    1685     }
    1686 
    1687 /**
    1688  * Determine whether the current user is the admin of the current group.
    1689  *
    1690  * Alias of {@link bp_is_item_admin()}.
    1691  *
    1692  * @since 1.1.0
    1693  *
    1694  * @return bool
    1695  */
    1696 function bp_group_is_admin() {
    1697     return bp_is_item_admin();
    1698 }
    1699 
    1700 /**
    1701  * Determine whether the current user is a mod of the current group.
    1702  *
    1703  * Alias of {@link bp_is_item_mod()}.
    1704  *
    1705  * @since 1.1.0
    1706  *
    1707  * @return bool
    1708  */
    1709 function bp_group_is_mod() {
    1710     return bp_is_item_mod();
    1711 }
    1712 
    1713 /**
    1714  * Output markup listing group admins.
    1715  *
    1716  * @since 1.0.0
    1717  *
    1718  * @param object|bool $group Optional. Group object.
    1719  *                           Default: current group in loop.
    1720  */
    1721 function bp_group_list_admins( $group = false ) {
    1722     global $groups_template;
    1723 
    1724     if ( empty( $group ) ) {
    1725         $group =& $groups_template->group;
    1726     }
    1727 
    1728     // Fetch group admins if 'populate_extras' flag is false.
    1729     if ( empty( $group->args['populate_extras'] ) ) {
    1730         $query = new BP_Group_Member_Query( array(
    1731             'group_id'   => $group->id,
    1732             'group_role' => 'admin',
    1733             'type'       => 'first_joined',
    1734         ) );
    1735 
    1736         if ( ! empty( $query->results ) ) {
    1737             $group->admins = $query->results;
    1738         }
    1739     }
    1740 
    1741     if ( ! empty( $group->admins ) ) { ?>
    1742         <ul id="group-admins">
    1743             <?php foreach( (array) $group->admins as $admin ) { ?>
    1744                 <li>
    1745                     <a href="<?php echo bp_core_get_user_domain( $admin->user_id, $admin->user_nicename, $admin->user_login ) ?>"><?php echo bp_core_fetch_avatar( array( 'item_id' => $admin->user_id, 'email' => $admin->user_email, 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $admin->user_id ) ) ) ) ?></a>
    1746                 </li>
    1747             <?php } ?>
    1748         </ul>
    1749     <?php } else { ?>
    1750         <span class="activity"><?php _e( 'No Admins', 'buddypress' ) ?></span>
    1751     <?php } ?>
    1752 <?php
    1753 }
    1754 
    1755 /**
    1756  * Output markup listing group mod.
    1757  *
    1758  * @since 1.0.0
    1759  *
    1760  * @param object|bool $group Optional. Group object.
    1761  *                           Default: current group in loop.
    1762  */
    1763 function bp_group_list_mods( $group = false ) {
    1764     global $groups_template;
    1765 
    1766     if ( empty( $group ) ) {
    1767         $group =& $groups_template->group;
    1768     }
    1769 
    1770     // Fetch group mods if 'populate_extras' flag is false.
    1771     if ( empty( $group->args['populate_extras'] ) ) {
    1772         $query = new BP_Group_Member_Query( array(
    1773             'group_id'   => $group->id,
    1774             'group_role' => 'mod',
    1775             'type'       => 'first_joined',
    1776         ) );
    1777 
    1778         if ( ! empty( $query->results ) ) {
    1779             $group->mods = $query->results;
    1780         }
    1781     }
    1782 
    1783     if ( ! empty( $group->mods ) ) : ?>
    1784 
    1785         <ul id="group-mods">
    1786 
    1787             <?php foreach( (array) $group->mods as $mod ) { ?>
    1788 
    1789                 <li>
    1790                     <a href="<?php echo bp_core_get_user_domain( $mod->user_id, $mod->user_nicename, $mod->user_login ) ?>"><?php echo bp_core_fetch_avatar( array( 'item_id' => $mod->user_id, 'email' => $mod->user_email, 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $mod->user_id ) ) ) ) ?></a>
    1791                 </li>
    1792 
    1793             <?php } ?>
    1794 
    1795         </ul>
    1796 
    1797 <?php else : ?>
    1798 
    1799         <span class="activity"><?php _e( 'No Mods', 'buddypress' ) ?></span>
    1800 
    1801 <?php endif;
    1802 
    1803 }
    1804 
    1805 /**
    1806  * Return a list of user IDs for a group's admins.
    1807  *
    1808  * @since 1.5.0
    1809  *
    1810  * @param BP_Groups_Group|bool $group     Optional. The group being queried. Defaults
    1811  *                                        to the current group in the loop.
    1812  * @param string               $format    Optional. 'string' to get a comma-separated string,
    1813  *                                        'array' to get an array.
    1814  * @return mixed               $admin_ids A string or array of user IDs.
    1815  */
    1816 function bp_group_admin_ids( $group = false, $format = 'string' ) {
    1817     global $groups_template;
    1818 
    1819     if ( empty( $group ) ) {
    1820         $group =& $groups_template->group;
    1821     }
    1822 
    1823     $admin_ids = array();
    1824 
    1825     if ( $group->admins ) {
    1826         foreach( $group->admins as $admin ) {
    1827             $admin_ids[] = $admin->user_id;
    1828         }
    1829     }
    1830 
    1831     if ( 'string' == $format ) {
    1832         $admin_ids = implode( ',', $admin_ids );
    1833     }
    1834 
    1835     /**
    1836      * Filters a list of user IDs for a group's admins.
    1837      *
    1838      * This filter may return either an array or a comma separated string.
    1839      *
    1840      * @since 1.5.0
    1841      * @since 2.5.0 Added the `$group` parameter.
    1842      *
    1843      * @param array|string $admin_ids List of user IDs for a group's admins.
    1844      * @param object       $group     Group object.
    1845      */
    1846     return apply_filters( 'bp_group_admin_ids', $admin_ids, $group );
    1847 }
    1848 
    1849 /**
    1850  * Return a list of user IDs for a group's moderators.
    1851  *
    1852  * @since 1.5.0
    1853  *
    1854  * @param BP_Groups_Group|bool $group   Optional. The group being queried.
    1855  *                                      Defaults to the current group in the loop.
    1856  * @param string               $format  Optional. 'string' to get a comma-separated string,
    1857  *                                      'array' to get an array.
    1858  * @return mixed               $mod_ids A string or array of user IDs.
    1859  */
    1860 function bp_group_mod_ids( $group = false, $format = 'string' ) {
    1861     global $groups_template;
    1862 
    1863     if ( empty( $group ) ) {
    1864         $group =& $groups_template->group;
    1865     }
    1866 
    1867     $mod_ids = array();
    1868 
    1869     if ( $group->mods ) {
    1870         foreach( $group->mods as $mod ) {
    1871             $mod_ids[] = $mod->user_id;
    1872         }
    1873     }
    1874 
    1875     if ( 'string' == $format ) {
    1876         $mod_ids = implode( ',', $mod_ids );
    1877     }
    1878 
    1879     /**
    1880      * Filters a list of user IDs for a group's moderators.
    1881      *
    1882      * This filter may return either an array or a comma separated string.
    1883      *
    1884      * @since 1.5.0
    1885      * @since 2.5.0 Added the `$group` parameter.
    1886      *
    1887      * @param array|string $admin_ids List of user IDs for a group's moderators.
    1888      * @param object       $group     Group object.
    1889      */
    1890     return apply_filters( 'bp_group_mod_ids', $mod_ids, $group );
    1891 }
    1892 
    1893 /**
    1894  * Output the permalink of the current group's Members page.
    1895  *
    1896  * @since 1.0.0
    1897  */
    1898 function bp_group_all_members_permalink() {
    1899     echo bp_get_group_all_members_permalink();
    1900 }
    1901     /**
    1902      * Return the permalink of the Members page of the current group in the loop.
    1903      *
    1904      * @since 1.0.0
    1905      *
    1906      * @param object|bool $group Optional. Group object.
    1907      *                           Default: current group in loop.
    1908      * @return string
    1909      */
    1910     function bp_get_group_all_members_permalink( $group = false ) {
    1911         global $groups_template;
    1912 
    1913         if ( empty( $group ) ) {
    1914             $group =& $groups_template->group;
    1915         }
    1916 
    1917         /**
    1918          * Filters the permalink of the Members page for the current group in the loop.
    1919          *
    1920          * @since 1.0.0
    1921          * @since 2.5.0 Added the `$group` parameter.
    1922          *
    1923          * @param string $value Permalink of the Members page for the current group.
    1924          * @param object $group Group object.
    1925          */
    1926         return apply_filters( 'bp_get_group_all_members_permalink', bp_get_group_permalink( $group ) . 'members', $group );
    1927     }
    1928 
    1929 /**
    1930  * Display a Groups search form.
    1931  *
    1932  * No longer used in BuddyPress.
    1933  *
    1934  * @todo Deprecate.
    1935  */
    1936 function bp_group_search_form() {
    1937 
    1938     $action = bp_displayed_user_domain() . bp_get_groups_slug() . '/my-groups/search/';
    1939     $label = __('Filter Groups', 'buddypress');
    1940     $name = 'group-filter-box';
    1941 
    1942     $search_form_html = '<form action="' . $action . '" id="group-search-form" method="post">
    1943         <label for="'. $name .'" id="'. $name .'-label">'. $label .'</label>
    1944         <input type="search" name="'. $name . '" id="'. $name .'" value="'. $value .'"'.  $disabled .' />
    1945 
    1946         '. wp_nonce_field( 'group-filter-box', '_wpnonce_group_filter', true, false ) .'
    1947         </form>';
    1948 
    1949     echo apply_filters( 'bp_group_search_form', $search_form_html );
    1950 }
    1951 
    1952 /**
    1953  * Determine whether the displayed user has no groups.
    1954  *
    1955  * No longer used in BuddyPress.
    1956  *
    1957  * @todo Deprecate.
    1958  *
    1959  * @return bool True if the displayed user has no groups, otherwise false.
    1960  */
    1961 function bp_group_show_no_groups_message() {
    1962     if ( !groups_total_groups_for_user( bp_displayed_user_id() ) ) {
    1963         return true;
    1964     }
    1965 
    1966     return false;
    1967 }
    1968 
    1969 /**
    1970  * Determine whether the current page is a group activity permalink.
    1971  *
    1972  * No longer used in BuddyPress.
    1973  *
    1974  * @todo Deprecate.
    1975  *
    1976  * @return bool True if this is a group activity permalink, otherwise false.
    1977  */
    1978 function bp_group_is_activity_permalink() {
    1979 
    1980     if ( !bp_is_single_item() || !bp_is_groups_component() || !bp_is_current_action( bp_get_activity_slug() ) ) {
    1981         return false;
    1982     }
    1983 
    1984     return true;
    1985 }
    1986 
    1987 /**
    1988  * Output the pagination HTML for a group loop.
    1989  *
    1990  * @since 1.2.0
    1991  */
    1992 function bp_groups_pagination_links() {
    1993     echo bp_get_groups_pagination_links();
    1994 }
    1995     /**
    1996      * Get the pagination HTML for a group loop.
    1997      *
    1998      * @since 1.2.0
    1999      *
    2000      * @return string
    2001      */
    2002     function bp_get_groups_pagination_links() {
    2003         global $groups_template;
    2004 
    2005         /**
    2006          * Filters the pagination HTML for a group loop.
    2007          *
    2008          * @since 1.2.0
    2009          *
    2010          * @param string $pag_links HTML markup for the pagination links.
    2011          */
    2012         return apply_filters( 'bp_get_groups_pagination_links', $groups_template->pag_links );
    2013     }
    2014 
    2015 /**
    2016  * Output the "Viewing x-y of z groups" pagination message.
    2017  *
    2018  * @since 1.2.0
    2019  */
    2020 function bp_groups_pagination_count() {
    2021     echo bp_get_groups_pagination_count();
    2022 }
    2023     /**
    2024      * Generate the "Viewing x-y of z groups" pagination message.
    2025      *
    2026      * @since 1.5.0
    2027      *
    2028      * @return string
    2029      */
    2030     function bp_get_groups_pagination_count() {
    2031         global $groups_template;
    2032 
    2033         $start_num = intval( ( $groups_template->pag_page - 1 ) * $groups_template->pag_num ) + 1;
    2034         $from_num  = bp_core_number_format( $start_num );
    2035         $to_num    = bp_core_number_format( ( $start_num + ( $groups_template->pag_num - 1 ) > $groups_template->total_group_count ) ? $groups_template->total_group_count : $start_num + ( $groups_template->pag_num - 1 ) );
    2036         $total     = bp_core_number_format( $groups_template->total_group_count );
    2037 
    2038         if ( 1 == $groups_template->total_group_count ) {
    2039             $message = __( 'Viewing 1 group', 'buddypress' );
    2040         } else {
    2041             $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s group', 'Viewing %1$s - %2$s of %3$s groups', $groups_template->total_group_count, 'buddypress' ), $from_num, $to_num, $total );
    2042         }
    2043 
    2044         /**
    2045          * Filters the "Viewing x-y of z groups" pagination message.
    2046          *
    2047          * @since 1.5.0
    2048          *
    2049          * @param string $message  "Viewing x-y of z groups" text.
    2050          * @param string $from_num Total amount for the low value in the range.
    2051          * @param string $to_num   Total amount for the high value in the range.
    2052          * @param string $total    Total amount of groups found.
    2053          */
    2054         return apply_filters( 'bp_get_groups_pagination_count', $message, $from_num, $to_num, $total );
    2055     }
    2056 
    2057 /**
    2058  * Determine whether groups auto-join is enabled.
    2059  *
    2060  * "Auto-join" is the toggle that determines whether users are joined to a
    2061  * public group automatically when creating content in that group.
    2062  *
    2063  * @since 1.2.6
    2064  *
    2065  * @return bool
    2066  */
    2067 function bp_groups_auto_join() {
    2068 
    2069     /**
    2070      * Filters whether groups auto-join is enabled.
    2071      *
    2072      * @since 1.2.6
    2073      *
    2074      * @param bool $value Enabled status.
    2075      */
    2076     return apply_filters( 'bp_groups_auto_join', (bool) buddypress()->groups->auto_join );
    2077 }
    2078 
    2079 /**
    2080  * Output the total member count for a group.
    2081  *
    2082  * @since 1.0.0
    2083  *
    2084  * @param object|bool $group Optional. Group object. Default: current group in loop.
    2085  */
    2086 function bp_group_total_members( $group = false ) {
    2087     echo bp_get_group_total_members( $group );
    2088 }
    2089     /**
    2090      * Get the total member count for a group.
    2091      *
    2092      * @since 1.0.0
    2093      *
    2094      * @param object|bool $group Optional. Group object.
    2095      *                           Default: current group in loop.
    2096      * @return int
    2097      */
    2098     function bp_get_group_total_members( $group = false ) {
    2099         global $groups_template;
    2100 
    2101         if ( empty( $group ) ) {
    2102             $group =& $groups_template->group;
    2103         }
    2104 
    2105         /**
    2106          * Filters the total member count for a group.
    2107          *
    2108          * @since 1.0.0
    2109          * @since 2.5.0 Added the `$group` parameter.
    2110          *
    2111          * @param int    $total_member_count Total member count for a group.
    2112          * @param object $group              Group object.
    2113          */
    2114         return apply_filters( 'bp_get_group_total_members', $group->total_member_count, $group );
    2115     }
    2116 
    2117 /**
    2118  * Output the "x members" count string for a group.
    2119  *
    2120  * @since 1.2.0
    2121  */
    2122 function bp_group_member_count() {
    2123     echo bp_get_group_member_count();
    2124 }
    2125     /**
    2126      * Generate the "x members" count string for a group.
    2127      *
    2128      * @since 1.2.0
    2129      *
    2130      * @return string
    2131      */
    2132     function bp_get_group_member_count() {
    2133         global $groups_template;
    2134 
    2135         if ( isset( $groups_template->group->total_member_count ) ) {
    2136             $count = (int) $groups_template->group->total_member_count;
    2137         } else {
    2138             $count = 0;
    2139         }
    2140 
    2141         $count_string = sprintf( _n( '%s member', '%s members', $count, 'buddypress' ), bp_core_number_format( $count ) );
    2142 
    2143         /**
    2144          * Filters the "x members" count string for a group.
    2145          *
    2146          * @since 1.2.0
    2147          *
    2148          * @param string $count_string The "x members" count string for a group.
    2149          */
    2150         return apply_filters( 'bp_get_group_member_count', $count_string );
    2151     }
    2152 
    2153 /**
    2154  * Output the URL of the Forum page of the current group in the loop.
    2155  *
    2156  * @since 1.0.0
    2157  */
    2158 function bp_group_forum_permalink() {
    2159     echo bp_get_group_forum_permalink();
    2160 }
    2161     /**
    2162      * Generate the URL of the Forum page of a group.
    2163      *
    2164      * @since 1.0.0
    2165      *
    2166      * @param object|bool $group Optional. Group object.
    2167      *                           Default: current group in loop.
    2168      * @return string
    2169      */
    2170     function bp_get_group_forum_permalink( $group = false ) {
    2171         global $groups_template;
    2172 
    2173         if ( empty( $group ) ) {
    2174             $group =& $groups_template->group;
    2175         }
    2176 
    2177         /**
    2178          * Filters the URL of the Forum page of a group.
    2179          *
    2180          * @since 1.0.0
    2181          * @since 2.5.0 Added the `$group` parameter.
    2182          *
    2183          * @param string $value URL permalink for the Forum Page.
    2184          * @param object $group Group object.
    2185          */
    2186         return apply_filters( 'bp_get_group_forum_permalink', bp_get_group_permalink( $group ) . 'forum', $group );
    2187     }
    2188 
    2189 /**
    2190  * Output the topic count for a group forum.
    2191  *
    2192  * @since 1.2.0
    2193  *
    2194  * @param array|string $args See {@link bp_get_group_forum_topic_count()}.
    2195  */
    2196 function bp_group_forum_topic_count( $args = '' ) {
    2197     echo bp_get_group_forum_topic_count( $args );
    2198 }
    2199     /**
    2200      * Generate the topic count string for a group forum.
    2201      *
    2202      * @since 1.2.0
    2203      *
    2204      * @param array|string $args {
    2205      *     Array of arguments.
    2206      *     @type bool $showtext Optional. If true, result will be formatted as "x topics".
    2207      *                          If false, just a number will be returned.
    2208      *                          Default: false.
    2209      * }
    2210      * @return string|int
    2211      */
    2212     function bp_get_group_forum_topic_count( $args = '' ) {
    2213         global $groups_template;
    2214 
    2215         $defaults = array(
    2216             'showtext' => false
    2217         );
    2218 
    2219         $r = wp_parse_args( $args, $defaults );
    2220         extract( $r, EXTR_SKIP );
    2221 
    2222         if ( !$forum_id = groups_get_groupmeta( $groups_template->group->id, 'forum_id' ) ) {
    2223             return false;
    2224         }
    2225 
    2226         if ( !bp_is_active( 'forums' ) ) {
    2227             return false;
    2228         }
    2229 
    2230         if ( !$groups_template->group->forum_counts ) {
    2231             $groups_template->group->forum_counts = bp_forums_get_forum_topicpost_count( (int) $forum_id );
    2232         }
    2233 
    2234         if ( (bool) $showtext ) {
    2235             if ( 1 == (int) $groups_template->group->forum_counts[0]->topics ) {
    2236                 $total_topics = sprintf( __( '%d topic', 'buddypress' ), (int) $groups_template->group->forum_counts[0]->topics );
    2237             } else {
    2238                 $total_topics = sprintf( __( '%d topics', 'buddypress' ), (int) $groups_template->group->forum_counts[0]->topics );
    2239             }
    2240         } else {
    2241             $total_topics = (int) $groups_template->group->forum_counts[0]->topics;
    2242         }
    2243 
    2244         /**
    2245          * Filters the topic count string for a group forum.
    2246          *
    2247          * @since 1.2.0
    2248          *
    2249          * @param string $total_topics Total topic count string.
    2250          * @param bool   $showtext     Whether or not to return as formatted string.
    2251          */
    2252         return apply_filters( 'bp_get_group_forum_topic_count', $total_topics, (bool)$showtext );
    2253     }
    2254 
    2255 /**
    2256  * Output the post count for a group forum.
    2257  *
    2258  * @since 1.2.0
    2259  *
    2260  * @param array|string $args See {@link bp_get_group_forum_post_count()}.
    2261  */
    2262 function bp_group_forum_post_count( $args = '' ) {
    2263     echo bp_get_group_forum_post_count( $args );
    2264 }
    2265     /**
    2266      * Generate the post count string for a group forum.
    2267      *
    2268      * @since 1.2.0
    2269      *
    2270      * @param array|string $args {
    2271      *     Array of arguments.
    2272      *     @type bool $showtext Optional. If true, result will be formatted as "x posts".
    2273      *                          If false, just a number will be returned.
    2274      *                          Default: false.
    2275      * }
    2276      * @return string|int
    2277      */
    2278     function bp_get_group_forum_post_count( $args = '' ) {
    2279         global $groups_template;
    2280 
    2281         $defaults = array(
    2282             'showtext' => false
    2283         );
    2284 
    2285         $r = wp_parse_args( $args, $defaults );
    2286         extract( $r, EXTR_SKIP );
    2287 
    2288         if ( !$forum_id = groups_get_groupmeta( $groups_template->group->id, 'forum_id' ) ) {
    2289             return false;
    2290         }
    2291 
    2292         if ( !bp_is_active( 'forums' ) ) {
    2293             return false;
    2294         }
    2295 
    2296         if ( !$groups_template->group->forum_counts ) {
    2297             $groups_template->group->forum_counts = bp_forums_get_forum_topicpost_count( (int) $forum_id );
    2298         }
    2299 
    2300         if ( (bool) $showtext ) {
    2301             if ( 1 == (int) $groups_template->group->forum_counts[0]->posts ) {
    2302                 $total_posts = sprintf( __( '%d post', 'buddypress' ), (int) $groups_template->group->forum_counts[0]->posts );
    2303             } else {
    2304                 $total_posts = sprintf( __( '%d posts', 'buddypress' ), (int) $groups_template->group->forum_counts[0]->posts );
    2305             }
    2306         } else {
    2307             $total_posts = (int) $groups_template->group->forum_counts[0]->posts;
    2308         }
    2309 
    2310         /**
    2311          * Filters the post count string for a group forum.
    2312          *
    2313          * @since 1.2.0
    2314          *
    2315          * @param string $total_posts Total post count string.
    2316          * @param bool   $showtext    Whether or not to return as formatted string.
    2317          */
    2318         return apply_filters( 'bp_get_group_forum_post_count', $total_posts, (bool)$showtext );
    2319     }
    2320 
    2321 /**
    2322  * Determine whether forums are enabled for a group.
    2323  *
    2324  * @since 1.0.0
    2325  *
    2326  * @param object|bool $group Optional. Group object. Default: current group in loop.
    2327  * @return bool
    2328  */
    2329 function bp_group_is_forum_enabled( $group = false ) {
    2330     global $groups_template;
    2331 
    2332     if ( empty( $group ) ) {
    2333         $group =& $groups_template->group;
    2334     }
    2335 
    2336     if ( ! empty( $group->enable_forum ) ) {
    2337         return true;
    2338     }
    2339 
    2340     return false;
    2341 }
    2342 
    2343 /**
    2344  * Output the 'checked' attribute for the group forums settings UI.
    2345  *
    2346  * @since 1.0.0
    2347  *
    2348  * @param object|bool $group Optional. Group object. Default: current group in loop.
    2349  */
    2350 function bp_group_show_forum_setting( $group = false ) {
    2351     global $groups_template;
    2352 
    2353     if ( empty( $group ) ) {
    2354         $group =& $groups_template->group;
    2355     }
    2356 
    2357     if ( $group->enable_forum ) {
    2358         echo ' checked="checked"';
    2359     }
    2360 }
    2361 
    2362 /**
    2363  * Output the 'checked' attribute for a given status in the settings UI.
    2364  *
    2365  * @since 1.0.0
    2366  *
    2367  * @param string      $setting Group status. 'public', 'private', 'hidden'.
    2368  * @param object|bool $group   Optional. Group object. Default: current group in loop.
    2369  */
    2370 function bp_group_show_status_setting( $setting, $group = false ) {
    2371     global $groups_template;
    2372 
    2373     if ( empty( $group ) ) {
    2374         $group =& $groups_template->group;
    2375     }
    2376 
    2377     if ( $setting == $group->status ) {
    2378         echo ' checked="checked"';
    2379     }
    2380 }
    2381 
    2382 /**
    2383  * Output the 'checked' value, if needed, for a given invite_status on the group create/admin screens
    2384  *
    2385  * @since 1.5.0
    2386  *
    2387  * @param string      $setting The setting you want to check against ('members',
    2388  *                             'mods', or 'admins').
    2389  * @param object|bool $group   Optional. Group object. Default: current group in loop.
    2390  */
    2391 function bp_group_show_invite_status_setting( $setting, $group = false ) {
    2392     $group_id = isset( $group->id ) ? $group->id : false;
    2393 
    2394     $invite_status = bp_group_get_invite_status( $group_id );
    2395 
    2396     if ( $setting == $invite_status ) {
    2397         echo ' checked="checked"';
    2398     }
    2399 }
    2400 
    2401 /**
    2402  * Get the invite status of a group.
    2403  *
    2404  * 'invite_status' became part of BuddyPress in BP 1.5. In order to provide
    2405  * backward compatibility with earlier installations, groups without a status
    2406  * set will default to 'members', ie all members in a group can send
    2407  * invitations. Filter 'bp_group_invite_status_fallback' to change this
    2408  * fallback behavior.
    2409  *
    2410  * This function can be used either in or out of the loop.
    2411  *
    2412  * @since 1.5.0
    2413  *
    2414  * @param int|bool $group_id Optional. The ID of the group whose status you want to
    2415  *                           check. Default: the displayed group, or the current group
    2416  *                           in the loop.
    2417  * @return bool|string Returns false when no group can be found. Otherwise
    2418  *                     returns the group invite status, from among 'members',
    2419  *                     'mods', and 'admins'.
    2420  */
    2421 function bp_group_get_invite_status( $group_id = false ) {
    2422     global $groups_template;
    2423 
    2424     if ( !$group_id ) {
    2425         $bp = buddypress();
    2426 
    2427         if ( isset( $bp->groups->current_group->id ) ) {
    2428             // Default to the current group first.
    2429             $group_id = $bp->groups->current_group->id;
    2430         } elseif ( isset( $groups_template->group->id ) ) {
    2431             // Then see if we're in the loop.
    2432             $group_id = $groups_template->group->id;
    2433         } else {
    2434             return false;
    2435         }
    2436     }
    2437 
    2438     $invite_status = groups_get_groupmeta( $group_id, 'invite_status' );
    2439 
    2440     // Backward compatibility. When 'invite_status' is not set, fall back to a default value.
    2441     if ( !$invite_status ) {
    2442         $invite_status = apply_filters( 'bp_group_invite_status_fallback', 'members' );
    2443     }
    2444 
    2445     /**
    2446      * Filters the invite status of a group.
    2447      *
    2448      * Invite status in this case means who from the group can send invites.
    2449      *
    2450      * @since 1.5.0
    2451      *
    2452      * @param string $invite_status Membership level needed to send an invite.
    2453      * @param int    $group_id      ID of the group whose status is being checked.
    2454      */
    2455     return apply_filters( 'bp_group_get_invite_status', $invite_status, $group_id );
    2456 }
    2457 
    2458 /**
    2459  * Can a user send invitations in the specified group?
    2460  *
    2461  * @since 1.5.0
    2462  * @since 2.2.0 Added the $user_id parameter.
    2463  *
    2464  * @param int $group_id The group ID to check.
    2465  * @param int $user_id  The user ID to check.
    2466  * @return bool
    2467  */
    2468 function bp_groups_user_can_send_invites( $group_id = 0, $user_id = 0 ) {
    2469     $can_send_invites = false;
    2470     $invite_status    = false;
    2471 
    2472     // If $user_id isn't specified, we check against the logged-in user.
    2473     if ( ! $user_id ) {
    2474         $user_id = bp_loggedin_user_id();
    2475     }
    2476 
    2477     // If $group_id isn't specified, use existing one if available.
    2478     if ( ! $group_id ) {
    2479         $group_id = bp_get_current_group_id();
    2480     }
    2481 
    2482     if ( $user_id ) {
    2483         // Users with the 'bp_moderate' cap can always send invitations.
    2484         if ( user_can( $user_id, 'bp_moderate' ) ) {
    2485             $can_send_invites = true;
    2486         } else {
    2487             $invite_status = bp_group_get_invite_status( $group_id );
    2488 
    2489             switch ( $invite_status ) {
    2490                 case 'admins' :
    2491                     if ( groups_is_user_admin( $user_id, $group_id ) ) {
    2492                         $can_send_invites = true;
    2493                     }
    2494                     break;
    2495 
    2496                 case 'mods' :
    2497                     if ( groups_is_user_mod( $user_id, $group_id ) || groups_is_user_admin( $user_id, $group_id ) ) {
    2498                         $can_send_invites = true;
    2499                     }
    2500                     break;
    2501 
    2502                 case 'members' :
    2503                     if ( groups_is_user_member( $user_id, $group_id ) ) {
    2504                         $can_send_invites = true;
    2505                     }
    2506                     break;
    2507             }
    2508         }
    2509     }
    2510 
    2511     /**
    2512      * Filters whether a user can send invites in a group.
    2513      *
    2514      * @since 1.5.0
    2515      * @since 2.2.0 Added the $user_id parameter.
    2516      *
    2517      * @param bool $can_send_invites Whether the user can send invites
    2518      * @param int  $group_id         The group ID being checked
    2519      * @param bool $invite_status    The group's current invite status
    2520      * @param int  $user_id          The user ID being checked
    2521      */
    2522     return apply_filters( 'bp_groups_user_can_send_invites', $can_send_invites, $group_id, $invite_status, $user_id );
    2523 }
    2524 
    2525 /**
    2526  * Since BuddyPress 1.0, this generated the group settings admin/member screen.
    2527  * As of BuddyPress 1.5 (r4489), and because this function outputs HTML, it was moved into /bp-default/groups/single/admin.php.
    2528  *
    2529  * @deprecated 1.5
    2530  * @deprecated No longer used.
    2531  * @since 1.0.0
    2532  * @todo Remove in 1.4
    2533  *
    2534  * @param bool $admin_list
    2535  * @param bool $group
    2536  */
    2537 function bp_group_admin_memberlist( $admin_list = false, $group = false ) {
    2538     global $groups_template;
    2539 
    2540     _deprecated_function( __FUNCTION__, '1.5', 'No longer used. See /bp-default/groups/single/admin.php' );
    2541 
    2542     if ( empty( $group ) ) {
    2543         $group =& $groups_template->group;
    2544     }
    2545 
    2546 
    2547     if ( $admins = groups_get_group_admins( $group->id ) ) : ?>
    2548 
    2549         <ul id="admins-list" class="item-list<?php if ( !empty( $admin_list ) ) : ?> single-line<?php endif; ?>">
    2550 
    2551         <?php foreach ( (array) $admins as $admin ) { ?>
    2552 
    2553             <?php if ( !empty( $admin_list ) ) : ?>
    2554 
    2555             <li>
    2556 
    2557                 <?php echo bp_core_fetch_avatar( array( 'item_id' => $admin->user_id, 'type' => 'thumb', 'width' => 30, 'height' => 30, 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $admin->user_id ) ) ) ) ?>
    2558 
    2559                 <h5>
    2560 
    2561                     <?php echo bp_core_get_userlink( $admin->user_id ); ?>
    2562 
    2563                     <span class="small">
    2564                         <a class="button confirm admin-demote-to-member" href="<?php bp_group_member_demote_link($admin->user_id) ?>"><?php _e( 'Demote to Member', 'buddypress' ) ?></a>
    2565                     </span>
    2566                 </h5>
    2567             </li>
    2568 
    2569             <?php else : ?>
    2570 
    2571             <li>
    2572 
    2573                 <?php echo bp_core_fetch_avatar( array( 'item_id' => $admin->user_id, 'type' => 'thumb', 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $admin->user_id ) ) ) ) ?>
    2574 
    2575                 <h5><?php echo bp_core_get_userlink( $admin->user_id ) ?></h5>
    2576                 <span class="activity">
    2577                     <?php echo bp_core_get_last_activity( strtotime( $admin->date_modified ), __( 'joined %s', 'buddypress') ); ?>
    2578                 </span>
    2579 
    2580                 <?php if ( bp_is_active( 'friends' ) ) : ?>
    2581 
    2582                     <div class="action">
    2583 
    2584                         <?php bp_add_friend_button( $admin->user_id ); ?>
    2585 
    2586                     </div>
    2587 
    2588                 <?php endif; ?>
    2589 
    2590             </li>
    2591 
    2592             <?php endif;
    2593         } ?>
    2594 
    2595         </ul>
    2596 
    2597     <?php else : ?>
    2598 
    2599         <div id="message" class="info">
    2600             <p><?php _e( 'This group has no administrators', 'buddypress' ); ?></p>
    2601         </div>
    2602 
    2603     <?php endif;
    2604 }
    2605 
    2606 /**
    2607  * Generate the HTML for a list of group moderators.
    2608  *
    2609  * No longer used.
    2610  *
    2611  * @todo Deprecate.
    2612  *
    2613  * @param bool $admin_list
    2614  * @param bool $group
    2615  */
    2616 function bp_group_mod_memberlist( $admin_list = false, $group = false ) {
    2617     global $groups_template;
    2618 
    2619     if ( empty( $group ) ) {
    2620         $group =& $groups_template->group;
    2621     }
    2622 
    2623     if ( $group_mods = groups_get_group_mods( $group->id ) ) { ?>
    2624 
    2625         <ul id="mods-list" class="item-list<?php if ( $admin_list ) { ?> single-line<?php } ?>">
    2626 
    2627         <?php foreach ( (array) $group_mods as $mod ) { ?>
    2628 
    2629             <?php if ( !empty( $admin_list ) ) { ?>
    2630 
    2631             <li>
    2632 
    2633                 <?php echo bp_core_fetch_avatar( array( 'item_id' => $mod->user_id, 'type' => 'thumb', 'width' => 30, 'height' => 30, 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $mod->user_id ) ) ) ) ?>
    2634 
    2635                 <h5>
    2636                     <?php echo bp_core_get_userlink( $mod->user_id ); ?>
    2637 
    2638                     <span class="small">
    2639                         <a href="<?php bp_group_member_promote_admin_link( array( 'user_id' => $mod->user_id ) ) ?>" class="button confirm mod-promote-to-admin" title="<?php esc_attr_e( 'Promote to Admin', 'buddypress' ); ?>"><?php _e( 'Promote to Admin', 'buddypress' ); ?></a>
    2640                         <a class="button confirm mod-demote-to-member" href="<?php bp_group_member_demote_link($mod->user_id) ?>"><?php _e( 'Demote to Member', 'buddypress' ) ?></a>
    2641                     </span>
    2642                 </h5>
    2643             </li>
    2644 
    2645             <?php } else { ?>
    2646 
    2647             <li>
    2648 
    2649                 <?php echo bp_core_fetch_avatar( array( 'item_id' => $mod->user_id, 'type' => 'thumb', 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $mod->user_id ) ) ) ) ?>
    2650 
    2651                 <h5><?php echo bp_core_get_userlink( $mod->user_id ) ?></h5>
    2652 
    2653                 <span class="activity"><?php echo bp_core_get_last_activity( strtotime( $mod->date_modified ), __( 'joined %s', 'buddypress') ); ?></span>
    2654 
    2655                 <?php if ( bp_is_active( 'friends' ) ) : ?>
    2656 
    2657                     <div class="action">
    2658                         <?php bp_add_friend_button( $mod->user_id ) ?>
    2659                     </div>
    2660 
    2661                 <?php endif; ?>
    2662 
    2663             </li>
    2664 
    2665             <?php } ?>
    2666         <?php } ?>
    2667 
    2668         </ul>
    2669 
    2670     <?php } else { ?>
    2671 
    2672         <div id="message" class="info">
    2673             <p><?php _e( 'This group has no moderators', 'buddypress' ); ?></p>
    2674         </div>
    2675 
    2676     <?php }
    2677 }
    2678 
    2679 /**
    2680  * Determine whether a group has moderators.
    2681  *
    2682  * @since 1.0.0
    2683  *
    2684  * @param object|bool $group Optional. Group object. Default: current group in loop.
    2685  * @return array Info about group admins (user_id + date_modified).
    2686  */
    2687 function bp_group_has_moderators( $group = false ) {
    2688     global $groups_template;
    2689 
    2690     if ( empty( $group ) ) {
    2691         $group =& $groups_template->group;
    2692     }
    2693 
    2694     /**
    2695      * Filters whether a group has moderators.
    2696      *
    2697      * @since 1.0.0
    2698      * @since 2.5.0 Added the `$group` parameter.
    2699      *
    2700      * @param array  $value Array of user IDs who are a moderator of the provided group.
    2701      * @param object $group Group object.
    2702      */
    2703     return apply_filters( 'bp_group_has_moderators', groups_get_group_mods( $group->id ), $group );
    2704 }
    2705 
    2706 /**
    2707  * Output a URL for promoting a user to moderator.
    2708  *
    2709  * @since 1.1.0
    2710  *
    2711  * @param array|string $args See {@link bp_get_group_member_promote_mod_link()}.
    2712  */
    2713 function bp_group_member_promote_mod_link( $args = '' ) {
    2714     echo bp_get_group_member_promote_mod_link( $args );
    2715 }
    2716     /**
    2717      * Generate a URL for promoting a user to moderator.
    2718      *
    2719      * @since 1.1.0
    2720      *
    2721      * @param array|string $args {
    2722      *     @type int    $user_id ID of the member to promote. Default:
    2723      *                           current member in a group member loop.
    2724      *     @type object $group   Group object. Default: current group.
    2725      * }
    2726      * @return string
    2727      */
    2728     function bp_get_group_member_promote_mod_link( $args = '' ) {
    2729         global $members_template, $groups_template;
    2730 
    2731         $defaults = array(
    2732             'user_id' => $members_template->member->user_id,
    2733             'group'   => &$groups_template->group
    2734         );
    2735 
    2736         $r = wp_parse_args( $args, $defaults );
    2737         extract( $r, EXTR_SKIP );
    2738 
    2739         /**
    2740          * Filters a URL for promoting a user to moderator.
    2741          *
    2742          * @since 1.1.0
    2743          *
    2744          * @param string $value URL to use for promoting a user to moderator.
    2745          */
    2746         return apply_filters( 'bp_get_group_member_promote_mod_link', wp_nonce_url( bp_get_group_permalink( $group ) . 'admin/manage-members/promote/mod/' . $user_id, 'groups_promote_member' ) );
    2747     }
    2748 
    2749 /**
    2750  * Output a URL for promoting a user to admin.
    2751  *
    2752  * @since 1.1.0
    2753  *
    2754  * @param array|string $args See {@link bp_get_group_member_promote_admin_link()}.
    2755  */
    2756 function bp_group_member_promote_admin_link( $args = '' ) {
    2757     echo bp_get_group_member_promote_admin_link( $args );
    2758 }
    2759     /**
    2760      * Generate a URL for promoting a user to admin.
    2761      *
    2762      * @since 1.1.0
    2763      *
    2764      * @param array|string $args {
    2765      *     @type int    $user_id ID of the member to promote. Default:
    2766      *                           current member in a group member loop.
    2767      *     @type object $group   Group object. Default: current group.
    2768      * }
    2769      * @return string
    2770      */
    2771     function bp_get_group_member_promote_admin_link( $args = '' ) {
    2772         global $members_template, $groups_template;
    2773 
    2774         $defaults = array(
    2775             'user_id' => !empty( $members_template->member->user_id ) ? $members_template->member->user_id : false,
    2776             'group'   => &$groups_template->group
    2777         );
    2778 
    2779         $r = wp_parse_args( $args, $defaults );
    2780         extract( $r, EXTR_SKIP );
    2781 
    2782         /**
    2783          * Filters a URL for promoting a user to admin.
    2784          *
    2785          * @since 1.1.0
    2786          *
    2787          * @param string $value URL to use for promoting a user to admin.
    2788          */
    2789         return apply_filters( 'bp_get_group_member_promote_admin_link', wp_nonce_url( bp_get_group_permalink( $group ) . 'admin/manage-members/promote/admin/' . $user_id, 'groups_promote_member' ) );
    2790     }
    2791 
    2792 /**
    2793  * Output a URL for demoting a user to member.
    2794  *
    2795  * @since 1.0.0
    2796  *
    2797  * @param int $user_id ID of the member to demote. Default: current member in
    2798  *                     a member loop.
    2799  */
    2800 function bp_group_member_demote_link( $user_id = 0 ) {
    2801     global $members_template;
    2802 
    2803     if ( !$user_id ) {
    2804         $user_id = $members_template->member->user_id;
    2805     }
    2806 
    2807     echo bp_get_group_member_demote_link( $user_id );
    2808 }
    2809     /**
    2810      * Generate a URL for demoting a user to member.
    2811      *
    2812      * @since 1.0.0
    2813      *
    2814      * @param int         $user_id ID of the member to demote. Default: current
    2815      *                             member in a member loop.
    2816      * @param object|bool $group   Optional. Group object. Default: current group.
    2817      * @return string
    2818      */
    2819     function bp_get_group_member_demote_link( $user_id = 0, $group = false ) {
    2820         global $members_template, $groups_template;
    2821 
    2822         if ( empty( $group ) ) {
    2823             $group =& $groups_template->group;
    2824         }
    2825 
    2826         if ( !$user_id ) {
    2827             $user_id = $members_template->member->user_id;
    2828         }
    2829 
    2830         /**
    2831          * Filters a URL for demoting a user to member.
    2832          *
    2833          * @since 1.0.0
    2834          * @since 2.5.0 Added the `$group` parameter.
    2835          *
    2836          * @param string $value URL to use for demoting a user to member.
    2837          * @param object $group Group object.
    2838          */
    2839         return apply_filters( 'bp_get_group_member_demote_link', wp_nonce_url( bp_get_group_permalink( $group ) . 'admin/manage-members/demote/' . $user_id, 'groups_demote_member' ), $group );
    2840     }
    2841 
    2842 /**
    2843  * Output a URL for banning a member from a group.
    2844  *
    2845  * @since 1.0.0
    2846  *
    2847  * @param int $user_id ID of the member to ban.
    2848  *                     Default: current member in a member loop.
    2849  */
    2850 function bp_group_member_ban_link( $user_id = 0 ) {
    2851     global $members_template;
    2852 
    2853     if ( !$user_id ) {
    2854         $user_id = $members_template->member->user_id;
    2855     }
    2856 
    2857     echo bp_get_group_member_ban_link( $user_id );
    2858 }
    2859     /**
    2860      * Generate a URL for banning a member from a group.
    2861      *
    2862      * @since 1.0.0
    2863      *
    2864      * @param int         $user_id ID of the member to ban.
    2865      *                             Default: current member in a member loop.
    2866      * @param object|bool $group   Optional. Group object. Default: current group.
    2867      * @return string
    2868      */
    2869     function bp_get_group_member_ban_link( $user_id = 0, $group = false ) {
    2870         global $groups_template;
    2871 
    2872         if ( empty( $group ) ) {
    2873             $group =& $groups_template->group;
    2874         }
    2875 
    2876         /**
    2877          * Filters a URL for banning a member from a group.
    2878          *
    2879          * @since 1.0.0
    2880          *
    2881          * @param string $value URL to use for banning a member.
    2882          */
    2883         return apply_filters( 'bp_get_group_member_ban_link', wp_nonce_url( bp_get_group_permalink( $group ) . 'admin/manage-members/ban/' . $user_id, 'groups_ban_member' ) );
    2884     }
    2885 
    2886 /**
    2887  * Output a URL for unbanning a member from a group.
    2888  *
    2889  * @since 1.0.0
    2890  *
    2891  * @param int $user_id ID of the member to unban.
    2892  *                     Default: current member in a member loop.
    2893  */
    2894 function bp_group_member_unban_link( $user_id = 0 ) {
    2895     global $members_template;
    2896 
    2897     if ( !$user_id ) {
    2898         $user_id = $members_template->member->user_id;
    2899     }
    2900 
    2901     echo bp_get_group_member_unban_link( $user_id );
    2902 }
    2903     /**
    2904      * Generate a URL for unbanning a member from a group.
    2905      *
    2906      * @since 1.0.0
    2907      *
    2908      * @param int         $user_id ID of the member to unban.
    2909      *                             Default: current member in a member loop.
    2910      * @param object|bool $group   Optional. Group object. Default: current group.
    2911      * @return string
    2912      */
    2913     function bp_get_group_member_unban_link( $user_id = 0, $group = false ) {
    2914         global $members_template, $groups_template;
    2915 
    2916         if ( !$user_id ) {
    2917             $user_id = $members_template->member->user_id;
    2918         }
    2919 
    2920         if ( empty( $group ) ) {
    2921             $group =& $groups_template->group;
    2922         }
    2923 
    2924         /**
    2925          * Filters a URL for unbanning a member from a group.
    2926          *
    2927          * @since 1.0.0
    2928          *
    2929          * @param string $value URL to use for unbanning a member.
    2930          */
    2931         return apply_filters( 'bp_get_group_member_unban_link', wp_nonce_url( bp_get_group_permalink( $group ) . 'admin/manage-members/unban/' . $user_id, 'groups_unban_member' ) );
    2932     }
    2933 
    2934 /**
    2935  * Output a URL for removing a member from a group.
    2936  *
    2937  * @since 1.2.6
    2938  *
    2939  * @param int $user_id ID of the member to remove.
    2940  *                     Default: current member in a member loop.
    2941  */
    2942 function bp_group_member_remove_link( $user_id = 0 ) {
    2943     global $members_template;
    2944 
    2945     if ( !$user_id ) {
    2946         $user_id = $members_template->member->user_id;
    2947     }
    2948 
    2949     echo bp_get_group_member_remove_link( $user_id );
    2950 }
    2951     /**
    2952      * Generate a URL for removing a member from a group.
    2953      *
    2954      * @since 1.2.6
    2955      *
    2956      * @param int         $user_id ID of the member to remove.
    2957      *                             Default: current member in a member loop.
    2958      * @param object|bool $group   Optional. Group object. Default: current group.
    2959      * @return string
    2960      */
    2961     function bp_get_group_member_remove_link( $user_id = 0, $group = false ) {
    2962         global $groups_template;
    2963 
    2964         if ( empty( $group ) ) {
    2965             $group =& $groups_template->group;
    2966         }
    2967 
    2968         /**
    2969          * Filters a URL for removing a member from a group.
    2970          *
    2971          * @since 1.2.6
    2972          * @since 2.5.0 Added the `$group` parameter.
    2973          *
    2974          * @param string $value URL to use for removing a member.
    2975          * @param object $group Group object.
    2976          */
    2977         return apply_filters( 'bp_get_group_member_remove_link', wp_nonce_url( bp_get_group_permalink( $group ) . 'admin/manage-members/remove/' . $user_id, 'groups_remove_member' ), $group );
    2978     }
    2979 
    2980 /**
    2981  * HTML admin subnav items for group pages.
    2982  *
    2983  * @since 1.0.0
    2984  *
    2985  * @param object|bool $group Optional. Group object.
    2986  *                           Default: current group in the loop.
    2987  */
    2988 function bp_group_admin_tabs( $group = false ) {
    2989     global $groups_template;
    2990 
    2991     if ( empty( $group ) ) {
    2992         $group = ( $groups_template->group ) ? $groups_template->group : groups_get_current_group();
    2993     }
    2994 
    2995     $css_id = 'manage-members';
    2996 
    2997     if ( 'private' == $group->status ) {
    2998         $css_id = 'membership-requests';
    2999     }
    3000 
    3001     add_filter( "bp_get_options_nav_{$css_id}", 'bp_group_admin_tabs_backcompat', 10, 3 );
    3002 
    3003     bp_get_options_nav( $group->slug . '_manage' );
    3004 
    3005     remove_filter( "bp_get_options_nav_{$css_id}", 'bp_group_admin_tabs_backcompat', 10, 3 );
    3006 }
    3007 
    3008 /**
    3009  * BackCompat for plugins/themes directly hooking groups_admin_tabs
    3010  * without using the Groups Extension API.
    3011  *
    3012  * @since 2.2.0
    3013  *
    3014  * @param  string $subnav_output Subnav item output.
    3015  * @param  string $subnav_item   subnav item params.
    3016  * @param  string $selected_item Surrent selected tab.
    3017  * @return string HTML output
    3018  */
    3019 function bp_group_admin_tabs_backcompat( $subnav_output = '', $subnav_item = '', $selected_item = '' ) {
    3020     if ( ! has_action( 'groups_admin_tabs' ) ) {
    3021         return $subnav_output;
    3022     }
    3023 
    3024     $group = groups_get_current_group();
    3025 
    3026     ob_start();
    3027 
    3028     do_action( 'groups_admin_tabs', $selected_item, $group->slug );
    3029 
    3030     $admin_tabs_backcompat = trim( ob_get_contents() );
    3031     ob_end_clean();
    3032 
    3033     if ( ! empty( $admin_tabs_backcompat ) ) {
    3034         _doing_it_wrong( "do_action( 'groups_admin_tabs' )", __( 'This action should not be used directly. Please use the BuddyPress Group Extension API to generate Manage tabs.', 'buddypress' ), '2.2.0' );
    3035         $subnav_output .= $admin_tabs_backcompat;
    3036     }
    3037 
    3038     return $subnav_output;
    3039 }
    3040 
    3041 /**
    3042  * Output the group count for the displayed user.
    3043  *
    3044  * @since 1.1.0
    3045  */
    3046 function bp_group_total_for_member() {
    3047     echo bp_get_group_total_for_member();
    3048 }
    3049     /**
    3050      * Get the group count for the displayed user.
    3051      *
    3052      * @since 1.1.0
    3053      *
    3054      * @return string
    3055      */
    3056     function bp_get_group_total_for_member() {
    3057 
    3058         /**
    3059          * FIlters the group count for a displayed user.
    3060          *
    3061          * @since 1.1.0
    3062          *
    3063          * @param int $value Total group count for a displayed user.
    3064          */
    3065         return apply_filters( 'bp_get_group_total_for_member', BP_Groups_Member::total_group_count() );
    3066     }
    3067 
    3068 /**
    3069  * Output the 'action' attribute for a group form.
    3070  *
    3071  * @since 1.0.0
    3072  *
    3073  * @param string $page Page slug.
    3074  */
    3075 function bp_group_form_action( $page ) {
    3076     echo bp_get_group_form_action( $page );
    3077 }
    3078     /**
    3079      * Generate the 'action' attribute for a group form.
    3080      *
    3081      * @since 1.0.0