Skip to:
Content

BuddyPress.org

Ticket #6026: 6026.03.patch

File 6026.03.patch, 203.8 KB (added by imath, 9 years ago)
  • src/bp-activity/bp-activity-loader.php

    diff --git src/bp-activity/bp-activity-loader.php src/bp-activity/bp-activity-loader.php
    index c6b169d..6ec6e49 100644
    class BP_Activity_Component extends BP_Component { 
    226226                        );
    227227                }
    228228
     229                // Additional menu if blogs single item is active
     230                if ( bp_is_active( 'blogs', 'blog' ) ) {
     231                        $sub_nav[] = array(
     232                                'name'            => _x( 'Sites', 'Profile activity screen sub nav', 'buddypress' ),
     233                                'slug'            => bp_get_blogs_slug(),
     234                                'parent_url'      => $activity_link,
     235                                'parent_slug'     => $this->slug,
     236                                'screen_function' => 'bp_activity_screen_blogs',
     237                                'position'        => 60,
     238                                'item_css_id'     => 'activity-blogs'
     239                        );
     240                }
     241
    229242                parent::setup_nav( $main_nav, $sub_nav );
    230243        }
    231244
    class BP_Activity_Component extends BP_Component { 
    321334                                        'href'   => trailingslashit( $activity_link . bp_get_groups_slug() )
    322335                                );
    323336                        }
     337
     338                        // Blogs single item ?
     339                        if ( bp_is_active( 'blogs', 'blog' ) ) {
     340                                $wp_admin_nav[] = array(
     341                                        'parent' => 'my-account-' . $this->id,
     342                                        'id'     => 'my-account-' . $this->id . '-blogs',
     343                                        'title'  => _x( 'Sites', 'My Account Activity sub nav', 'buddypress' ),
     344                                        'href'   => trailingslashit( $activity_link . bp_get_blogs_slug() )
     345                                );
     346                        }
    324347                }
    325348
    326349                parent::setup_admin_bar( $wp_admin_nav );
  • src/bp-activity/bp-activity-screens.php

    diff --git src/bp-activity/bp-activity-screens.php src/bp-activity/bp-activity-screens.php
    index 8ac5f3a..cc84ef4 100644
    function bp_activity_screen_groups() { 
    148148        bp_core_load_template( apply_filters( 'bp_activity_template_groups_activity', 'members/single/home' ) );
    149149}
    150150
     151 /**
     152 * Load the 'My Blogs' activity page.
     153 *
     154 * @since BuddyPress (2.4.0)
     155 */
     156function bp_activity_screen_blogs() {
     157        if ( ! bp_is_active( 'blogs', 'blog' ) ) {
     158                return false;
     159        }
     160
     161        bp_update_is_item_admin( bp_current_user_can( 'bp_moderate' ), 'activity' );
     162
     163        /**
     164         * Fires right before the loading of the "My Groups" screen template file.
     165         *
     166         * @since BuddyPress (2.4.0)
     167         */
     168        do_action( 'bp_activity_screen_blogs' );
     169
     170        /**
     171         * Filters the template to load for the "My Blogs" screen.
     172         *
     173         * @since BuddyPress (2.4.0)
     174         *
     175         * @param string $template Path to the activity template to load.
     176         */
     177        bp_core_load_template( apply_filters( 'bp_activity_template_blogs_activity', 'members/single/home' ) );
     178}
     179
    151180/**
    152181 * Load the 'Favorites' activity page.
    153182 *
  • src/bp-activity/bp-activity-template.php

    diff --git src/bp-activity/bp-activity-template.php src/bp-activity/bp-activity-template.php
    index e73a259..6332db5 100644
    function bp_has_activities( $args = '' ) { 
    626626                $object      = $bp->groups->id;
    627627                $primary_id  = bp_get_current_group_id();
    628628                $show_hidden = (bool) ( groups_is_user_member( bp_loggedin_user_id(), $primary_id ) || bp_current_user_can( 'bp_moderate' ) );
     629        } elseif ( bp_is_blog() ) {
     630                $object      = $bp->blogs->id;
     631                $primary_id  = bp_blogs_blog_get_current_blog_id();
     632                $show_hidden = false;
    629633        } else {
    630634                $object      = false;
    631635                $primary_id  = false;
    function bp_activity_show_filters( $context = '' ) { 
    44624466                        if ( bp_is_user() ) {
    44634467                                if ( bp_is_active( 'groups' ) && bp_is_current_action( bp_get_groups_slug() ) ) {
    44644468                                        $context = 'member_groups';
     4469                                } elseif ( bp_is_active( 'blogs', 'blog' ) && bp_is_current_action( bp_get_blogs_slug() ) ) {
     4470                                        $context = 'member_blogs';
    44654471                                } else {
    44664472                                        $context = 'member';
    44674473                                }
  • src/bp-blogs/bp-blogs-activity.php

    diff --git src/bp-blogs/bp-blogs-activity.php src/bp-blogs/bp-blogs-activity.php
    index c29e56b..5fff910 100644
    function bp_blogs_register_activity_actions() { 
    4545                        __( 'New post comment posted', 'buddypress' ),
    4646                        'bp_blogs_format_activity_action_new_blog_comment',
    4747                        __( 'Comments', 'buddypress' ),
    48                         array( 'activity', 'member' ),
     48                        array( 'activity', 'member', 'blog', 'member_blogs' ),
    4949                        10
    5050                );
    5151        }
  • src/bp-blogs/bp-blogs-adminbar.php

    diff --git src/bp-blogs/bp-blogs-adminbar.php src/bp-blogs/bp-blogs-adminbar.php
    index e69de29..9f54ce1 100644
     
     1<?php
     2
     3/**
     4 * BuddyPress Blogs Toolbar.
     5 *
     6 * Handles the blogs functions related to the WordPress Toolbar.
     7 *
     8 * @package BuddyPress
     9 * @subpackage Blogs
     10 */
     11
     12// Exit if accessed directly
     13defined( 'ABSPATH' ) || exit;
     14
     15/**
     16 * Add the Blog Admin top-level menu when viewing blog pages.
     17 *
     18 * @since BuddyPress (2.4.0)
     19 *
     20 * @return false|null False if not on a blog page, or if user does not have
     21 *                    access to blog admin options.
     22 */
     23function bp_blogs_blog_admin_menu() {
     24        global $wp_admin_bar;
     25        $bp = buddypress();
     26
     27        // Only show if viewing a group
     28        if ( ! bp_is_blog() || bp_is_create_blog() ) {
     29                return false;
     30        }
     31
     32        // Bail if nav is not set
     33        if ( ! is_a( $bp->blogs->nav, 'BP_Single_Item_Navigation' ) ) {
     34                return false;
     35        }
     36
     37        // Only show this menu to blog admins and super admins
     38        if ( ! bp_current_user_can( 'bp_moderate' ) && ! bp_is_item_admin() ) {
     39                return false;
     40        }
     41
     42        // Unique ID for the 'Edit Blog' menu
     43        $blog_manage_menu_id = 'blog-admin';
     44        $blog_manage_link    = trailingslashit( bp_blogs_blog_get_view_details_link() . 'manage' );
     45
     46        // Add the top-level Group Admin button
     47        $wp_admin_bar->add_menu( array(
     48                'id'    => $blog_manage_menu_id,
     49                'title' => __( 'Edit Blog', 'buddypress' ),
     50                'href'  => $blog_manage_link,
     51        ) );
     52
     53        // Get the Manage sub nav
     54        $manage_sub_nav = $bp->blogs->nav->get_sub_nav_by_parent_slug( 'manage' );
     55
     56        // Check if current blog has Manage tabs
     57        if ( empty( $manage_sub_nav ) ) {
     58                return;
     59        }
     60
     61        // Build the Group Admin menus
     62        foreach ( $manage_sub_nav as $menu ) {
     63                /**
     64                 * Should we add the current manage link in the Blog's "Edit" Admin Bar menu ?
     65                 */
     66                if ( $menu['show_in_admin_bar'] ) {
     67                        $title = sprintf( _x( 'Edit Blog %s', 'Group WP Admin Bar manage links', 'buddypress' ), $menu['name'] );
     68
     69                        $wp_admin_bar->add_menu( array(
     70                                'parent' => $blog_manage_menu_id,
     71                                'id'     => $menu['slug'],
     72                                'title'  => $title,
     73                                'href'   => trailingslashit( $blog_manage_link . $menu['slug'] ),
     74                        ) );
     75                }
     76        }
     77
     78        // Finally add a link to the WP Administration
     79        $wp_admin_bar->add_menu( array(
     80                'parent' => $blog_manage_menu_id,
     81                'id'     => 'wp-dashboard',
     82                'title'  => __( 'Dashboard', 'buddypress' ),
     83                'href'   => get_admin_url( bp_blogs_blog_get_current_blog_id() ),
     84        ) );
     85}
     86add_action( 'admin_bar_menu', 'bp_blogs_blog_admin_menu', 99 );
     87
     88/**
     89 * Remove rogue WP core Edit menu when viewing a single blog.
     90 *
     91 * @since BuddyPress (2.4.0)
     92 */
     93function bp_blogs_blog_remove_edit_page_menu() {
     94        if ( bp_is_blog() ) {
     95                remove_action( 'admin_bar_menu', 'wp_admin_bar_edit_menu', 80 );
     96        }
     97}
     98add_action( 'admin_bar_init', 'bp_blogs_blog_remove_edit_page_menu', 200 );
  • src/bp-blogs/bp-blogs-blog.php

    diff --git src/bp-blogs/bp-blogs-blog.php src/bp-blogs/bp-blogs-blog.php
    index e69de29..f3d8ae3 100644
     
     1<?php
     2
     3/**
     4 * BuddyPress Blogs Blog (single item) feature.
     5 *
     6 * @package BuddyPress
     7 * @subpackage BlogsBlog
     8 */
     9
     10/** Actions *******************************************************************/
     11
     12/**
     13 * Check if the user needs to set an avatar for his just registered blog.
     14 *
     15 * @since BuddyPress (2.4.0)
     16 */
     17function bp_blogs_blog_maybe_redirect_to_single_blog() {
     18        if ( ! is_multisite() || ! is_user_logged_in() || ! bp_blogs_blog_is_avatar_uploads_enabled() ) {
     19                return;
     20        }
     21
     22        $transient_key = sprintf( '_bp_activation_%d_redirect', bp_loggedin_user_id() );
     23        $blog_id = get_transient( $transient_key );
     24
     25        if ( empty( $blog_id ) ) {
     26                return;
     27        }
     28
     29        // Delete the redirect transient
     30        delete_transient( $transient_key );
     31
     32        $single_blog = bp_blogs_blog_get_blog( array( 'blog_id' => $blog_id ) );
     33
     34        if ( empty( $single_blog->slug ) ) {
     35                return;
     36        }
     37
     38        $redirect = trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . '/' . $single_blog->slug . '/manage/edit-logo' );
     39
     40        bp_core_add_message( __( 'Welcome to the profile area of your new site, please consider adding a site logo for your site', 'buddypress' ) );
     41        bp_core_redirect( esc_url( $redirect ) );
     42}
     43add_action( 'bp_blogs_setup_nav', 'bp_blogs_blog_maybe_redirect_to_single_blog' );
     44
     45/**
     46 * Make sure Signups are not forced to subscribe to root blog
     47 *
     48 * When a user is created, it first has a subscriber role, WordPress
     49 * is then removing this role by deleting its capabilities. Unfortunately
     50 * there's no hook before wp_create_user() in the wpmu_create_user() function
     51 * so we need to remove the subscriptions as soon as we can.
     52 *
     53 * @since BuddyPress (2.4.0)
     54 *
     55 * @param  int $user_id the newly created ID of the user
     56 */
     57function bp_blogs_blog_remove_signup_subscription( $user_id = 0 ) {
     58
     59        // Delete the subscription
     60        BP_Blogs_Blog::delete_blog_for_user( bp_get_root_blog_id(), $user_id );
     61}
     62add_action( 'wpmu_new_user', 'bp_blogs_blog_remove_signup_subscription', 10, 1 );
     63
     64/** Activity ******************************************************************/
     65
     66/**
     67 * Register activity actions for the blog feature.
     68 *
     69 * @since BuddyPress (2.4.0)
     70 */
     71function bp_blogs_blog_register_subscription_activity_action() {
     72        /**
     73         * Only add subscription actions if subscription are enabled
     74         * for current blog, or when viewing the blogs activities on
     75         * a user's profile or on the activity directory
     76         */
     77        if ( bp_blogs_blog_current_blog_can_subscribe() || bp_is_user() || bp_is_activity_directory() ) {
     78                bp_activity_set_action(
     79                        buddypress()->blogs->id,
     80                        'site_subscription',
     81                        __( 'New site subscription', 'buddypress' ),
     82                        'bp_blogs_blog_format_activity_action_new_site_subscription',
     83                        __( 'Site Subscriptions', 'buddypress' ),
     84                        array( 'activity', 'member', 'blog', 'member_blogs' ),
     85                        20
     86                );
     87        }
     88}
     89add_action( 'bp_blogs_register_activity_actions', 'bp_blogs_blog_register_subscription_activity_action' );
     90
     91 /**
     92 * Activity action callback for new site subscriptions
     93 *
     94 * @since BuddyPress (2.4.0)
     95 *
     96 * @param  string  $action      the content of the action
     97 * @param  BP_Activity_Activity the activity object
     98 * @return string  $action      the content of the action
     99 */
     100function bp_blogs_blog_format_activity_action_new_site_subscription( $action = '', $activity = null ) {
     101        if ( empty( $activity->item_id ) ) {
     102                return $action;
     103        }
     104
     105        $user_link         = bp_core_get_userlink( $activity->user_id );
     106        $blog_name         = bp_blogs_get_blogmeta( $activity->item_id, 'name' );
     107        $blog_url          = bp_blogs_get_blogmeta( $activity->item_id, 'url' );
     108        $root_domain       = trailingslashit( bp_get_root_domain() );
     109
     110        if ( (int) $activity->item_id !== (int) get_current_site()->id ) {
     111                $view_details_link = trailingslashit( $root_domain . bp_get_blogs_root_slug() . str_replace( $root_domain, '/', $blog_url ) );
     112        } else {
     113                $view_details_link = trailingslashit( $root_domain . bp_get_blogs_root_slug() . '/' . bp_blogs_blog_get_site_slug() );
     114        }
     115
     116        $action = sprintf(
     117                __( '%1$s subscribed to the site %2$s', 'buddypress' ),
     118                $user_link,
     119                '<a href="' . esc_url( $view_details_link ) . '">' . esc_html( $blog_name ) . '</a>'
     120        );
     121
     122        return apply_filters( 'bp_blogs_blog_format_activity_action_new_site_subscription', $action, $activity );
     123}
     124
     125/**
     126 * Set up activity arguments to use for the 'blogs' scope.
     127 *
     128 * @since BuddyPress (2.4.0)
     129 *
     130 * @param array $retval Empty array by default
     131 * @param array $filter Current activity arguments
     132 * @return array
     133 */
     134function bp_blogs_blog_activity_scope( $retval = array(), $filter = array() ) {
     135
     136        // Determine the user_id
     137        if ( ! empty( $filter['user_id'] ) ) {
     138                $user_id = $filter['user_id'];
     139        } else {
     140                $user_id = bp_displayed_user_id()
     141                        ? bp_displayed_user_id()
     142                        : bp_loggedin_user_id();
     143        }
     144
     145        // Determine blogs of user
     146        $blogs = bp_blogs_get_blogs_for_user( $user_id );
     147        if ( empty( $blogs['blogs'] ) ) {
     148                $blogs = array( 'blogs' => 0 );
     149        } else {
     150                $blogs['blogs'] = array_keys( $blogs['blogs'] );
     151        }
     152
     153        // Should we show all items regardless of sitewide visibility?
     154        $show_hidden = array();
     155        if ( ! empty( $user_id ) && ( $user_id !== bp_loggedin_user_id() ) ) {
     156                $show_hidden = array(
     157                        'column' => 'hide_sitewide',
     158                        'value'  => 0
     159                );
     160        }
     161
     162        $retval = array(
     163                'relation' => 'AND',
     164                array(
     165                        'relation' => 'AND',
     166                        array(
     167                                'column' => 'component',
     168                                'value'  => buddypress()->blogs->id
     169                        ),
     170                        array(
     171                                'column'  => 'item_id',
     172                                'compare' => 'IN',
     173                                'value'   => (array) $blogs['blogs']
     174                        ),
     175                ),
     176                $show_hidden,
     177
     178                // overrides
     179                'override' => array(
     180                        'filter'      => array( 'user_id' => 0 ),
     181                        'show_hidden' => true
     182                ),
     183        );
     184
     185        return $retval;
     186}
     187add_filter( 'bp_activity_set_blogs_scope_args', 'bp_blogs_blog_activity_scope', 10, 2 );
     188
     189/** Fonctions *****************************************************************/
     190
     191/**
     192 * Get the root site's slug
     193 *
     194 * @since  BuddyPress (2.4.0)
     195 *
     196 * @param string $default The default slug for the root site
     197 */
     198function bp_blogs_blog_get_site_slug( $default = 'root' ) {
     199        /**
     200         * Filters the root site's slug.
     201         *
     202         * @since BuddyPress (2.4.0)
     203         *
     204         * @param string $default the default slug (root).
     205         */
     206        return sanitize_title( apply_filters( 'bp_blogs_blog_get_site_slug', $default ) );
     207}
     208
     209/**
     210 * Get a list of member ids for a given blog
     211 *
     212 * @since  BuddyPress (2.4.0)
     213 *
     214 * @param  array  $args {
     215 *  $blog_id    int       the blog ID to get the members for
     216 *  $user_level int|false false to get all members, 1 to restrict to contributors, 0 to only get subscribers
     217 * }
     218 * @return array      the list of member ids and extra data for the blog
     219 */
     220function bp_blogs_blog_get_users_for_blog( $args = array() ) {
     221        $r = wp_parse_args( $args, array(
     222                'blog_id'    => 0,
     223                'user_level' => false,
     224        ) );
     225
     226        if ( empty( $r['blog_id'] ) ) {
     227                return false;
     228        }
     229
     230        // Get the current blog to check if we already have the needed users
     231        $current_blog = bp_blogs_blog_get_current_blog();
     232
     233        if ( ! empty( $current_blog->members ) && (int) $r['blog_id'] === (int) $current_blog->blog_id && false === $r['user_level'] ) {
     234                return $current_blog->members;
     235        } else {
     236                return BP_Blogs_Blog::get_users_for_blog( $r['blog_id'], $r['user_level'] );
     237        }
     238}
     239
     240/**
     241 * Get the total number of blogs for a specific user depending on his user level.
     242 *
     243 * @since  BuddyPress (2.4.0)
     244 *
     245 * @param  integer $user_id        the user id to get the number of blogs for
     246 * @param  int     $is_contributor 1 to get the blogs count for the blogs he contributes to
     247 *                                 0 to get the blogs count of the blogs he subscribed to
     248 * @return int                     the blogs count
     249 */
     250function bp_blogs_total_blogs_for_user_level( $user_id = 0, $is_contributor = 0 ) {
     251        if ( empty( $user_id ) ) {
     252                if ( bp_is_user() ) {
     253                        $user_id = bp_displayed_user_id();
     254                } else {
     255                        $user_id = bp_loggedin_user_id();
     256                }
     257        }
     258
     259        // no user ID or user level ? do not attempt to look at cache
     260        if ( empty( $user_id ) || false === $is_contributor ) {
     261                return 0;
     262        }
     263
     264        $level = 'subscriber';
     265        if ( 1 === (int) $is_contributor ) {
     266                $level = 'contributor';
     267        }
     268
     269        $count = wp_cache_get( 'bp_total_blogs_for_' . $level . '_' . $user_id, 'bp' );
     270        if ( false === $count ) {
     271                $count = BP_Blogs_Blog::total_blog_count_for_user( $user_id, $is_contributor );
     272                wp_cache_set( 'bp_total_blogs_for_' . $level . '_' . $user_id, $count, 'bp' );
     273        }
     274
     275        return $count;
     276}
     277
     278/**
     279 * Fetch a single blog object.
     280 *
     281 * @since  BuddyPress (2.4.0)
     282 *
     283 * @param array $args {
     284 *      Array of arguments.
     285 *      @type int $blog_id ID of the blog.
     286 *      @type bool $populate_extras Whether to fetch extra information about the blog.
     287 *                 Default: True.
     288 * }
     289 * @return BP_Blogs_Blog $blog The blog object.
     290 */
     291function bp_blogs_blog_get_blog( $args = '' ) {
     292        // Parse query arguments
     293        $r = bp_parse_args( $args, array(
     294                'blog_id'         => 0,
     295                'populate_extras' => true // Whether to populate blogmeta
     296        ), 'blogs_blog_get_blog' );
     297
     298        if ( $r['populate_extras'] ) {
     299                // Check cache for blog data
     300                $blog = wp_cache_get( $r['blog_id'], 'bp_blogs' );
     301
     302                // Got Cache
     303                if ( false !== $blog ) {
     304                        return $blog;
     305                }
     306        }
     307
     308        $blog = new BP_Blogs_Blog( false, $r );
     309
     310        if ( $r['populate_extras'] && ! empty( $blog->blog_id ) ) {
     311                wp_cache_set( $blog->blog_id, $blog, 'bp_blogs' );
     312        }
     313
     314        /**
     315         * Filters a single blog object.
     316         *
     317         * @since BuddyPress (2.4.0)
     318         *
     319         * @param BP_Blogs_Blog $blog Single blog object.
     320         */
     321        return apply_filters( 'bp_blogs_blog_get_blog', $blog );
     322}
     323
     324/**
     325 * Helper function to let you make sure the user is not added as a subscriber
     326 * to the blog
     327 *
     328 * @since BuddyPress (2.4.0)
     329 *
     330 * @param  int $blog_id the blog id
     331 * @return bool         True to add the subcriber role to the user.
     332 *                      False otherwise
     333 */
     334function bp_blogs_blog_wp_subscriber_role( $blog_id = 0 ) {
     335        if ( empty( $blog_id ) ) {
     336                $blog_id = bp_blogs_blog_get_current_blog_id();
     337        }
     338
     339        /**
     340         * Use this filter if you do not want to add the user a subscriber role for the blog
     341         *
     342         * @since BuddyPress (2.4.0)
     343         *
     344         * @param bool True to add the subsriber role to the user for the blog,
     345         *             False otherwise
     346         * @param int  $blog_id the ID of the blog
     347         */
     348        return (bool) apply_filters( 'bp_blogs_blog_wp_subscriber_role', true, $blog_id );
     349}
     350
     351/**
     352 * Are subscriptions enabled for the given blog ?
     353 *
     354 * @since BuddyPress (2.4.0)
     355 *
     356 * @param  object $blog the Blogs single item object
     357 * @return bool         true if subscription are enabled, false otherwise.
     358 */
     359function bp_blogs_blog_can_subscribe( $blog = null ) {
     360        $can_subscribe = bp_blogs_blog_current_blog_can_subscribe();
     361
     362        if ( isset( $blog->disallow_subscriptions ) ) {
     363                $can_subscribe = ! $blog->disallow_subscriptions;
     364        }
     365
     366        /**
     367         * Filters subscriptions setting for the blog
     368         *
     369         * @since BuddyPress (2.4.0)
     370         *
     371         * @param bool   $can_subscribe true if subscription are enabled, false otherwise.
     372         * @param object $blog          Instance holding the current blog.
     373         */
     374        return (bool) apply_filters( 'bp_blogs_blog_can_subscribe', $can_subscribe, $blog );
     375}
     376
     377/** Current blog **************************************************************/
     378
     379/**
     380 * Get the BP_Blogs_Blog object corresponding to the current blog.
     381 *
     382 * @since BuddyPress (2.4.0)
     383 *
     384 * @return BP_Blogs_Blog The current blog object.
     385 */
     386function bp_blogs_blog_get_current_blog() {
     387        $bp = buddypress();
     388
     389        $current_blog = false;
     390
     391        if ( isset( $bp->blogs->current_blog ) ) {
     392                $current_blog = $bp->blogs->current_blog;
     393        }
     394
     395        /**
     396         * Filters the BP_Blogs_Blog object corresponding to the current blog.
     397         *
     398         * @since BuddyPress (2.4.0)
     399         *
     400         * @param BP_Blogs_Blog $current_blog Current BP_Blogs_Blog object.
     401         */
     402        return apply_filters( 'bp_blogs_blog_get_current_blog', $current_blog );
     403}
     404
     405/**
     406 * Returns the ID of the current blog
     407 *
     408 * @since BuddyPress (2.4.0)
     409 *
     410 * @return string The ID of the current blog, if there is one
     411 */
     412function bp_blogs_blog_get_current_blog_id() {
     413        $current_blog    = bp_blogs_blog_get_current_blog();
     414        $current_blog_id = '';
     415
     416        if ( isset( $current_blog->blog_id ) ) {
     417                $current_blog_id = $current_blog->blog_id;
     418        }
     419
     420        /**
     421         * Filters the ID of the current blog
     422         *
     423         * @since BuddyPress (2.4.0)
     424         *
     425         * @param string $current_blog_id ID of the current blog.
     426         * @param object $current_blog    Instance holding the current blog.
     427         */
     428        return apply_filters( 'bp_blogs_blog_get_current_blog_id', $current_blog_id, $current_blog );
     429}
     430
     431/**
     432 * Returns the name of the current blog
     433 *
     434 * @since BuddyPress (2.4.0)
     435 *
     436 * @return string The name of the current blog, if there is one
     437 */
     438function bp_blogs_blog_get_current_blog_name() {
     439        $current_blog      = bp_blogs_blog_get_current_blog();
     440        $current_blog_name = '';
     441
     442        if ( isset( $current_blog->name ) ) {
     443                $current_blog_name = $current_blog->name;
     444        }
     445
     446        /**
     447         * Filters the name of the current blog
     448         *
     449         * @since BuddyPress (2.4.0)
     450         *
     451         * @param string $current_blog_name Name of the current blog.
     452         * @param object $current_blog      Instance holding the current blog.
     453         */
     454        return apply_filters( 'bp_blogs_blog_get_current_blog_name', $current_blog_name, $current_blog );
     455}
     456
     457/**
     458 * Returns the slug of the current blog
     459 *
     460 * @since BuddyPress (2.4.0)
     461 *
     462 * @return string The slug of the current blog, if there is one
     463 */
     464function bp_blogs_blog_get_current_blog_slug() {
     465        $current_blog      = bp_blogs_blog_get_current_blog();
     466        $current_blog_slug = '';
     467
     468        if ( isset( $current_blog->slug ) ) {
     469                $current_blog_slug = $current_blog->slug;
     470        }
     471
     472        /**
     473         * Filters the slug of the current blog
     474         *
     475         * @since BuddyPress (2.4.0)
     476         *
     477         * @param string $current_blog_slug Slug of the current blog.
     478         * @param object $current_blog      Instance holding the current blog.
     479         */
     480        return apply_filters( 'bp_blogs_blog_get_current_blog_slug', $current_blog_slug, $current_blog );
     481}
     482
     483/**
     484 * Returns the admins of the current blog
     485 *
     486 * @since BuddyPress (2.4.0)
     487 *
     488 * @return array The admins list of the current blog
     489 */
     490function bp_blogs_blog_get_current_blog_admins() {
     491        $current_blog        = bp_blogs_blog_get_current_blog();
     492        $current_blog_admins = array();
     493
     494        if ( isset( $current_blog->admins ) ) {
     495                $current_blog_admins = wp_list_pluck( (array) $current_blog->admins, 'ID' );
     496        }
     497
     498        /**
     499         * Filters the slug of the current blog
     500         *
     501         * @since BuddyPress (2.4.0)
     502         *
     503         * @param array $current_blog_admins The admins list of the current blog
     504         * @param object $current_blog       Instance holding the current blog.
     505         */
     506        return (array) apply_filters( 'bp_blogs_blog_get_current_blog_admins', $current_blog_admins, $current_blog );
     507}
     508
     509/**
     510 * Is the user able to access to single blog's content
     511 *
     512 * @since BuddyPress (2.4.0)
     513 *
     514 * @return bool true if the user can access, false otherwise
     515 */
     516function bp_blogs_blog_current_blog_has_access() {
     517        $current_blog    = bp_blogs_blog_get_current_blog();
     518        $has_access      = false;
     519
     520        if ( isset( $current_blog->user_has_access ) ) {
     521                $has_access = $current_blog->user_has_access;
     522        }
     523
     524        /**
     525         * Filters the access to the current blog
     526         *
     527         * @since BuddyPress (2.4.0)
     528         *
     529         * @param bool   $has_access   true if user can access, false otherwise.
     530         * @param object $current_blog Instance holding the current blog.
     531         */
     532        return (bool) apply_filters( 'bp_blogs_blog_current_blog_has_access', $has_access, $current_blog );
     533}
     534
     535/**
     536 * Is the current blog item public
     537 *
     538 * @since BuddyPress (2.4.0)
     539 *
     540 * @return bool true if the blog is public, false otherwise
     541 */
     542function bp_blogs_blog_current_blog_is_public() {
     543        $current_blog    = bp_blogs_blog_get_current_blog();
     544        $is_public       = false;
     545
     546        if ( isset( $current_blog->blog_public ) ) {
     547                $is_public = $current_blog->blog_public;
     548        }
     549
     550        /**
     551         * Filters activity visibility of the blog
     552         *
     553         * @since BuddyPress (2.4.0)
     554         *
     555         * @param bool   $is_public    true if blog is public, false otherwise.
     556         * @param object $current_blog Instance holding the current blog.
     557         */
     558        return (bool) apply_filters( 'bp_is_blog_public', $is_public, $current_blog );
     559}
     560
     561/**
     562 * Can users subscribe to the current blog
     563 *
     564 * @since BuddyPress (2.4.0)
     565 *
     566 * @return bool true if users can subscribe to the current blog, false otherwise
     567 */
     568function bp_blogs_blog_current_blog_can_subscribe() {
     569        $current_blog    = bp_blogs_blog_get_current_blog();
     570
     571        // Defaults to site's visibility
     572        $can_subscribe   = bp_blogs_blog_current_blog_is_public();
     573
     574        if ( isset( $current_blog->disallow_subscriptions ) ) {
     575                $can_subscribe = ! $current_blog->disallow_subscriptions;
     576        }
     577
     578        /**
     579         * Filters subscriptions setting for the blog
     580         *
     581         * @since BuddyPress (2.4.0)
     582         *
     583         * @param bool   $can_subscribe true if subscription are enabled, false otherwise.
     584         * @param object $current_blog Instance holding the current blog.
     585         */
     586        return (bool) apply_filters( 'bp_blogs_blog_current_blog_can_subscribe', $can_subscribe, $current_blog );
     587}
     588
     589/**
     590 * Is current user a member of the current blog ?
     591 *
     592 * @since BuddyPress (2.4.0)
     593 * @uses apply_filters() Filter bp_current_blog_is_member to edit the user membership
     594 *
     595 * @return bool true if the user is a member of the current blog, false otherwise
     596 */
     597function bp_blogs_blog_current_blog_is_member() {
     598        $current_blog    = bp_blogs_blog_get_current_blog();
     599        $is_member       = false;
     600
     601
     602        if ( isset( $current_blog->is_member ) ) {
     603                $is_member = $current_blog->is_member;
     604        }
     605
     606        /**
     607         * Filters subscriptions setting for the blog
     608         *
     609         * @since BuddyPress (2.4.0)
     610         *
     611         * @param bool   $is_member true if the user is a member of the current blog, false otherwise.
     612         * @param object $current_blog Instance holding the current blog.
     613         */
     614        return (bool) apply_filters( 'bp_blogs_blog_current_blog_is_member', $is_member, $current_blog );
     615}
     616
     617/**
     618 * Return the link to the single blog item
     619 *
     620 * @since  BuddyPress (2.4.0)
     621 *
     622 * @param  object $blog the blog to get the view details link for
     623 * @return string the  link to the blog's single item
     624 */
     625function bp_blogs_blog_get_view_details_link( $blog = null ) {
     626        if ( empty( $blog->blog_id ) ) {
     627                $blog = bp_blogs_blog_get_current_blog();
     628        }
     629
     630        if ( isset( $blog->slug ) ) {
     631                $slug = $blog->slug;
     632        } elseif ( isset( $blog->path ) ) {
     633                if ( (int) get_current_site()->id === (int) $blog->blog_id ) {
     634                        $slug = bp_blogs_blog_get_site_slug();
     635                } else {
     636                        $slug = trim( str_replace( get_current_site()->path, '', $blog->path ), '/' );
     637                }
     638        } else {
     639                return false;
     640        }
     641
     642        $link = trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . '/' . $slug );
     643
     644        /**
     645         * Filters the blog view details link.
     646         *
     647         * @since BuddyPress (2.4.0)
     648         *
     649         * @param string $link Permalink URL to the profile of the blog.
     650         * @param object $blog the blogs single item object.
     651         */
     652        return apply_filters( 'bp_blogs_blog_get_view_details_link', $link, $blog );
     653}
     654
     655/**
     656 * Adds a relationship between a user and a blog
     657 *
     658 * We don't use bp_blogs_add_user_to_blog() to avoid recording blogmetas
     659 * @see bp_blogs_record_blog()
     660 *
     661 * @since BuddyPress (2.4.0)
     662 *
     663 * @return bool true if the relationship was created, false otherwise
     664 */
     665function bp_blogs_blog_link_user_to_blog( $user_id = 0, $blog_id = 0 ) {
     666        if ( empty( $user_id ) || empty( $blog_id ) ) {
     667                return false;
     668        }
     669
     670        // Create the relationship between user & blog
     671        $join_blog = new BP_Blogs_Blog( false, array( 'user_id' => $user_id, 'blog_id', $blog_id ) );
     672
     673        // The user has already subscribed or is a contributor
     674        if ( ! empty( $join_blog->id ) ) {
     675                return true;
     676        }
     677
     678        // Create the association
     679        $join_blog->user_id        = $user_id;
     680        $join_blog->blog_id        = $blog_id;
     681        $join_blog->is_contributor = 0;
     682
     683        if ( ! $join_blog->save() ) {
     684                return false;
     685        }
     686
     687        return true;
     688}
     689
     690/**
     691 * Subscribe a user to a blog
     692 *
     693 * @since BuddyPress (2.4.0)
     694 *
     695 * @param  int            $user_id the user id joining the blog
     696 * @param  BP_Blogs_Blog  $blog the blog object
     697 * @return array          the result in a feedback array
     698 */
     699function bp_blogs_blog_join_blog( $user_id = 0, $blog = null ) {
     700        if ( empty( $blog ) ) {
     701                $blog = bp_blogs_blog_get_current_blog();
     702        }
     703
     704        // Default result
     705        $result = array(
     706                'message' => __( 'We were not able to perform this action, please try again later', 'buddypress' ),
     707                'type'    => 'error',
     708        );
     709
     710        if ( ! bp_blogs_blog_can_subscribe( $blog ) || empty( $blog->blog_id ) ) {
     711                return $result;
     712        }
     713
     714        // Init the WP subscription result
     715        $subscribed = false;
     716
     717        if ( empty( $user_id ) ) {
     718                $user_id = bp_loggedin_user_id();
     719        }
     720
     721        // No user?
     722        if ( empty( $user_id ) ) {
     723                return $result;
     724        }
     725
     726        /**
     727         * Fires before the user joins the blog
     728         *
     729         * @since BuddyPress (2.4.0)
     730         *
     731         * @param int            $user_id the ID of the current user
     732         * @param BP_Blogs_Blog  $blog the blog object
     733         */
     734        do_action( 'bp_blogs_blog_before_join_blog', $user_id, $blog );
     735
     736        // First WordPress, making sure not to add a user that is already a user of the blog
     737        if ( bp_blogs_blog_wp_subscriber_role( $blog->blog_id ) && ! bp_user_can_for_blog( $user_id, 'read', $blog->blog_id ) ) {
     738                // No need to use this action
     739                remove_action( 'set_user_role', 'bp_blogs_add_user_to_blog', 10, 2 );
     740
     741                $subscribed = add_user_to_blog( $blog->blog_id, $user_id, 'subscriber' );
     742
     743                // Restore the action
     744                add_action( 'set_user_role', 'bp_blogs_add_user_to_blog', 10, 2 );
     745        }
     746
     747        if ( is_wp_error( $subscribed ) ) {
     748                $result = array(
     749                        'message' => $subscribed->get_error_message(),
     750                        'type'    => 'error',
     751                );
     752        } else {
     753                // Then BuddyPress
     754                bp_blogs_blog_link_user_to_blog( $user_id, $blog->blog_id );
     755
     756                $result = array(
     757                        'message' => __( 'You successfully joined the site.', 'buddypress' ),
     758                        'type'    => '',
     759                );
     760
     761                $user_link = bp_core_get_userlink( $user_id );
     762
     763                $action = sprintf(
     764                        __( '%1$s subscribed to the site %2$s', 'buddypress' ),
     765                        $user_link,
     766                        '<a href="' . esc_url( bp_blogs_blog_get_view_details_link() ) . '">' . esc_html( $blog->name ) . '</a>'
     767                );
     768
     769                bp_blogs_record_activity( array(
     770                        'action'  => $action,
     771                        'type'    => 'site_subscription',
     772                        'item_id' => $blog->blog_id,
     773                ) );
     774
     775                // Update the blog's last activity.
     776                bp_blogs_update_blogmeta( $blog->blog_id, 'last_activity', bp_core_current_time() );
     777
     778                /**
     779                 * Fires after the user joined the blog
     780                 *
     781                 * @since BuddyPress (2.4.0)
     782                 *
     783                 * @param int            $user_id the ID of the current user
     784                 * @param BP_Blogs_Blog  $blog the current blog object
     785                 */
     786                do_action( 'bp_blogs_blog_joined_blog', $user_id, $blog );
     787        }
     788
     789        return $result;
     790}
     791
     792/**
     793 * Unsubscribe a user from a blog
     794 *
     795 * @since BuddyPress (2.4.0)
     796 *
     797 * @param  int $user_id the user id joining the blog
     798 * @param  int $blog_id the blog id the user is joining
     799 * @return array        the result in a feedback array
     800 */
     801function bp_blogs_blog_leave_blog( $user_id = 0, $blog_id = 0 ) {
     802        if ( empty( $blog_id ) ) {
     803                $blog_id = bp_blogs_blog_get_current_blog_id();
     804        }
     805
     806        // Default result
     807        $result = array(
     808                'message' => __( 'We were not able to perform this action, please try again later', 'buddypress' ),
     809                'type'    => 'error',
     810        );
     811
     812        // Bail if no blog were found
     813        if ( empty( $blog_id ) ) {
     814                return $result;
     815        }
     816
     817        // Init the WP unsubscription result
     818        $unsubscribed = false;
     819
     820        if ( empty( $user_id ) ) {
     821                $user_id = bp_loggedin_user_id();
     822        }
     823
     824        // No user?
     825        if ( empty( $user_id ) ) {
     826                return $result;
     827        }
     828
     829        /**
     830         * Fires before the user leaves the blog
     831         *
     832         * @since BuddyPress (2.4.0)
     833         *
     834         * @param int            $user_id the ID of the current user
     835         * @param BP_Blogs_Blog  $blog the current blog object
     836         */
     837        do_action( 'bp_blogs_blog_before_leave_blog', $user_id, $blog_id );
     838
     839        // First WordPress
     840        if ( bp_blogs_blog_wp_subscriber_role( $blog_id ) && bp_user_can_for_blog( $user_id, 'read', $blog_id ) ) {
     841                // No need to use these actions
     842                remove_action( 'remove_user_from_blog', 'bp_blogs_remove_blog_for_user', 10, 2 );
     843                remove_action( 'remove_user_from_blog', 'bp_blogs_remove_user_from_blog', 10, 2 );
     844
     845                $unsubscribed = remove_user_from_blog( $user_id, $blog_id );
     846
     847                // Restore the actions
     848                add_action( 'remove_user_from_blog', 'bp_blogs_remove_blog_for_user', 10, 2 );
     849                add_action( 'remove_user_from_blog', 'bp_blogs_remove_user_from_blog', 10, 2 );
     850        }
     851
     852        if ( is_wp_error( $unsubscribed ) ) {
     853                $result = array(
     854                        'message' => $unsubscribed->get_error_message(),
     855                        'type'    => 'error',
     856                );
     857        } else {
     858                // Then BuddyPress
     859                BP_Blogs_Blog::delete_blog_for_user( $blog_id, $user_id );
     860
     861                $result = array(
     862                        'message' => __( 'You successfully left the site.', 'buddypress' ),
     863                        'type'    => 'success',
     864                );
     865
     866                bp_blogs_delete_activity( array(
     867                        'user_id' => $user_id,
     868                        'item_id' => $blog_id,
     869                        'type'    => 'site_subscription',
     870                ) );
     871
     872                /**
     873                 * Fires after the user left the blog
     874                 *
     875                 * @since BuddyPress (2.4.0)
     876                 *
     877                 * @param int $user_id the ID of the current user
     878                 * @param int $blog_id the ID of the blog
     879                 */
     880                do_action( 'bp_blogs_blog_left_blog', $user_id, $blog_id );
     881        }
     882
     883        return $result;
     884}
     885
     886/**
     887 * Generate the avatar upload directory path for a given blog.
     888 *
     889 * @since BuddyPress (2.4.0)
     890 *
     891 * @param int $blog_id Optional. ID of the blog. Default: ID of the
     892 *        current blog.
     893 * @return string
     894 */
     895function blogs_avatar_upload_dir( $blog_id = 0 ) {
     896
     897        if ( empty( $blog_id ) ) {
     898                $blog_id = bp_blogs_blog_get_current_blog_id();
     899        }
     900
     901        $directory = 'blog-avatars';
     902        $path      = bp_core_avatar_upload_path() . '/' . $directory . '/' . $blog_id;
     903        $newbdir   = $path;
     904        $newurl    = bp_core_avatar_url() . '/' . $directory . '/' . $blog_id;
     905        $newburl   = $newurl;
     906        $newsubdir = '/' . $directory . '/' . $blog_id;
     907
     908        /**
     909         * Filters the avatar upload directory path for a given blog.
     910         *
     911         * @since BuddyPress (2.4.0)
     912         *
     913         * @param array $value Array of parts related to the blog avatar upload directory.
     914         */
     915        return apply_filters( 'blogs_avatar_upload_dir', array(
     916                'path'    => $path,
     917                'url'     => $newurl,
     918                'subdir'  => $newsubdir,
     919                'basedir' => $newbdir,
     920                'baseurl' => $newburl,
     921                'error'   => false
     922        ) );
     923}
     924
     925/**
     926 * Check if avatar uploads are enabled
     927 *
     928 * @since BuddyPress (2.4.0)
     929 *
     930 * @return bool true if avatar uploads are enabled, false otherwise.
     931 */
     932function bp_blogs_blog_is_avatar_uploads_enabled() {
     933        $bp = buddypress();
     934
     935        /**
     936         * Check if :
     937         * - user can upload blog avatars
     938         * - the WordPress show avatars setting is enabled
     939         * - the new avatar UI is not disabled.
     940         */
     941        $is_avatar_enabled = ! bp_blogs_blog_disable_avatar_uploads() && $bp->avatar->show_avatars && false !== (bool) apply_filters( 'bp_avatar_is_front_edit', true );
     942
     943        /**
     944         * Filters the ability to set an avatar for a given blog.
     945         *
     946         * @since BuddyPress (2.4.0)
     947         *
     948         * @param bool $is_avatar_enabled true if avatar uploads are enabled, false otherwise.
     949         */
     950        return (bool) apply_filters( 'bp_blogs_blog_is_avatar_uploads_enabled', $is_avatar_enabled );
     951}
     952
     953/**
     954 * Return whether a blog has an avatar
     955 *
     956 * @since BuddyPress (2.4.0)
     957 *
     958 * @param  int $blog_id
     959 * @return boolean
     960 */
     961function bp_get_blog_has_avatar( $blog_id = false ) {
     962        if ( false === $blog_id ) {
     963                $blog_id = bp_blogs_blog_get_current_blog_id();
     964        }
     965
     966        $blog_avatar = bp_core_fetch_avatar( array(
     967                'item_id' => $blog_id,
     968                'object'  => 'blog',
     969                'no_grav' => true,
     970                'html'    => false,
     971        ) );
     972
     973        if ( bp_core_avatar_default( 'local' ) === $blog_avatar ) {
     974                return false;
     975        }
     976
     977        return true;
     978}
     979
     980/** Filters ******************************************************************/
     981
     982/**
     983 * Filters the body class to add a custom header class if the
     984 * current blog is supporting it
     985 *
     986 * @since BuddyPress (2.4.0)
     987 *
     988 * @param  array $classes list of body classes
     989 * @return array the list of body classes
     990 */
     991function bp_blogs_blog_body_class( $classes = array() ) {
     992        // Get the current blog
     993        $current_blog = bp_blogs_blog_get_current_blog();
     994
     995        // If set, check it has a custom header
     996        if ( ! empty( $current_blog->custom_header ) ) {
     997                $classes[] = 'bp-blog-custom-header';
     998        }
     999
     1000        return $classes;
     1001}
     1002add_filter( 'bp_get_the_body_class', 'bp_blogs_blog_body_class', 10, 1 );
     1003
     1004add_filter( 'bp_get_blog_description',          'wptexturize'       );
     1005add_filter( 'bp_get_blog_name',                 'wptexturize'       );
     1006add_filter( 'bp_get_blog_description',          'convert_smilies'   );
     1007add_filter( 'bp_get_blog_description',          'convert_chars'     );
     1008add_filter( 'bp_get_blog_name',                 'convert_chars'     );
     1009add_filter( 'bp_get_blog_description',          'wpautop'           );
     1010add_filter( 'bp_get_blog_description',          'make_clickable', 9 );
     1011add_filter( 'bp_get_blog_name',                 'wp_filter_kses', 1 );
     1012add_filter( 'bp_get_blog_description',          'stripslashes'      );
     1013add_filter( 'bp_get_blog_description_editable', 'stripslashes'      );
     1014add_filter( 'bp_get_blog_name',                 'stripslashes'      );
     1015add_filter( 'bp_get_blog_name_editable',        'stripslashes'      );
     1016
     1017/** Screens ******************************************************************/
     1018
     1019/**
     1020 * Home screen for the blogs single item
     1021 *
     1022 * @since BuddyPress (2.4.0)
     1023 */
     1024function bp_blogs_blog_screen_blog_home() {
     1025        if ( ! bp_is_single_item() ) {
     1026                return false;
     1027        }
     1028
     1029        /**
     1030         * Hook here to run specific actions juste before
     1031         * a blog's single page is displayed
     1032         *
     1033         * @since BuddyPress (2.4.0)
     1034         */
     1035        do_action( 'bp_blogs_blog_screen_blog_home' );
     1036
     1037        if ( ! empty( $_GET['action'] ) && ( 'join' === $_GET['action'] || 'leave' === $_GET['action'] ) ) {
     1038                $action = sanitize_key( $_GET['action'] );
     1039
     1040                check_admin_referer( 'blogs_' . $action . '_blog' );
     1041
     1042                $referer = wp_get_referer();
     1043                $result = array(
     1044                        'message' => __( 'We were not able to perform this action, please try again later', 'buddypress' ),
     1045                        'type'    => 'error',
     1046                );
     1047
     1048                if ( is_user_logged_in() && is_callable( 'bp_blogs_blog_' . $action . '_blog' ) ) {
     1049                        $result = call_user_func( 'bp_blogs_blog_' . $action . '_blog' );
     1050                }
     1051
     1052                bp_core_add_message( $result['message'], $result['type'] );
     1053                bp_core_redirect( $referer );
     1054        }
     1055
     1056        bp_core_load_template( apply_filters( 'bp_blogs_blog_template_blog_home', 'blogs/single/home' ) );
     1057}
     1058
     1059/**
     1060 * Settings screen for the blogs single item
     1061 *
     1062 * @since BuddyPress (2.4.0)
     1063 */
     1064function bp_blogs_blog_screen_blog_settings() {
     1065        if ( ! bp_is_single_item() ) {
     1066                return false;
     1067        }
     1068
     1069        /**
     1070         * Hook here to run specific actions juste before
     1071         * a blog's single settings page is displayed
     1072         *
     1073         * @since BuddyPress (2.4.0)
     1074         */
     1075        do_action( 'bp_blogs_blog_screen_blog_settings' );
     1076
     1077        if ( bp_is_blog_manage() && ! bp_action_variables( 0 ) && ! empty( $_POST['bp_blog']['submit'] ) ) {
     1078
     1079                check_admin_referer( 'blog_settings_general' );
     1080
     1081                unset( $_POST['bp_blog']['submit'] );
     1082                $options = $_POST['bp_blog'];
     1083
     1084                if ( ! isset( $options['blog_public'] ) ) {
     1085                        $options['blog_public'] = 0;
     1086                }
     1087
     1088                $blog_id = bp_blogs_blog_get_current_blog_id();
     1089                $referer = wp_unslash( $_POST['_wp_http_referer'] );
     1090                $message = __( 'We were not able to perform this action, please try again later', 'buddypress' );
     1091
     1092                if ( empty( $blog_id ) ) {
     1093                        bp_core_add_message( $message, 'error' );
     1094                        bp_core_redirect( $referer );
     1095                }
     1096
     1097                $success = 'error';
     1098
     1099                // Update general settings
     1100                if ( bp_get_root_blog_id() !== $blog_id ) {
     1101                        $needs_reset = true;
     1102                        switch_to_blog( $blog_id );
     1103                }
     1104
     1105                if ( current_user_can( 'manage_options' ) ) {
     1106
     1107                        // This option will only be saved in BuddyPress blog metas
     1108                        if ( isset( $options['disallow_subscriptions'] ) ) {
     1109                                bp_blogs_update_blogmeta( $blog_id, 'disallow_subscriptions', intval( $options['disallow_subscriptions'] ) );
     1110                                unset( $options['disallow_subscriptions'] );
     1111                        } else {
     1112                                bp_blogs_delete_blogmeta( $blog_id, 'disallow_subscriptions' );
     1113                        }
     1114
     1115                        foreach ( $options as $key => $option ) {
     1116                                $sanitized_option = sanitize_option( $key, $option );
     1117
     1118                                update_option( $key, $sanitized_option );
     1119                        }
     1120                        $message = __( 'Settings saved.', 'buddypress' );
     1121                        $success = '';
     1122
     1123                } else {
     1124                        $message = __( 'You cannot update this site&#39;s options.', 'buddypress' );
     1125                }
     1126
     1127                if ( isset( $needs_reset ) ) {
     1128                        restore_current_blog();
     1129                }
     1130
     1131                // Redirect the user once done
     1132                bp_core_add_message( $message, $success );
     1133                bp_core_redirect( $referer );
     1134        }
     1135
     1136        if ( bp_is_blog_manage_screen( 'members' ) && isset( $_GET['remove_subscriber'] ) ) {
     1137
     1138                check_admin_referer( 'blogs_remove_subscriber' );
     1139
     1140                $blog_id = bp_blogs_blog_get_current_blog_id();
     1141                $user_id = intval( $_GET['remove_subscriber'] );
     1142                $referer = wp_get_referer();
     1143                $message = __( 'We were not able to perform this action, please try again later', 'buddypress' );
     1144                $type    = 'error';
     1145
     1146                if ( ! bp_is_item_admin() || empty( $blog_id ) || empty( $user_id ) ) {
     1147                        bp_core_add_message( $message, $type );
     1148                        bp_core_redirect( $referer );
     1149                }
     1150
     1151                if ( bp_user_can_for_blog( $user_id, 'edit_posts', $blog_id ) ) {
     1152                        $message = __( 'Only subscriptions can be removed from this screen.', 'buddypress' );
     1153                        bp_core_add_message( $message, $type );
     1154                        bp_core_redirect( $referer );
     1155                }
     1156
     1157                /**
     1158                 * Fires before the user is removed from the blog
     1159                 *
     1160                 * @since BuddyPress (2.4.0)
     1161                 *
     1162                 * @param int $user_id the ID of the current user
     1163                 * @param int $blog_id the ID of the blog
     1164                 */
     1165                do_action( 'bp_blogs_blog_before_remove_user_from_blog', $user_id, $blog_id );
     1166
     1167                /**
     1168                 * Removing the user is the same than leaving the blog
     1169                 */
     1170                $removed = bp_blogs_blog_leave_blog( $user_id, $blog_id );
     1171
     1172                if ( isset( $removed['type'] ) && 'error' !== $removed['type'] ) {
     1173                        $message = __( 'Member successfully removed from the site.', 'buddypress' );
     1174                        $type    = 'success';
     1175
     1176                        /**
     1177                         * Fires after the user was removed from the blog
     1178                         *
     1179                         * @since BuddyPress (2.4.0)
     1180                         *
     1181                         * @param int $user_id the ID of the current user
     1182                         * @param int $blog_id the ID of the blog
     1183                         */
     1184                        do_action( 'bp_blogs_blog_user_removed_from_blog', $user_id, $blog_id );
     1185                }
     1186
     1187                bp_core_add_message( $message, $type );
     1188                bp_core_redirect( $referer );
     1189        }
     1190
     1191        bp_core_load_template( apply_filters( 'bp_blogs_blog_template_blog_settings', 'blogs/single/home' ) );
     1192}
     1193
     1194/** Template *****************************************************************/
     1195
     1196// Blogs Directory
     1197
     1198/**
     1199 * Output button to view the blogs single item details.
     1200 *
     1201 * @since BuddyPress (2.4.0)
     1202 *
     1203 * @see bp_get_blogs_view_details_blog_button() for description of arguments.
     1204 *
     1205 * @param array $args See {@link bp_get_blogs_view_details_blog_button()}.
     1206 */
     1207function bp_blogs_view_details_blog_button( $args = '' ) {
     1208        echo bp_get_blogs_view_details_blog_button( $args );
     1209}
     1210add_action( 'bp_directory_blogs_actions', 'bp_blogs_view_details_blog_button' );
     1211
     1212        /**
     1213         * Return button for viewing the blogs single item details.
     1214         *
     1215         * @since BuddyPress (2.4.0)
     1216         *
     1217         * @see BP_Button for a complete description of arguments and return
     1218         *      value.
     1219         *
     1220         * @global object $blogs_template {@link BP_Blogs_Template}
     1221         *
     1222         * @param array $args {
     1223         *     Arguments are listed below, with their default values. For a
     1224         *     complete description of arguments, see {@link BP_Button}.
     1225         *     @type string $id Default: 'view_blog_profile'.
     1226         *     @type string $component Default: 'blogs'.
     1227         *     @type bool $must_be_logged_in Default: false.
     1228         *     @type bool $block_self Default: false.
     1229         *     @type string $wrapper_class Default: 'blog-button profile'.
     1230         *     @type string $link_href View details link of the current blog in the loop.
     1231         *     @type string $link_class Default: 'blog-button profile'.
     1232         *     @type string $link_text Default: 'View Details'.
     1233         *     @type string $link_title Default: 'View Details'.
     1234         * }
     1235         * @return string The HTML for the Visit button.
     1236         */
     1237        function bp_get_blogs_view_details_blog_button( $args = '' ) {
     1238                global $blogs_template;
     1239                $blog = false;
     1240
     1241                if ( ! empty( $blogs_template->blog ) ) {
     1242                        $blog = $blogs_template->blog;
     1243                } else {
     1244                        $blog = bp_get_blog();
     1245                }
     1246
     1247                $button = wp_parse_args( $args, array(
     1248                        'id'                => 'view_blog_profile',
     1249                        'component'         => 'blogs',
     1250                        'must_be_logged_in' => false,
     1251                        'block_self'        => false,
     1252                        'wrapper_class'     => 'blog-button profile',
     1253                        'link_href'         => esc_url( bp_blogs_blog_get_view_details_link( $blog ) ),
     1254                        'link_class'        => 'blog-button profile',
     1255                        'link_text'         => __( 'View Details', 'buddypress' ),
     1256                        'link_title'        => __( 'View Details', 'buddypress' ),
     1257                ) );
     1258
     1259                // Filter and return the HTML button
     1260                return bp_get_button( apply_filters( 'bp_get_blogs_view_details_blog_button', $button ) );
     1261        }
     1262
     1263// Blogs Single item
     1264
     1265/**
     1266 * Load the appropriate current blog's home page
     1267 *
     1268 * @since BuddyPress (2.4.0)
     1269 */
     1270function bp_blogs_blog_load_front_template( $require_once = false, $blog = null ) {
     1271        $located = bp_blogs_blog_get_blog_front_template( $blog );
     1272
     1273        if ( false !== $located ) {
     1274                $slug = str_replace( '.php', '', $located );
     1275
     1276                /**
     1277                 * Let plugins adding an action to bp_get_template_part get it from here
     1278                 *
     1279                 * @param string $slug Template part slug requested.
     1280                 * @param string $name Template part name requested.
     1281                 */
     1282                do_action( 'get_template_part_' . $slug, $slug, false );
     1283
     1284                load_template( $located, $require_once );
     1285
     1286        } elseif ( bp_is_active( 'activity' ) && bp_blogs_blog_current_blog_is_public() ) {
     1287                bp_get_template_part( 'blogs/single/activity' );
     1288
     1289        } elseif ( bp_is_active( 'members' ) ) {
     1290                bp_get_template_part( 'blogs/single/members' );
     1291        }
     1292
     1293        return $located;
     1294}
     1295
     1296/**
     1297 * Locate a custom blog front template if it exsists
     1298 *
     1299 * @since BuddyPress (2.4.0)
     1300 */
     1301function bp_blogs_blog_get_blog_front_template( $blog = null ) {
     1302        if ( ! is_a( $blog, 'BP_Blogs_Blog' ) ) {
     1303                $blog = bp_blogs_blog_get_current_blog();
     1304        }
     1305
     1306        if ( ! isset( $blog->blog_id ) ) {
     1307                return false;
     1308        }
     1309
     1310        if ( isset( $blog->front_template ) ) {
     1311                return $blog->front_template;
     1312        }
     1313
     1314        $template_names = apply_filters( 'bp_blogs_get_front_template', array(
     1315                'blogs/single/front-id-'     . sanitize_file_name( $blog->blog_id )     . '.php',
     1316                'blogs/single/front-slug-'   . sanitize_file_name( $blog->slug )   . '.php',
     1317                'blogs/single/front.php'
     1318        ) );
     1319
     1320        return bp_locate_template( $template_names, false, true );
     1321}
     1322
     1323/**
     1324 * Get the blog object within the blogs loop
     1325 *
     1326 * @since BuddyPress (2.4.0)
     1327 *
     1328 * @global $blogs_template
     1329 */
     1330function bp_get_blog() {
     1331        global $blogs_template;
     1332        $blog = false;
     1333
     1334        if ( ! empty( $blogs_template->blog->blog_id ) ) {
     1335                $blog = &$blogs_template->blog;
     1336        } else {
     1337                $blog = bp_blogs_blog_get_current_blog();
     1338        }
     1339
     1340        return apply_filters( 'bp_get_blog', $blog );
     1341}
     1342
     1343// Add a button to visit the site in the blogs single item
     1344add_action( 'bp_blog_header_actions', 'bp_blogs_visit_blog_button', 10 );
     1345
     1346/**
     1347 * Display the blog's custom header if set
     1348 *
     1349 * @since BuddyPress (2.4.0)
     1350 */
     1351function bp_blog_custom_header() {
     1352        echo bp_get_blog_custom_header();
     1353}
     1354
     1355        /**
     1356         * Get the blog's custom header if set
     1357         *
     1358         * NB: The custom header is managed by the blog's
     1359         * active theme.
     1360         *
     1361         * @since BuddyPress (2.4.0)
     1362         */
     1363        function bp_get_blog_custom_header() {
     1364                $blog          = bp_get_blog();
     1365                $custom_header = false;
     1366
     1367                if ( ! empty( $blog->custom_header ) ) {
     1368                        $custom_header = $blog->custom_header;
     1369                }
     1370
     1371                if ( ! (bool) $custom_header ) {
     1372                        return;
     1373                }
     1374
     1375                $output = array(
     1376                        '<style type="text/css" media="screen">',
     1377                        '/*<![CDATA[*/',
     1378                        '#buddypress #item-header {',
     1379                        '   background: url(' . $custom_header . ') no-repeat 50% 50%;',
     1380                        '}',
     1381                        '/*]]>*/',
     1382                        '</style>',
     1383                );
     1384
     1385                /**
     1386                 * Filters a blog's custom header.
     1387                 *
     1388                 * @since BuddyPress (2.4.0)
     1389                 *
     1390                 * @param string         some css rules
     1391                 * @param array  $output The output organized into an array
     1392                 * @param object $blog   The blog object
     1393                 */
     1394                return apply_filters( 'bp_get_blog_custom_header', join( "\n", $output ), $output, $blog );
     1395        }
     1396
     1397/**
     1398 * Display the admins in the blog's header
     1399 *
     1400 * @since BuddyPress (2.4.0)
     1401 */
     1402function bp_blog_list_admins() {
     1403        echo bp_get_blog_list_admins();
     1404}
     1405        /**
     1406         * Get the admins list
     1407         *
     1408         * @since BuddyPress (2.4.0)
     1409         */
     1410        function bp_get_blog_list_admins() {
     1411                $blog       = bp_get_blog();
     1412                $pre_output = false;
     1413
     1414                // Do not display admins if the user has no access
     1415                if ( ! bp_blog_has_access() ) {
     1416                        $pre_output = '';
     1417                }
     1418
     1419                /**
     1420                 * Use this filter if you need to hide the blog admins by returning false
     1421                 *
     1422                 * @since BuddyPress (2.4.0)
     1423                 *
     1424                 * @param boolean $pre_output whether to output the list of the current blog admins
     1425                 * @param object  $blog the blogs single item object
     1426                 */
     1427                $pre_output = apply_filters( 'bp_blog_pre_get_current_blog_admins', $pre_output, $blog );
     1428                if ( false !== $pre_output ) {
     1429                        return $pre_output;
     1430                }
     1431
     1432                $output = '<h3>' . esc_html__( 'Site Admins', 'buddypress' ) . '</h3>';
     1433
     1434                if ( ! empty( $blog->admins ) ) {
     1435                        $output .= '<ul id="blog-admins">';
     1436
     1437                        foreach( (array) $blog->admins as $admin ) {
     1438                                $output .= '<li>';
     1439
     1440                                if ( bp_disable_avatar_uploads() ) {
     1441                                        $output .= sprintf(
     1442                                                '<a href="%s" title="%s">%s</a>',
     1443                                                esc_url( bp_core_get_user_domain( $admin->ID, $admin->user_nicename, $admin->user_login ) ),
     1444                                                sprintf( esc_attr__( 'Profile of %s', 'buddypress' ), $admin->display_name ),
     1445                                                esc_html( $admin->user_nicename )
     1446                                        );
     1447                                } else {
     1448                                        $output .= sprintf(
     1449                                                '<a href="%s">%s</a>',
     1450                                                esc_url( bp_core_get_user_domain( $admin->ID, $admin->user_nicename, $admin->user_login ) ),
     1451                                                bp_core_fetch_avatar( array(
     1452                                                        'item_id' => esc_attr( $admin->ID ),
     1453                                                        'email'   => esc_attr( $admin->user_email ),
     1454                                                        'alt'     => sprintf( esc_attr__( 'Profile picture of %s', 'buddypress' ), $admin->display_name )
     1455                                                ) )
     1456                                        );
     1457                                }
     1458
     1459                                $output .= '</li>';
     1460                        }
     1461
     1462                        $output .= '</ul>';
     1463                } else {
     1464                        $output .= '<span class="activity">' . esc_html__( 'No Admins', 'buddypress' ) . '</span>';
     1465                }
     1466
     1467                return apply_filters( 'bp_get_blog_list_admins', $output, $blog );
     1468        }
     1469
     1470/**
     1471 * Output the link to the single blog item
     1472 *
     1473 * @since  BuddyPress (2.4.0)
     1474 */
     1475function bp_blog_view_details_link() {
     1476        echo bp_blogs_blog_get_view_details_link( bp_get_blog() );
     1477}
     1478
     1479/**
     1480 * Is the current blog item public
     1481 *
     1482 * @since BuddyPress (2.4.0)
     1483 *
     1484 * @return bool true if the blog is public, false otherwise
     1485 */
     1486function bp_blog_is_public() {
     1487        $blog      = bp_get_blog();
     1488        $is_public = false;
     1489
     1490        if ( ! empty( $blog->blog_public ) ) {
     1491                $is_public = $blog->blog_public;
     1492        }
     1493
     1494        /**
     1495         * Filters activity visibility of the blog
     1496         *
     1497         * @since BuddyPress (2.4.0)
     1498         *
     1499         * @param bool   $is_public    true if blog is public, false otherwise.
     1500         * @param object $blog         the blogs single object.
     1501         */
     1502        return (bool) apply_filters( 'bp_is_blog_public', $is_public, $blog );
     1503}
     1504
     1505/**
     1506 * Display the current blog type
     1507 *
     1508 * @since BuddyPress (2.4.0)
     1509 */
     1510function bp_blog_status() {
     1511        echo bp_get_blog_status();
     1512}
     1513
     1514        /**
     1515         * Display the blog status
     1516         *
     1517         * @since BuddyPress (2.4.0)
     1518         *
     1519         * @return string The status of the blog, if there is one
     1520         */
     1521        function bp_get_blog_status() {
     1522                $status = esc_html__( 'Private', 'buddypress' );
     1523
     1524                if ( bp_blog_is_public() ) {
     1525                        $status = esc_html__( 'Public', 'buddypress' );
     1526                }
     1527
     1528                /**
     1529                 * Use this filter if you need to edit the blog status
     1530                 *
     1531                 * @since BuddyPress (2.4.0)
     1532                 *
     1533                 * @param string $status the blog status
     1534                 */
     1535                return apply_filters( 'bp_get_blog_status', $status );
     1536        }
     1537
     1538/**
     1539 * Is the blog supporting subscriptions
     1540 *
     1541 * @since BuddyPress (2.4.0)
     1542 *
     1543 * @return bool True if users can subscribe, false otherwise
     1544 */
     1545function bp_get_blog_can_subscribe() {
     1546        return bp_blogs_blog_can_subscribe( bp_get_blog() );
     1547}
     1548
     1549/**
     1550 * Is the current user a member of the blog ?
     1551 *
     1552 * @since BuddyPress (2.4.0)
     1553 *
     1554 * @return bool True if users is a member of the blog, false otherwise
     1555 */
     1556function bp_blog_is_member() {
     1557        $blog      = bp_get_blog();
     1558        $is_member = false;
     1559
     1560        if ( ! empty( $blog->is_member ) ) {
     1561                $is_member = $blog->is_member;
     1562        }
     1563
     1564        /**
     1565         * Filters the current user's membership
     1566         *
     1567         * @since BuddyPress (2.4.0)
     1568         *
     1569         * @param bool   $is_member true if the current user is a member of the blog, false otherwise.
     1570         * @param object $blog      the blogs single object.
     1571         */
     1572        return (bool) apply_filters( 'bp_blog_is_member', $is_member, $blog );
     1573}
     1574
     1575function bp_blog_is_contributor() {
     1576        $blog           = bp_get_blog();
     1577        $is_contributor = false;
     1578
     1579        if ( ! empty( $blog->is_contributor ) ) {
     1580                $is_contributor = $blog->is_contributor;
     1581        }
     1582
     1583        /**
     1584         * Filters the current user's contributor's level for the blog
     1585         *
     1586         * @since BuddyPress (2.4.0)
     1587         *
     1588         * @param bool   $is_contributor true if the current user is a contributor of the blog, false otherwise.
     1589         * @param object $blog           the blogs single object.
     1590         */
     1591        return (bool) apply_filters( 'bp_blog_is_contributor', $is_contributor, $blog );
     1592}
     1593
     1594/**
     1595 * Does the user has access to the blog ?
     1596 *
     1597 * @since BuddyPress (2.4.0)
     1598 */
     1599function bp_blog_has_access() {
     1600        $blog       = bp_get_blog();
     1601        $has_access = false;
     1602
     1603        if ( ! empty( $blog->user_has_access ) ) {
     1604                $has_access = $blog->user_has_access;
     1605        }
     1606
     1607        /**
     1608         * Filters user's access for the blog
     1609         *
     1610         * @since BuddyPress (2.4.0)
     1611         *
     1612         * @param bool   $has_access   true if user has access, false otherwise.
     1613         * @param object $blog         the blogs single object.
     1614         */
     1615        return (bool) apply_filters( 'bp_blog_has_access', $has_access, $blog );
     1616}
     1617
     1618/**
     1619 * Prints a message if the user has no access to the blog's content
     1620 *
     1621 * @since BuddyPress (2.4.0)
     1622 */
     1623function bp_blog_status_message() {
     1624        $blog = bp_get_blog();
     1625        $message = false;
     1626
     1627        // For now display a message if the blog is not public
     1628        if ( empty( $blog->blog_public ) ) {
     1629                $message = __( 'The details of this site are restricted to its members.', 'buddypress' );
     1630        }
     1631
     1632        /**
     1633         * Filters a message if the blog is not public.
     1634         *
     1635         * @since BuddyPress (2.4.0)
     1636         *
     1637         * @param string $message Message to display to the current user.
     1638         * @param object $blog    Blog to get status message for.
     1639         */
     1640        echo apply_filters( 'bp_blog_status_message', $message, $blog );
     1641}
     1642
     1643/**
     1644 * Add a subcribe button in blog's header
     1645 *
     1646 * @since BuddyPress (2.4.0)
     1647 */
     1648function bp_blogs_join_blog_button( $blog = null ) {
     1649        echo bp_get_blogs_join_blog_button( $blog );
     1650}
     1651add_action( 'bp_blog_header_actions', 'bp_blogs_join_blog_button', 5 );
     1652
     1653        /**
     1654         * Get the blog's subcribe button
     1655         *
     1656         * @since BuddyPress (2.4.0)
     1657         */
     1658        function bp_get_blogs_join_blog_button( $blog = null ) {
     1659                if ( empty( $blog ) ) {
     1660                        $blog = bp_get_blog();
     1661                }
     1662
     1663                if ( ! is_user_logged_in() || ! isset( $blog->blog_id ) || ! bp_get_blog_can_subscribe() ) {
     1664                        return false;
     1665                }
     1666
     1667                // Already a member
     1668                if ( bp_blog_is_member() ) {
     1669
     1670                        if ( bp_blog_is_contributor() ) {
     1671                                return false;
     1672                        }
     1673
     1674                        $button = array(
     1675                                'id'                => 'leave_blog',
     1676                                'component'         => 'blogs',
     1677                                'must_be_logged_in' => true,
     1678                                'block_self'        => false,
     1679                                'wrapper_class'     => 'blog-button leave',
     1680                                'wrapper_id'        => 'blogbutton-' . $blog->blog_id,
     1681                                'link_href'         => esc_url( wp_nonce_url( bp_blogs_blog_get_view_details_link() . '?action=leave', 'blogs_leave_blog' ) ),
     1682                                'link_text'         => __( 'Leave', 'buddypress' ),
     1683                                'link_title'        => __( 'Leave', 'buddypress' ),
     1684                                'link_class'        => 'blog-button leave-blog confirm',
     1685                        );
     1686
     1687                // Not a member
     1688                } else {
     1689
     1690                        $button = array(
     1691                                'id'                => 'join_blog',
     1692                                'component'         => 'blogs',
     1693                                'must_be_logged_in' => true,
     1694                                'block_self'        => false,
     1695                                'wrapper_class'     => 'blog-button join',
     1696                                'wrapper_id'        => 'blogbutton-' . $blog->blog_id,
     1697                                'link_href'         => esc_url( wp_nonce_url( bp_blogs_blog_get_view_details_link() . '?action=join', 'blogs_join_blog' ) ),
     1698                                'link_text'         => __( 'Join', 'buddypress' ),
     1699                                'link_title'        => __( 'Join', 'buddypress' ),
     1700                                'link_class'        => 'blog-button join-blog',
     1701                        );
     1702                }
     1703
     1704                // Filter and return the HTML button
     1705                return bp_get_button( apply_filters( 'bp_get_blogs_join_blog_button', $button ) );
     1706        }
     1707
     1708// Blogs single item Members
     1709
     1710/**
     1711 * Construct a specific query for blog members
     1712 *
     1713 * @since BuddyPress (2.4.0)
     1714 *
     1715 * @param  BP_User_Query &$blog_user_query the BuddyPress User query object passed by reference
     1716 */
     1717function bp_blogs_blog_set_user_query( &$blog_user_query = null ) {
     1718        $bp = buddypress();
     1719
     1720        if ( empty( $bp->blogs->blog_user_query->args ) ) {
     1721                return;
     1722        }
     1723
     1724        $bp->blogs->blog_user_query->results = bp_blogs_blog_get_users_for_blog( $bp->blogs->blog_user_query->args );
     1725
     1726        // Defaults to no members by forcing to include a null user
     1727        $blog_members = array( 0 );
     1728
     1729        if ( ! empty( $bp->blogs->blog_user_query->results ) ) {
     1730                $blog_members = wp_list_pluck( $bp->blogs->blog_user_query->results, 'user_id' );
     1731        }
     1732
     1733        // Only include blog members ids
     1734        $blog_user_query->query_vars_raw['include'] = $blog_members;
     1735        $blog_user_query->query_vars['include']     = wp_parse_id_list( $blog_members );
     1736}
     1737
     1738/**
     1739 * Populate extra datas for each user of the blog members loop
     1740 *
     1741 * @since BuddyPress (2.4.0)
     1742 *
     1743 * @param  BP_User_Query $blog_user_query the BuddyPress User query object
     1744 */
     1745function bp_blogs_blog_user_query_populate_extras( $blog_user_query = null ) {
     1746        $bp = buddypress();
     1747
     1748        if ( empty( $bp->blogs->blog_user_query->results ) ) {
     1749                return;
     1750        }
     1751
     1752        $blog_admins = (array) bp_blogs_blog_get_current_blog_admins();
     1753
     1754        foreach ( (array) $bp->blogs->blog_user_query->results as $extra ) {
     1755                if ( isset( $blog_user_query->results[ $extra->user_id ] ) ) {
     1756                        $blog_user_query->results[ $extra->user_id ]->is_contributor = (int) $extra->is_contributor;
     1757
     1758                        if ( ! empty( $blog_admins ) && in_array( $extra->user_id, $blog_admins ) ) {
     1759                                $blog_user_query->results[ $extra->user_id ]->is_admin = 1;
     1760                        } else {
     1761                                $blog_user_query->results[ $extra->user_id ]->is_admin = 0;
     1762                        }
     1763                }
     1764        }
     1765}
     1766
     1767/**
     1768 * bp_has_members wrapper to fetch the current blog's members
     1769 *
     1770 * @since BuddyPress (2.4.0)
     1771 *
     1772 * @see bp_has_members() for detailed available arguments
     1773 */
     1774function bp_blog_has_members( $args = '' ) {
     1775        $bp = buddypress();
     1776
     1777        $user_level = false;
     1778
     1779        /**
     1780         * Only manage subscriptions when on the manage subscribers screen
     1781         */
     1782        if ( bp_is_blog_manage_screen( 'members' ) ) {
     1783                $user_level = 0;
     1784        }
     1785
     1786        $r = bp_parse_args( $args, array(
     1787                'type'            => 'active',
     1788                'page'            => 1,
     1789                'per_page'        => 20,
     1790                'max'             => false,
     1791                'page_arg'        => 'blogpage',
     1792                'user_id'         => 0,
     1793                'blog_id'         => bp_blogs_blog_get_current_blog_id(),          // Only return users of the current blog
     1794                'user_level'      => $user_level,
     1795        ), 'blog_has_members' );
     1796
     1797        // Build specific arguments for the Blog members
     1798        $bp->blogs->blog_user_query = new stdClass();
     1799        $bp->blogs->blog_user_query->args = array( 'blog_id' => (int) $r['blog_id'], 'user_level' => $r['user_level'] );
     1800
     1801        // Map levels
     1802        if ( 'contributor' === $r['user_level'] ) {
     1803                $bp->blogs->blog_user_query->args['user_level'] = 1;
     1804        } elseif ( 'subscriber' === $r['user_level'] ) {
     1805                $bp->blogs->blog_user_query->args['user_level'] = 0;
     1806        }
     1807
     1808        // Set up our query construct hook
     1809        add_action( 'bp_pre_user_query_construct', 'bp_blogs_blog_set_user_query', 10, 1 );
     1810
     1811        // Set up our populate_extras hook
     1812        add_action( 'bp_user_query_populate_extras', 'bp_blogs_blog_user_query_populate_extras', 10, 1 );
     1813
     1814        $blog_members = bp_has_members( $r );
     1815
     1816        // Remove actions
     1817        remove_action( 'bp_pre_user_query_construct', 'bp_blogs_blog_set_user_query', 10, 1 );
     1818        remove_action( 'bp_user_query_populate_extras', 'bp_blogs_blog_user_query_populate_extras', 10, 1 );
     1819
     1820        // Unset the global
     1821        unset( $bp->blogs->blog_user_query );
     1822
     1823        return $blog_members;
     1824}
     1825
     1826/**
     1827 * The following functions are wrapping some Members loop template functions
     1828 * It might be interesting in the future to use a specific class to extend
     1829 * BP_User_Query the same way the groups component is doing to add new filter
     1830 * options.
     1831 */
     1832
     1833/**
     1834 * bp_members wrapper for the current blog's
     1835 *
     1836 * @since BuddyPress (2.4.0)
     1837 */
     1838function bp_blog_members() {
     1839        return bp_members();
     1840}
     1841
     1842/**
     1843 * bp_the_member wrapper for the current blog's
     1844 *
     1845 * @since BuddyPress (2.4.0)
     1846 */
     1847function bp_blog_the_member() {
     1848        return bp_the_member();
     1849}
     1850
     1851/**
     1852 * bp_member_permalink wrapper for the current blog's
     1853 *
     1854 * @since BuddyPress (2.4.0)
     1855 */
     1856function bp_blog_member_permalink() {
     1857        return bp_member_permalink();
     1858}
     1859
     1860/**
     1861 * bp_member_avatar wrapper for the current blog's
     1862 *
     1863 * @since BuddyPress (2.4.0)
     1864 */
     1865function bp_blog_member_avatar() {
     1866        return bp_member_avatar();
     1867}
     1868
     1869/**
     1870 * bp_member_name wrapper for the current blog's
     1871 *
     1872 * @since BuddyPress (2.4.0)
     1873 */
     1874function bp_blog_member_name() {
     1875        return bp_member_name();
     1876}
     1877
     1878/**
     1879 * bp_get_member_latest_update wrapper for the current blog's
     1880 *
     1881 * @since BuddyPress (2.4.0)
     1882 */
     1883function bp_blog_get_member_latest_update() {
     1884        return bp_get_member_latest_update();
     1885}
     1886
     1887/**
     1888 * bp_member_latest_update wrapper for the current blog's
     1889 *
     1890 * @since BuddyPress (2.4.0)
     1891 */
     1892function bp_blog_member_latest_update() {
     1893        return bp_member_latest_update();
     1894}
     1895
     1896/**
     1897 * bp_member_last_active wrapper for the current blog's
     1898 *
     1899 * @since BuddyPress (2.4.0)
     1900 */
     1901function bp_blog_member_last_active() {
     1902        return bp_member_last_active();
     1903}
     1904
     1905/**
     1906 * Output button to remove a member from the site.
     1907 *
     1908 * @since BuddyPress (2.4.0)
     1909 *
     1910 * @see bp_get_blog_member_remove_button() for description of arguments.
     1911 *
     1912 * @param array $args See {@link bp_get_blog_member_remove_button()}.
     1913 */
     1914function bp_blog_member_remove_button( $args = '' ) {
     1915        echo bp_get_blog_member_remove_button( $args );
     1916}
     1917
     1918        /**
     1919         * Return button to remove a member from the site.
     1920         *
     1921         * @since BuddyPress (2.4.0)
     1922         *
     1923         * @see BP_Button for a complete description of arguments and return
     1924         *      value.
     1925         *
     1926         * @param array $args {
     1927         *     Arguments are listed below, with their default values. For a
     1928         *     complete description of arguments, see {@link BP_Button}.
     1929         *     @type string $id Default: 'blog_remove_subscriber'.
     1930         *     @type string $component Default: 'blogs'.
     1931         *     @type bool $must_be_logged_in Default: false.
     1932         *     @type bool $block_self Default: false.
     1933         *     @type string $wrapper_class Default: 'blog-button remove'.
     1934         *     @type string $link_href View details link of the current blog in the loop.
     1935         *     @type string $link_class Default: 'blog-button remove'.
     1936         *     @type string $link_text Default: 'Remove member'.
     1937         *     @type string $link_title Default: 'Remove member'.
     1938         * }
     1939         * @return string The HTML for the Visit button.
     1940         */
     1941        function bp_get_blog_member_remove_button( $args = '' ) {
     1942                global $members_template;
     1943
     1944                $remove_link = trailingslashit( bp_blogs_blog_get_view_details_link() . 'manage/members' );
     1945
     1946                /**
     1947                 * Extra security to avoid a contributor to be removed from the subscribers management screen
     1948                 *
     1949                 * Only subscribers should be listed on this screen @see bp_blog_has_members()
     1950                 */
     1951                if ( isset( $members_template->member->is_contributor ) && 1 === (int) $members_template->member->is_contributor ) {
     1952                        return;
     1953                }
     1954
     1955                $button = wp_parse_args( $args, array(
     1956                        'id'                => 'blog_remove_subscriber',
     1957                        'component'         => 'blogs',
     1958                        'must_be_logged_in' => true,
     1959                        'block_self'        => true,
     1960                        'wrapper_class'     => 'blog-button remove',
     1961                        'link_href'         => esc_url( wp_nonce_url( $remove_link . '?remove_subscriber=' . bp_get_member_user_id(), 'blogs_remove_subscriber' ) ),
     1962                        'link_class'        => 'blog-button remove',
     1963                        'link_text'         => __( 'Remove member', 'buddypress' ),
     1964                        'link_title'        => __( 'Remove member', 'buddypress' ),
     1965                ) );
     1966
     1967                // Filter and return the HTML button
     1968                return bp_get_button( apply_filters( 'bp_get_blog_member_remove_button', $button ) );
     1969        }
     1970
     1971// Blogs single item settings
     1972
     1973/**
     1974 * Display the blog's editable name
     1975 *
     1976 * @since BuddyPress (2.4.0)
     1977 */
     1978function bp_blog_name_editable() {
     1979        echo bp_get_blog_name_editable();
     1980}
     1981
     1982        /**
     1983         * Get the blog's editable name
     1984         *
     1985         * 'bp_get_blog_name_editable' does not have the formatting
     1986         * filters that 'bp_get_blog_name' has, which makes it
     1987         * appropriate for "raw" editing.
     1988         *
     1989         * @since BuddyPress (2.4.0)
     1990         */
     1991        function bp_get_blog_name_editable() {
     1992                $blog      = bp_get_blog();
     1993                $blog_name = false;
     1994
     1995                if ( ! empty( $blog->name ) ) {
     1996                        $blog_name = $blog->name;
     1997                }
     1998
     1999                /**
     2000                 * Filters the editable blog name.
     2001                 *
     2002                 * @since BuddyPress (2.4.0)
     2003                 *
     2004                 * @param string $blog_name the name of the blog.
     2005                 * @param object $blog      Blog to get the editable name for.
     2006                 */
     2007                return apply_filters( 'bp_get_blog_name_editable', $blog_name, $blog );
     2008        }
     2009
     2010/**
     2011 * Display the editable blog's description
     2012 *
     2013 * @since BuddyPress (2.4.0)
     2014 */
     2015function bp_blog_description_editable() {
     2016        echo bp_get_blog_description_editable();
     2017}
     2018
     2019        /**
     2020         * Get the blog's editable description
     2021         *
     2022         * 'bp_get_blog_description_editable' does not have the formatting
     2023         * filters that 'bp_get_blog_description' has, which makes it
     2024         * appropriate for "raw" editing.
     2025         *
     2026         * @since BuddyPress (2.4.0)
     2027         */
     2028        function bp_get_blog_description_editable() {
     2029                $blog             = bp_get_blog();
     2030                $blog_description = false;
     2031
     2032                if ( ! empty( $blog->description ) ) {
     2033                        $blog_description = $blog->description;
     2034                }
     2035
     2036                /**
     2037                 * Filters the editable blog description.
     2038                 *
     2039                 * @since BuddyPress (2.4.0)
     2040                 *
     2041                 * @param string $blog_description the description of the blog.
     2042                 * @param object $blog             Blog to get the editable description for.
     2043                 */
     2044                return apply_filters( 'bp_get_blog_description_editable', $blog_description, $blog );
     2045        }
  • src/bp-blogs/bp-blogs-cache.php

    diff --git src/bp-blogs/bp-blogs-cache.php src/bp-blogs/bp-blogs-cache.php
    index df751d2..85ee9f9 100644
    function bp_blogs_clear_blog_object_cache( $blog_id = 0, $user_id = 0 ) { 
    4646        if ( ! empty( $user_id ) ) {
    4747                wp_cache_delete( 'bp_blogs_of_user_'        . $user_id, 'bp' );
    4848                wp_cache_delete( 'bp_total_blogs_for_user_' . $user_id, 'bp' );
     49
     50                if ( is_multisite() && bp_is_active( 'blogs', 'blog' ) ) {
     51                        wp_cache_delete( 'bp_total_blogs_for_contributor_' . $user_id, 'bp' );
     52                        wp_cache_delete( 'bp_total_blogs_for_subscriber_' . $user_id,  'bp' );
     53                }
    4954        }
    5055
    5156        wp_cache_delete( 'bp_total_blogs', 'bp' );
    add_action( 'bp_blogs_remove_blog_for_user', 'bp_blogs_clear_blog_object_cache', 
    5661add_action( 'wpmu_new_blog',                 'bp_blogs_clear_blog_object_cache', 10, 2 );
    5762add_action( 'bp_blogs_remove_blog',          'bp_blogs_clear_blog_object_cache' );
    5863
     64/**
     65 * Bust blog caches when editing or deleting.
     66 *
     67 * @since BuddyPress (2.4.0)
     68 *
     69 * @param int $blog_id The blog being edited.
     70 */
     71function bp_blogs_delete_blog_cache( $blog_id = 0 ) {
     72        if ( is_multisite() && bp_is_active( 'blogs', 'blog' ) ) {
     73                wp_cache_delete( $blog_id, 'bp_blogs' );
     74        }
     75}
     76add_action( 'refresh_blog_details',          'bp_blogs_delete_blog_cache' );
     77add_action( 'bp_blogs_remove_blog',          'bp_blogs_delete_blog_cache' );
     78add_action( 'bp_blogs_remove_data_for_blog', 'bp_blogs_delete_blog_cache' );
     79add_action( 'bp_blogs_remove_blog_for_user', 'bp_blogs_delete_blog_cache' );
     80
     81/**
     82 * Bust blogs caches when a user was deleted or marked as spam
     83 *
     84 * @since BuddyPress (2.4.0)
     85 *
     86 * @param int $user_id ID of the user whose blog cache should be cleared.
     87 */
     88function bp_blogs_delete_blogs_cache( $user_id = 0 ) {
     89        if ( is_multisite() && bp_is_active( 'blogs', 'blog' ) ) {
     90                $blogs = BP_Blogs_Blog::get_blog_ids_for_user( $user_id );
     91
     92                if ( empty( $blogs ) ) {
     93                        return;
     94                }
     95
     96                foreach ( $blogs as $blog_id ) {
     97                        wp_cache_delete( $blog_id, 'bp_blogs' );
     98                }
     99        }
     100}
     101add_action( 'bp_blogs_before_remove_data', 'bp_blogs_delete_blogs_cache' );
     102
     103/**
     104 * Bust blog caches when a user or a blog option was edited
     105 *
     106 * @since BuddyPress (2.4.0)
     107 *
     108 * @param int $blog_id The blog being edited.
     109 */
     110function bp_blogs_delete_blog_cache_on_change() {
     111        if ( is_multisite() && bp_is_active( 'blogs', 'blog' ) ) {
     112                $blog_id = get_current_blog_id();
     113                wp_cache_delete( $blog_id, 'bp_blogs' );
     114        }
     115}
     116add_action( 'set_user_role',                              'bp_blogs_delete_blog_cache_on_change' );
     117add_action( 'update_option_blogname',                     'bp_blogs_delete_blog_cache_on_change' );
     118add_action( 'update_option_blogdescription',              'bp_blogs_delete_blog_cache_on_change' );
     119add_action( 'update_option_thread_comments_depth',        'bp_blogs_delete_blog_cache_on_change' );
     120add_action( 'update_option_thread_comments',              'bp_blogs_delete_blog_cache_on_change' );
     121add_action( 'update_option_close_comments_days_old',      'bp_blogs_delete_blog_cache_on_change' );
     122add_action( 'update_option_close_comments_for_old_posts', 'bp_blogs_delete_blog_cache_on_change' );
     123
     124/**
     125 * Bust blog caches when a user joins or leaves a blog
     126 *
     127 * @since BuddyPress (2.4.0)
     128 *
     129 * @param int $user_id ID of the user whose blog cache should be cleared.
     130 * @param BP_Blogs_Blog|int $blog The blog being joined or left.
     131 */
     132function bp_blogs_delete_blog_cache_on_joinleave( $user_id, $blog ) {
     133        if ( is_multisite() && bp_is_active( 'blogs', 'blog' ) ) {
     134                if ( is_a( $blog, 'BP_Blogs_Blog' ) ) {
     135                        $blog_id = (int) $blog->blog_id;
     136                } else {
     137                        $blog_id = (int) $blog;
     138                }
     139
     140                wp_cache_delete( $blog_id, 'bp_blogs' );
     141
     142                // Totals
     143                wp_cache_delete( 'bp_total_blogs_for_user_' . $user_id,        'bp' );
     144                wp_cache_delete( 'bp_total_blogs_for_contributor_' . $user_id, 'bp' );
     145                wp_cache_delete( 'bp_total_blogs_for_subscriber_' . $user_id,  'bp' );
     146        }
     147}
     148add_action( 'bp_blogs_blog_left_blog',   'bp_blogs_delete_blog_cache_on_joinleave', 10, 2 );
     149add_action( 'bp_blogs_blog_joined_blog', 'bp_blogs_delete_blog_cache_on_joinleave', 10, 2 );
     150
    59151// List actions to clear super cached pages on, if super cache is installed
    60152add_action( 'bp_blogs_remove_data_for_blog', 'bp_core_clear_cache' );
    61153add_action( 'bp_blogs_remove_comment',       'bp_core_clear_cache' );
  • src/bp-blogs/bp-blogs-functions.php

    diff --git src/bp-blogs/bp-blogs-functions.php src/bp-blogs/bp-blogs-functions.php
    index c45590a..80dd4cb 100644
    function bp_blogs_get_blogs( $args = '' ) { 
    4747                'type'              => 'active', // 'active', 'alphabetical', 'newest', or 'random'
    4848                'include_blog_ids'  => false,    // Array of blog IDs to include
    4949                'user_id'           => false,    // Limit to blogs this user can post to
     50                'user_level'        => false,    // 1 to limit to blogs the user is a contributor of
     51                                         // 0 to limit to blogs the user is a subscriber of
    5052                'search_terms'      => false,    // Limit to blogs matching these search terms
    5153                'per_page'          => 20,       // The number of results to return per page
    5254                'page'              => 1,        // The page to return if limiting per page
    function bp_blogs_get_blogs( $args = '' ) { 
    5961                $r['per_page'],
    6062                $r['page'],
    6163                $r['user_id'],
     64                $r['user_level'],
    6265                $r['search_terms'],
    6366                $r['update_meta_cache'],
    6467                $r['include_blog_ids']
    function bp_blogs_get_blogs( $args = '' ) { 
    7780 * @uses get_users()
    7881 * @uses bp_blogs_record_blog()
    7982 */
    80 function bp_blogs_record_existing_blogs() {
     83function bp_blogs_record_existing_blogs( $reset = false ) {
    8184        global $wpdb;
    8285
    8386        // Query for all sites in network
    function bp_blogs_record_existing_blogs() { 
    110113        // Get BuddyPress
    111114        $bp = buddypress();
    112115
    113         // Truncate user blogs table
    114         $truncate = $wpdb->query( "TRUNCATE {$bp->blogs->table_name}" );
    115         if ( is_wp_error( $truncate ) ) {
    116                 return false;
     116        /**
     117         * Only Truncate user blogs table if the admin wants
     118         * to completely reset the users/blogs association.
     119         * This will remove all subscriptions.
     120         */
     121        if ( ! empty( $reset ) ) {
     122                $truncate = $wpdb->query( "TRUNCATE {$bp->blogs->table_name}" );
     123                if ( is_wp_error( $truncate ) ) {
     124                        return false;
     125                }
    117126        }
    118127
    119128        // Truncate user blogsmeta table
    function bp_blogs_record_existing_blogs() { 
    140149
    141150                // Loop through users and record their relationship to this blog
    142151                foreach ( (array) $users as $user ) {
    143                         bp_blogs_add_user_to_blog( $user->ID, false, $blog_id );
     152                        // Using true as 4th argument informs it's a batch process
     153                        bp_blogs_add_user_to_blog( $user->ID, false, $blog_id, true );
    144154                }
    145155        }
    146156
    function bp_blogs_record_blog( $blog_id, $user_id, $no_activity = false ) { 
    252262                $thread_depth = 1;
    253263        }
    254264
    255         $recorded_blog          = new BP_Blogs_Blog;
    256         $recorded_blog->user_id = $user_id;
    257         $recorded_blog->blog_id = $blog_id;
    258         $recorded_blog_id       = $recorded_blog->save();
    259         $is_recorded            = !empty( $recorded_blog_id ) ? true : false;
     265        // Check if the association already exists
     266        $recorded_blog = new BP_Blogs_Blog( false, array( 'user_id' => $user_id, 'blog_id' => $blog_id ) );
     267
     268        // No blog found, it's a new association
     269        if ( empty( $recorded_blog->id ) ) {
     270                $recorded_blog->user_id        = $user_id;
     271                $recorded_blog->blog_id        = $blog_id;
     272        }
     273
     274        // Used to separate subscribers from contributors
     275        if ( bp_user_can_for_blog( $user_id, 'edit_posts', $blog_id ) ) {
     276                $recorded_blog->is_contributor = 1;
     277        } else {
     278                $recorded_blog->is_contributor = 0;
     279        }
     280
     281        // Save or update the user/blog association
     282        $recorded_blog_id = $recorded_blog->save();
     283        $is_recorded = false;
     284
     285        if ( ! empty( $recorded_blog_id ) ) {
     286                $is_recorded = true;
     287        }
    260288
    261289        bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'url', $url );
    262290        bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'name', $name );
    add_action( 'edit_comment', 'bp_blogs_record_comment', 10 ); 
    732760 * @param int         $user_id The ID of the user
    733761 * @param string|bool $role    User's WordPress role for this blog ID
    734762 * @param int         $blog_id Blog ID user is being added to
     763 * @param bool        $batch True if it's a batch operation (initial population/restore), false otherwise
    735764 *
    736765 * @return bool|null False on failure.
    737766 */
    738 function bp_blogs_add_user_to_blog( $user_id, $role = false, $blog_id = 0 ) {
     767function bp_blogs_add_user_to_blog( $user_id, $role = false, $blog_id = 0, $batch = false ) {
    739768        global $wpdb;
    740769
    741770        // If no blog ID was passed, use the root blog ID
    function bp_blogs_add_user_to_blog( $user_id, $role = false, $blog_id = 0 ) { 
    769798                }
    770799        }
    771800
    772         // Bail if no role was found or role is not in the allowed roles array
    773         if ( empty( $role ) || ! in_array( $role, bp_blogs_get_allowed_roles() ) ) {
     801        // Bail if no role was found
     802        if ( empty( $role ) ) {
     803                /**
     804                 * If it's not a batch operation and the user has no role on the site
     805                 * remove the user blog association without deleting the 'new_blog'
     806                 * activity
     807                 */
     808                if ( empty( $batch ) ) {
     809                        // Also remove the new subscription activity
     810                        if ( bp_is_active( 'blogs', 'blog' ) ) {
     811                                bp_blogs_blog_leave_blog( $user_id, $blog_id );
     812
     813                        // Simply remove the user blog association and make sure to reset blogs total cache
     814                        } else {
     815                                BP_Blogs_Blog::delete_blog_for_user( $blog_id, $user_id );
     816
     817                                /**
     818                                 * Fires after a blog has been removed from the tracker for a specific user.
     819                                 *
     820                                 * @since BuddyPress (1.0.0)
     821                                 *
     822                                 * @param int $blog_id ID of the blog that was removed.
     823                                 * @param int $user_id ID of the user having the blog removed for.
     824                                 */
     825                                do_action( 'bp_blogs_remove_blog_for_user', $blog_id, $user_id );
     826                        }
     827                }
     828
     829                return false;
     830        }
     831
     832        // Bail if it's a batch operation and role is not in the allowed roles array
     833        if ( ! empty( $batch ) && ! in_array( $role, bp_blogs_get_allowed_roles() ) ) {
    774834                return false;
    775835        }
    776836
    777837        // Record the blog activity for this user being added to this blog
    778838        bp_blogs_record_blog( $blog_id, $user_id, true );
    779839}
    780 add_action( 'add_user_to_blog', 'bp_blogs_add_user_to_blog', 10, 3 );
    781 add_action( 'profile_update',   'bp_blogs_add_user_to_blog'        );
    782 add_action( 'user_register',    'bp_blogs_add_user_to_blog'        );
     840add_action( 'set_user_role', 'bp_blogs_add_user_to_blog', 10, 2 );
    783841
    784842/**
    785843 * The allowed blog roles a member must have to be recorded into the
    function bp_blogs_remove_blog( $blog_id ) { 
    861919                'type'      => 'new_blog'
    862920        ) );
    863921
     922        // Remove the site's avatar.
     923        if ( is_multisite() && bp_blogs_blog_is_avatar_uploads_enabled() ) {
     924                bp_core_delete_existing_avatar( array( 'item_id' => $blog_id, 'object' => 'blog' ) );
     925        }
     926
    864927        /**
    865928         * Fires after a "blog created" item has been removed from blogs
    866929         * tracker and activity stream.
    function bp_blogs_total_blogs_for_user( $user_id = 0 ) { 
    11951258                return 0;
    11961259        }
    11971260
    1198         $count = wp_cache_get( 'bp_total_blogs_for_user_' . $user_id, 'bp' );
    1199         if ( false === $count ) {
    1200                 $count = BP_Blogs_Blog::total_blog_count_for_user( $user_id );
    1201                 wp_cache_set( 'bp_total_blogs_for_user_' . $user_id, $count, 'bp' );
     1261        if ( bp_is_active( 'blogs', 'blog' ) && bp_is_blogs_directory() ) {
     1262                // User level: 1 = contributor, 0 = subscriber
     1263                return bp_blogs_total_blogs_for_user_level( $user_id, 1 );
     1264        } else {
     1265                $count = wp_cache_get( 'bp_total_blogs_for_user_' . $user_id, 'bp' );
     1266                if ( false === $count ) {
     1267                        $count = BP_Blogs_Blog::total_blog_count_for_user( $user_id, false );
     1268                        wp_cache_set( 'bp_total_blogs_for_user_' . $user_id, $count, 'bp' );
     1269                }
    12021270        }
    12031271
    12041272        return $count;
    function bp_blogs_restore_data( $user_id = 0 ) { 
    14661534        $blogs = array_keys( $user_blogs );
    14671535
    14681536        foreach ( $blogs as $blog_id ) {
    1469                 bp_blogs_add_user_to_blog( $user_id, false, $blog_id );
     1537                bp_blogs_add_user_to_blog( $user_id, false, $blog_id, true );
    14701538        }
    14711539}
    14721540add_action( 'bp_make_ham_user', 'bp_blogs_restore_data', 10, 1 );
  • src/bp-blogs/bp-blogs-loader.php

    diff --git src/bp-blogs/bp-blogs-loader.php src/bp-blogs/bp-blogs-loader.php
    index d146f37..d2a7f0c 100644
    defined( 'ABSPATH' ) || exit; 
    1616
    1717class BP_Blogs_Component extends BP_Component {
    1818
     19        public $nav = null;
     20
    1921        /**
    2022         * Start the blogs component creation process.
    2123         *
    class BP_Blogs_Component extends BP_Component { 
    2729                        __( 'Site Directory', 'buddypress' ),
    2830                        buddypress()->plugin_dir,
    2931                        array(
    30                                 'adminbar_myaccount_order' => 30
     32                                'adminbar_myaccount_order' => 30,
     33                                'features'                 => array( 'blog' ),
    3134                        )
    3235                );
    3336        }
    class BP_Blogs_Component extends BP_Component { 
    101104
    102105                // Filter the generic track parameters for the 'post' post type.
    103106                add_filter( 'bp_activity_get_post_type_tracking_args', array( $this, 'post_tracking_args' ), 10, 2 );
     107
     108                /** Single Blog globals ***********************************************/
     109
     110                if ( is_multisite() && bp_is_blogs_component() && bp_current_action() && bp_is_active( $this->id, 'blog' ) ) {
     111                        /**
     112                         * Set the blogs single nav
     113                         *
     114                         * We need to do this early so that we can manage item access
     115                         * within the single nav
     116                         */
     117                        $this->nav = new BP_Single_Item_Navigation( array(
     118                                'component_id'   => $this->id,
     119                                'component_slug' => bp_get_blogs_root_slug(),
     120                                'single_item'    => 'blog',
     121                        ) );
     122
     123                        // Sort the single item nav
     124                        add_action( 'wp_head', array( $this, 'sort_single_item_nav' ) );
     125
     126                        // Find the current blog id
     127                        if ( bp_is_current_action( bp_blogs_blog_get_site_slug() ) ) {
     128                                $blog_id = get_current_site()->id;
     129                        } else {
     130                                $blog_id = get_id_from_blogname( bp_current_action() );
     131                        }
     132
     133                        // Set the current blog data
     134                        $this->current_blog = bp_blogs_blog_get_blog( array( 'blog_id' => $blog_id ) );
     135
     136                        if ( empty( $this->current_blog->blog_id ) ) {
     137                                $this->current_blog = 0;
     138                                return;
     139                        }
     140
     141                        // It's a blog single item
     142                        $bp->is_single_item  = true;
     143                        $bp->current_item    = $this->current_blog->slug;
     144                        $bp->current_action  = bp_action_variable( 0 );
     145                        array_shift( $bp->action_variables );
     146
     147                        $admin_keys = array_flip( wp_list_pluck( $this->current_blog->admins, 'ID' ) );
     148
     149                        if ( is_super_admin() || isset( $admin_keys[ bp_loggedin_user_id() ] ) ) {
     150                                bp_update_is_item_admin( true, $bp->blogs->id );
     151                        }
     152
     153                        // By Default grant access
     154                        $this->current_blog->user_has_access = true;
     155
     156                        // If blog is not public, non members can't access
     157                        if ( ! $this->current_blog->blog_public && ! $this->current_blog->is_member && ! bp_is_item_admin() ) {
     158                                $this->current_blog->user_has_access = false;
     159                        }
     160
     161                        // Check once if the current blog has a custom front template
     162                        $this->current_blog->front_template = bp_blogs_blog_get_blog_front_template( $this->current_blog );
     163                }
    104164        }
    105165
    106166        /**
     167         * Set up canonical stack for this component.
     168         *
     169         * @since BuddyPress (2.4.0)
     170         */
     171        public function setup_canonical_stack() {
     172                $bp = buddypress();
     173
     174                if ( ! bp_is_blogs_component() ) {
     175                        return;
     176                }
     177
     178                if ( empty( $this->current_blog ) ) {
     179                        return;
     180                }
     181
     182                if ( ! bp_current_action() ) {
     183                        $bp->current_action = 'home';
     184                }
     185
     186                // Prepare for a redirect to the canonical URL
     187                $bp->canonical_stack['base_url'] = trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . '/'. $this->current_blog->slug );
     188
     189                if ( bp_current_action() ) {
     190                        $bp->canonical_stack['action'] = bp_current_action();
     191                }
     192
     193                if ( ! empty( $bp->action_variables ) ) {
     194                        $bp->canonical_stack['action_variables'] = bp_action_variables();
     195                }
     196
     197                // When viewing the default extension, the canonical URL should not have
     198                // that extension's slug, unless more has been tacked onto the URL via
     199                // action variables
     200                if ( bp_is_current_action( 'home' ) && empty( $bp->action_variables ) )  {
     201                        unset( $bp->canonical_stack['action'] );
     202                }
     203        }
     204
     205        /**
    107206         * Include bp-blogs files.
    108207         *
    109208         * @see BP_Component::includes() for description of parameters.
    class BP_Blogs_Component extends BP_Component { 
    126225
    127226                if ( is_multisite() ) {
    128227                        $includes[] = 'widgets';
     228
     229                        // Conditional includes
     230                        if ( bp_is_active( $this->id, 'blog' ) ) {
     231                                $includes = array_merge( $includes, array(
     232                                        'blog',
     233                                        'notifications',
     234                                        'adminbar',
     235                                ) );
     236                        }
    129237                }
    130238
    131239                // Include the files
    class BP_Blogs_Component extends BP_Component { 
    159267                } elseif ( bp_loggedin_user_domain() ) {
    160268                        $user_domain = bp_loggedin_user_domain();
    161269                } else {
    162                         return;
     270                        $user_domain = false;
    163271                }
    164272
    165                 $slug       = bp_get_blogs_slug();
    166                 $parent_url = trailingslashit( $user_domain . $slug );
    167 
    168                 // Add 'Sites' to the main navigation
    169                 $count    = (int) bp_get_total_blog_count_for_user();
    170                 $class    = ( 0 === $count ) ? 'no-count' : 'count';
    171                 $nav_text = sprintf( __( 'Sites <span class="%s">%s</span>', 'buddypress' ), esc_attr( $class ), bp_core_number_format( $count )  );
    172                 $main_nav = array(
    173                         'name'                => $nav_text,
    174                         'slug'                => $slug,
    175                         'position'            => 30,
    176                         'screen_function'     => 'bp_blogs_screen_my_blogs',
    177                         'default_subnav_slug' => 'my-sites',
    178                         'item_css_id'         => $this->id
    179                 );
     273                if ( ! empty( $user_domain ) ) {
     274                        $slug       = bp_get_blogs_slug();
     275                        $parent_url = trailingslashit( $user_domain . $slug );
     276
     277                        // Add 'Sites' to the main navigation
     278                        $count    = (int) bp_get_total_blog_count_for_user();
     279                        $class    = ( 0 === $count ) ? 'no-count' : 'count';
     280                        $nav_text = sprintf( __( 'Sites <span class="%s">%s</span>', 'buddypress' ), esc_attr( $class ), bp_core_number_format( $count ) );
     281                        $main_nav = array(
     282                                'name'                => $nav_text,
     283                                'slug'                => $slug,
     284                                'position'            => 30,
     285                                'screen_function'     => 'bp_blogs_screen_my_blogs',
     286                                'default_subnav_slug' => 'my-sites',
     287                                'item_css_id'         => $this->id
     288                        );
    180289
    181                 $sub_nav[] = array(
    182                         'name'            => __( 'My Sites', 'buddypress' ),
    183                         'slug'            => 'my-sites',
    184                         'parent_url'      => $parent_url,
    185                         'parent_slug'     => $slug,
    186                         'screen_function' => 'bp_blogs_screen_my_blogs',
    187                         'position'        => 10
    188                 );
     290                        $sub_nav[] = array(
     291                                'name'            => __( 'My Sites', 'buddypress' ),
     292                                'slug'            => 'my-sites',
     293                                'parent_url'      => $parent_url,
     294                                'parent_slug'     => $slug,
     295                                'screen_function' => 'bp_blogs_screen_my_blogs',
     296                                'position'        => 10
     297                        );
     298
     299                        if ( bp_is_active( $this->id, 'blog' ) ) {
     300                                $sub_nav[] = array(
     301                                        'name'            => __( 'My Subscriptions', 'buddypress' ),
     302                                        'slug'            => 'my-subscriptions',
     303                                        'parent_url'      => $parent_url,
     304                                        'parent_slug'     => $slug,
     305                                        'screen_function' => 'bp_blogs_screen_my_blogs',
     306                                        'position'        => 20
     307                                );
     308                        }
     309                }
    189310
    190311                // Setup navigation
    191312                parent::setup_nav( $main_nav, $sub_nav );
     313
     314                // Build the blog navigation
     315                if ( bp_is_blogs_component() && bp_is_single_item() ) {
     316
     317                        $item_main_nav = array( 'blog_home' => array(
     318                                        'name'                => __( 'Home', 'buddypress' ),
     319                                        'slug'                => 'home',
     320                                        'position'            => 0,
     321                                        'screen_function'     => 'bp_blogs_blog_screen_blog_home',
     322                                        'default_subnav_slug' => false,
     323                                ),
     324                        );
     325
     326                        if ( bp_blogs_blog_current_blog_has_access() ) {
     327                                // Fix the scope for Ajax filtering when members is the home page
     328                                $item_main_nav['blog_home']['item_css_id'] = 'members';
     329
     330                                if ( $this->current_blog->front_template || ( bp_is_active( 'activity' ) && bp_blogs_blog_current_blog_is_public() ) ) {
     331                                        /**
     332                                         * Only add the members nav if it's not the home's nav
     333                                         */
     334                                        $item_main_nav[] = array(
     335                                                'name'                => sprintf( _x( 'Members <span>%s</span>', 'Single Blog members screen nav', 'buddypress' ), $this->current_blog->total_member_count ),
     336                                                'slug'                => 'members',
     337                                                'position'            => 20,
     338                                                'screen_function'     => 'bp_blogs_blog_screen_blog_home',
     339                                                'default_subnav_slug' => false,
     340                                        );
     341
     342                                        // Default scope is home
     343                                        $item_main_nav['blog_home']['item_css_id'] = 'home';
     344
     345                                        /**
     346                                         * If the theme is using a custom front, create
     347                                         * an activity nav if the blog is public
     348                                         */
     349                                        if ( $this->current_blog->front_template && bp_is_active( 'activity' ) && bp_blogs_blog_current_blog_is_public() ) {
     350                                                $item_main_nav[] = array(
     351                                                        'name'                => _x( 'Activity', 'Single Blog activity screen nav', 'buddypress' ),
     352                                                        'slug'                => 'activity',
     353                                                        'position'            => 10,
     354                                                        'screen_function'     => 'bp_blogs_blog_screen_blog_home',
     355                                                        'default_subnav_slug' => false,
     356                                                );
     357                                        }
     358                                }
     359
     360                                // Manage Main nav
     361                                $item_main_nav[] = array(
     362                                        'name'                => _x( 'Manage', 'Single Blog manage screen nav', 'buddypress' ),
     363                                        'slug'                => 'manage',
     364                                        'position'            => 1000,
     365                                        'screen_function'     => 'bp_blogs_blog_screen_blog_settings',
     366                                        'default_subnav_slug' => 'manage',
     367                                        'item_admin_only'     => true,
     368                                );
     369                        }
     370
     371                        /** Sub nav items - only manage needs some for now */
     372                        $blog_link     = trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . '/'. $this->current_blog->slug );
     373
     374                        /**
     375                         * General settings
     376                         *
     377                         * Edit the preferences for the current blog
     378                         * Access is restricted to The blog admins
     379                         */
     380                        $item_sub_nav = array( array(
     381                                'name'              => _x( 'Settings', 'Single Blog setting screen', 'buddypress' ),
     382                                'slug'              => 'manage',
     383                                'parent_url'        => trailingslashit( $blog_link . 'manage' ),
     384                                'parent_slug'       => 'manage',
     385                                'screen_function'   => 'bp_blogs_blog_screen_blog_settings',
     386                                'position'          => 0,
     387                                'item_admin_only'   => true,
     388                                'show_in_admin_bar' => true,
     389                        ) );
     390
     391                        /**
     392                         * Site logo
     393                         *
     394                         * Edit the logo for the current blog
     395                         * Access is restricted to The blog admins
     396                         */
     397                        if ( bp_blogs_blog_is_avatar_uploads_enabled() ) {
     398                                $item_sub_nav[] = array(
     399                                        'name'              => _x( 'Logo', 'Single Blog photo screen', 'buddypress' ),
     400                                        'slug'              => 'edit-logo',
     401                                        'parent_url'        => trailingslashit( $blog_link . 'manage' ),
     402                                        'parent_slug'       => 'manage',
     403                                        'screen_function'   => 'bp_blogs_blog_screen_blog_settings',
     404                                        'position'          => 10,
     405                                        'item_admin_only'   => true,
     406                                        'show_in_admin_bar' => true,
     407                                );
     408                        }
     409
     410                        /**
     411                         * Manage members (remove)
     412                         */
     413                        $item_sub_nav[] = array(
     414                                'name'              => _x( 'Subscribers', 'Single Blog manage subscribers screen', 'buddypress' ),
     415                                'slug'              => 'members',
     416                                'parent_url'        => trailingslashit( $blog_link . 'manage' ),
     417                                'parent_slug'       => 'manage',
     418                                'screen_function'   => 'bp_blogs_blog_screen_blog_settings',
     419                                'position'          => 20,
     420                                'item_admin_only'   => true,
     421                                'show_in_admin_bar' => true,
     422                        );
     423
     424                        // Finally setup the blogs single item nav
     425                        if ( is_a( $this->nav, 'BP_Single_Item_Navigation' ) ) {
     426                                $this->nav->setup_nav( $item_main_nav, $item_sub_nav );
     427                        }
     428                }
    192429        }
    193430
    194431        /**
    class BP_Blogs_Component extends BP_Component { 
    234471                                'href'   => $blogs_link
    235472                        );
    236473
     474                        if ( bp_is_active( $this->id, 'blog' ) ) {
     475                                $wp_admin_nav[] = array(
     476                                        'parent' => 'my-account-' . $this->id,
     477                                        'id'     => 'my-account-' . $this->id . '-my-subscriptions',
     478                                        'title'  => __( 'My Subscriptions', 'buddypress' ),
     479                                        'href'   => trailingslashit( $blogs_link . 'my-subscriptions' )
     480                                );
     481                        }
     482
    237483                        // Create a Site
    238484                        if ( bp_blog_signup_enabled() ) {
    239485                                $wp_admin_nav[] = array(
    class BP_Blogs_Component extends BP_Component { 
    261507                                if ( bp_is_active( 'xprofile' ) ) {
    262508                                        $bp->bp_options_title = __( 'My Sites', 'buddypress' );
    263509                                }
     510                        // We are viewing a single blog, so set up the
     511                        // blog title tag using the $this->current_blog global.
     512                        } elseif ( bp_is_single_item() ) {
     513                                $bp->bp_options_title  = $this->current_blog->name;
     514                                $bp->bp_options_avatar = bp_core_fetch_avatar( array(
     515                                        'item_id'    => $this->current_blog->blog_id,
     516                                        'object'     => 'blog',
     517                                        'type'       => 'thumb',
     518                                        'avatar_dir' => 'blog-avatars',
     519                                        'alt'        => __( 'Site logo', 'buddypress' )
     520                                ) );
     521
     522                                if ( empty( $bp->bp_options_avatar ) ) {
     523                                        $bp->bp_options_avatar = '<img src="' . esc_url( bp_core_avatar_default_thumb() ) . '" alt="' . esc_attr__( 'No Site logo', 'buddypress' ) . '" class="avatar" />';
     524                                }
    264525
    265526                        // If we are not viewing the logged in user, set up the current
    266527                        // users avatar and name
    class BP_Blogs_Component extends BP_Component { 
    286547
    287548                // Global groups
    288549                wp_cache_add_global_groups( array(
    289                         'blog_meta'
     550                        'blog_meta',
     551                        'bp_blogs'
    290552                ) );
    291553
    292554                parent::setup_cache_groups();
    class BP_Blogs_Component extends BP_Component { 
    326588                $params->admin_filter    = __( 'New post published', 'buddypress' );
    327589                $params->format_callback = 'bp_blogs_format_activity_action_new_blog_post';
    328590                $params->front_filter    = __( 'Posts', 'buddypress' );
    329                 $params->contexts        = array( 'activity', 'member' );
     591                $params->contexts        = array( 'activity', 'member', 'blog', 'member_blogs' );
    330592                $params->position        = 5;
    331593
    332594                return $params;
    333595        }
     596
     597        /**
     598         * Sort the current blog's nav
     599         *
     600         * @since BuddyPress (2.4.0)
     601         */
     602        public function sort_single_item_nav() {
     603                bp_core_sort_nav_items( $this->id );
     604                bp_core_sort_subnav_items( $this->id );
     605        }
    334606}
    335607
    336608/**
  • src/bp-blogs/bp-blogs-notifications.php

    diff --git src/bp-blogs/bp-blogs-notifications.php src/bp-blogs/bp-blogs-notifications.php
    index e69de29..aa9604b 100644
     
     1<?php
     2
     3/**
     4 * BuddyPress Blogs Notification Functions
     5 *
     6 * These functions handle the recording, deleting and formatting of notifications
     7 * for the user and for this specific component.
     8 *
     9 * @package BuddyPress
     10 * @subpackage BlogsNotifications
     11 */
     12
     13// Exit if accessed directly
     14defined( 'ABSPATH' ) || exit;
     15
     16/**
     17 * Notify Site admins about a new subscription.
     18 *
     19 * @since BuddyPress (2.4.0)
     20 *
     21 * @param int           $subscriber_id ID of the user who subscribed to a site.
     22 * @param BP_Blogs_Blog $blog Blog object the user subscribed to
     23 * @return bool|null False on failure.
     24 */
     25function bp_blogs_notification_new_subscription( $subscriber_id = 0, $blog = null ) {
     26        if ( ! is_a( $blog, 'BP_Blogs_Blog' ) || empty( $subscriber_id ) ) {
     27                return;
     28        }
     29
     30        if ( empty( $blog->admins ) ) {
     31                return;
     32        }
     33
     34        // List of notified admins
     35        $admins_notified = array();
     36
     37        foreach ( $blog->admins as $admin ) {
     38
     39                // Trigger a BuddyPress Notification
     40                if ( bp_is_active( 'notifications' ) ) {
     41                        bp_notifications_add_notification( array(
     42                                'user_id'           => $admin->ID,
     43                                'item_id'           => $blog->blog_id,
     44                                'secondary_item_id' => $subscriber_id,
     45                                'component_name'    => buddypress()->blogs->id,
     46                                'component_action'  => 'new_site_subscription'
     47                        ) );
     48                }
     49
     50                // Bail if member opted out of receiving this email
     51                if ( 'no' === bp_get_user_meta( $admin->ID, 'notification_blogs_new_subscription', true ) ) {
     52                        return false;
     53                }
     54
     55                // Username of the subscriber: %1$s in mail
     56                $subscriber_user_name = bp_core_get_user_displayname( $subscriber_id );
     57
     58                // Blog's Manage members page
     59                $manage_members = trailingslashit( bp_blogs_blog_get_view_details_link() . 'manage/members' );
     60
     61                // Link to the user's profile who subscribed: %3$s in mail
     62                $subscriber_profile_link = bp_core_get_user_domain( $subscriber_id );
     63
     64                $settings_slug  = function_exists( 'bp_get_settings_slug' ) ? bp_get_settings_slug() : 'settings';
     65                // Link to the site administrator email settings: %s in "disable notifications" part of the email
     66                $settings_link  = bp_core_get_user_domain( $admin->ID ) . $settings_slug . '/notifications/';
     67
     68                // Set up and send the message
     69                $to       = $admin->user_email;
     70                $subject  = bp_get_email_subject( array( 'text' => sprintf( __( 'New subscription for the site: %s', 'buddypress' ), $blog->name ) ) );
     71
     72                $message = sprintf( __(
     73'%1$s subscribed to the site "%2$s".
     74
     75Because you are the administrator of this site, you are receiving this notification.
     76
     77To manage the members of your site, please visit:
     78%3$s
     79
     80To view %4$s\'s profile: %5$s
     81
     82---------------------
     83', 'buddypress' ), $subscriber_user_name, $blog->name, $manage_members, $subscriber_user_name, $subscriber_profile_link );
     84
     85                // Only show the disable notifications line if the settings component is enabled
     86                if ( bp_is_active( 'settings' ) ) {
     87                        $message .= sprintf( __( 'To disable these notifications please log in and go to: %s', 'buddypress' ), $settings_link );
     88                }
     89
     90                /**
     91                 * Filters the user email that the site subscription notification will be sent to.
     92                 *
     93                 * @since BuddyPress (2.4.0)
     94                 *
     95                 * @param string $to User email the notification is being sent to.
     96                 */
     97                $to = apply_filters( 'bp_blogs_notification_new_site_subscription_to', $to );
     98
     99                /**
     100                 * Filters the site subscription email subject that will be sent to user.
     101                 *
     102                 * @since BuddyPress (2.4.0)
     103                 *
     104                 * @param string          $subject site subscription email subject text.
     105                 * @param BP_Blogs_Blog   $blog    Object holding the current blog instance. Passed by reference.
     106                 */
     107                $subject = apply_filters_ref_array( 'bp_blogs_notification_new_site_subscription_subject', array( $subject, $blog ) );
     108
     109                /**
     110                 * Filters the site subscription notification message that will be sent to user.
     111                 *
     112                 * @since BuddyPress (2.4.0)
     113                 *
     114                 * @param string          $message                 Email message text.
     115                 * @param BP_Blogs_Blog   $blog                    Object holding the current blog instance. Passed by reference.
     116                 * @param string          $subscriber_user_name    Username of who subscribed.
     117                 * @param string          $subscriber_profile_link URL permalink for the profile for the user requesting membership.
     118                 * @param string          $manage_members          URL permalink for the Blog's Manage members page
     119                 * @param string          $settings_link           URL permalink for the user's notification settings area.
     120                 */
     121                $message = apply_filters_ref_array( 'bp_blogs_notification_new_site_subscription_message', array( $message, $blog, $subscriber_user_name, $subscriber_profile_link, $manage_members, $settings_link ) );
     122
     123                if ( wp_mail( $to, $subject, $message ) ) {
     124                        $admins_notified[] = $admin;
     125                }
     126        }
     127
     128        /**
     129         * Fires after the notification is sent that a member subscribed to a site.
     130         *
     131         * @since BuddyPress (2.4.0)
     132         *
     133         * @param array         $admins_notified     list of Admin objects (ID, display name, user_login, user_nicename, user_email)
     134         *                                           who were notified
     135         * @param string        $subject             Email notification subject text.
     136         * @param string        $message             Email notification message text.
     137         * @param int           $subscriber_id       ID of the user who subscribed.
     138         * @param BP_Blogs_Blog $blog                Object holding the current blog instance. Passed by reference.
     139         */
     140        do_action( 'bp_blogs_new_subscription_sent_email', $admins_notified, $subject, $message, $subscriber_id, $blog );
     141}
     142add_action( 'bp_blogs_blog_joined_blog', 'bp_blogs_notification_new_subscription', 10, 2 );
     143
     144/**
     145 * Format notifications for the Blogs component.
     146 *
     147 * @since BuddyPress (2.4.0)
     148 *
     149 * @param string $action            The kind of notification being rendered.
     150 * @param int    $item_id           The primary item ID.
     151 * @param int    $secondary_item_id The secondary item ID.
     152 * @param int    $total_items       The total number of messaging-related notifications
     153 *                                  waiting for the user.
     154 * @param string $format            'string' for BuddyBar-compatible notifications; 'array'
     155 *                                  for WP Toolbar. Default: 'string'.
     156 * @return string
     157 */
     158function bp_blogs_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) {
     159
     160        switch ( $action ) {
     161                case 'new_site_subscription':
     162                        $blog_id       = $item_id;
     163                        $subscriber_id = $secondary_item_id;
     164                        $amount        = 'single';
     165
     166                        // Set up the string and the filter
     167                        // Because different values are passed to the filters, we'll return the
     168                        // values inline
     169                        if ( (int) $total_items > 1 ) {
     170                                $text = sprintf( __( '%d new site subscriptions', 'buddypress' ), (int) $total_items );
     171                                $amount = 'multiple';
     172                                $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_blogs_slug() ) . '?n=1';;
     173
     174                                if ( 'string' == $format ) {
     175
     176                                        /**
     177                                         * Filters blogs multiple new subscription notification for string format.
     178                                         *
     179                                         * This is a dynamic filter that is dependent on item count and action.
     180                                         * Complete filter - bp_blogs_multiple_new_site_subscriptions_notification.
     181                                         *
     182                                         * @since BuddyPress (2.4.0)
     183                                         *
     184                                         * @param string $string            HTML anchor tag for request.
     185                                         * @param int    $total_items       Total number of membership requests.
     186                                         * @param string $text              Notification content.
     187                                         * @param string $notification_link The permalink for notification.
     188                                         */
     189                                        return apply_filters( 'bp_blogs_' . $amount . '_' . $action . 's_notification', '<a href="' . $notification_link . '" title="' . __( 'Site Subscriptions', 'buddypress' ) . '">' . $text . '</a>', $total_items, $text, $notification_link );
     190                                } else {
     191
     192                                        /**
     193                                         * Filters blogs multiple new subscription notification for any non-string format.
     194                                         *
     195                                         * This is a dynamic filter that is dependent on item count and action.
     196                                         * Complete filter - bp_blogs_multiple_new_site_subscriptions_notification.
     197                                         *
     198                                         * @since BuddyPress (2.4.0)
     199                                         *
     200                                         * @param array  $array             Array holding permalink and content for notification.
     201                                         * @param int    $total_items       Total number of membership requests.
     202                                         * @param string $text              Notification content.
     203                                         * @param string $notification_link The permalink for notification.
     204                                         */
     205                                        return apply_filters( 'bp_blogs_' . $amount . '_' . $action . 's_notification', array(
     206                                                'link' => $notification_link,
     207                                                'text' => $text
     208                                        ), $total_items, $text, $notification_link );
     209                                }
     210                        } else {
     211                                // Avoid switching blogs
     212                                $blog         = get_blog_details( (int) $blog_id, false );
     213                                $current_site = get_current_site();
     214
     215                                if ( (int) $current_site->id === (int) $blog_id ) {
     216                                        $slug = apply_filters( 'bp_blogs_get_site_slug', 'root' );
     217                                } else {
     218                                        $slug = trim( str_replace( $current_site->path, '', $blog->path ), '/' );
     219                                }
     220
     221                                $blog_link         = trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . '/' . $slug );
     222                                $blog_name         = bp_blogs_get_blogmeta( $blog_id, 'name' );
     223                                $user_fullname     = bp_core_get_user_displayname( $subscriber_id );
     224                                $text              = sprintf( __( '%1$s subscribed to the site "%2$s"', 'buddypress' ), $user_fullname, $blog_name );
     225                                $notification_link = $blog_link . 'manage/members/?n=1';
     226
     227                                if ( 'string' == $format ) {
     228
     229                                        /**
     230                                         * Filters blogs single new subscription notification for string format.
     231                                         *
     232                                         * This is a dynamic filter that is dependent on item count and action.
     233                                         * Complete filter - bp_blogs_single_new_site_subscription_notification.
     234                                         *
     235                                         * @since BuddyPress (2.4.0)
     236                                         *
     237                                         * @param string $string            HTML anchor tag for request.
     238                                         * @param string $blog_link         The permalink for the blog.
     239                                         * @param string $user_fullname     Full name of requesting user.
     240                                         * @param string $blog_name         Name of the blog.
     241                                         * @param string $text              Notification content.
     242                                         * @param string $notification_link The permalink for notification.
     243                                         */
     244                                        return apply_filters( 'bp_blogs_' . $amount . '_' . $action . '_notification', '<a href="' . $notification_link . '" title="' . sprintf( __( '%1$s subscribed to the site "%2$s"', 'buddypress' ), $user_fullname, $blog_name ) . '">' . $text . '</a>', $blog_link, $user_fullname, $blog_name, $text, $notification_link );
     245                                } else {
     246
     247                                        /**
     248                                         * Filters blogs single new subscription notification for any non-string format.
     249                                         *
     250                                         * This is a dynamic filter that is dependent on item count and action.
     251                                         * Complete filter - bp_blogs_single_new_site_subscription_notification.
     252                                         *
     253                                         * @since BuddyPress (2.4.0)
     254                                         *
     255                                         * @param array  $array             Array holding permalink and content for notification.
     256                                         * @param string $blog_link         The permalink for the blog.
     257                                         * @param string $user_fullname     Full name of requesting user.
     258                                         * @param string $blog_name         Name of the blog.
     259                                         * @param string $text              Notification content.
     260                                         * @param string $notification_link The permalink for notification.
     261                                         */
     262                                        return apply_filters( 'bp_blogs_' . $amount . '_' . $action . '_notification', array(
     263                                                'link' => $notification_link,
     264                                                'text' => $text
     265                                        ), $blog_link, $user_fullname, $blog_name, $text, $notification_link );
     266                                }
     267                        }
     268
     269                        break;
     270        }
     271
     272        /**
     273         * Fires right before returning the formatted blog notifications.
     274         *
     275         * @since BuddyPress (2.4.0)
     276         *
     277         * @param string $action            The type of notification being rendered.
     278         * @param int    $item_id           The primary item ID.
     279         * @param int    $secondary_item_id The secondary item ID.
     280         * @param int    $total_items       Total amount of items to format.
     281         */
     282        do_action( 'bp_blogs_format_notifications', $action, $item_id, $secondary_item_id, $total_items );
     283
     284        return false;
     285}
     286
     287/**
     288 * Render the blogs settings fields on the Notification Settings page.
     289 *
     290 * @since BuddyPress (2.4.0)
     291 */
     292function bp_blogs_screen_notification_settings() {
     293
     294        $new_subscription = bp_get_user_meta( bp_displayed_user_id(), 'notification_blogs_new_subscription', true );
     295
     296        // Defaults to yes
     297        if ( ! $new_subscription ) {
     298                $new_subscription  = 'yes';
     299        }
     300        ; ?>
     301
     302        <table class="notification-settings" id="blogs-notification-settings">
     303                <thead>
     304                        <tr>
     305                                <th class="icon"></th>
     306                                <th class="title"><?php _ex( 'Sites', 'Sites settings on notification settings page', 'buddypress' ) ?></th>
     307                                <th class="yes"><?php _e( 'Yes', 'buddypress' ) ?></th>
     308                                <th class="no"><?php _e( 'No', 'buddypress' )?></th>
     309                        </tr>
     310                </thead>
     311
     312                <tbody>
     313                        <tr id="blogs-notification-settings-subscription">
     314                                <td></td>
     315                                <td><?php _ex( 'A member subscribe to a site you are an administrator of', 'Sites settings on notification settings page','buddypress' ) ?></td>
     316                                <td class="yes"><input type="radio" name="notifications[notification_blogs_new_subscription]" value="yes" <?php checked( $new_subscription, 'yes', true ) ?>/></td>
     317                                <td class="no"><input type="radio" name="notifications[notification_blogs_new_subscription]" value="no" <?php checked( $new_subscription, 'no', true ) ?>/></td>
     318                        </tr>
     319
     320                        <?php
     321
     322                        /**
     323                         * Fires at the end of the available blog settings fields on Notification Settings page.
     324                         *
     325                         * @since BuddyPress (2.4.0)
     326                         */
     327                        do_action( 'bp_blogs_screen_notification_settings' ); ?>
     328
     329                </tbody>
     330        </table>
     331
     332<?php
     333}
     334add_action( 'bp_notification_settings', 'bp_blogs_screen_notification_settings', 20 );
     335
     336/**
     337 * Mark notifications read when a member views their blogs.
     338 *
     339 * @since BuddyPress (2.4.0)
     340 */
     341function bp_blogs_screen_my_blogs_mark_notifications() {
     342
     343        // Delete blog subscriptions for the user
     344        if ( isset( $_GET['n'] ) && bp_is_active( 'notifications' ) ) {
     345
     346                // Get the necessary ID's
     347                $component_id = buddypress()->blogs->id;
     348                $user_id      = bp_loggedin_user_id();
     349
     350                // Mark notifications read
     351                bp_notifications_mark_notifications_by_type( $user_id, $component_id, 'new_site_subscription' );
     352        }
     353}
     354add_action( 'bp_blogs_screen_my_blogs',  'bp_blogs_screen_my_blogs_mark_notifications', 10 );
     355
     356
     357/**
     358 * Mark notifications read when a member views the manage members screen of his site.
     359 *
     360 * @since BuddyPress (2.4.0)
     361 */
     362function bp_blogs_screen_manage_blog_members_mark_notifications() {
     363
     364        // Delete blog subscriptions for the user
     365        if ( isset( $_GET['n'] ) && bp_is_active( 'notifications' ) ) {
     366                bp_notifications_mark_notifications_by_item_id( bp_loggedin_user_id(), bp_blogs_blog_get_current_blog_id(), buddypress()->blogs->id, 'new_site_subscription' );
     367        }
     368}
     369add_action( 'bp_blogs_blog_screen_blog_settings',  'bp_blogs_screen_manage_blog_members_mark_notifications', 10 );
     370
     371/**
     372 * Delete notifications generated by a user who has been removed from the blog.
     373 *
     374 * @since BuddyPress (2.4.0)
     375 */
     376function bp_blogs_clean_notification_on_user_removed( $user_id = 0, $blog_id = 0 ) {
     377        if ( bp_is_active( 'notifications' ) && ! empty( $user_id ) && ! empty( $blog_id ) ) {
     378                bp_notifications_delete_notifications_by_item_id( false, $blog_id, buddypress()->blogs->id, 'new_site_subscription', $user_id );
     379        }
     380}
     381add_action( 'bp_blogs_remove_blog_for_user', 'bp_blogs_clean_notification_on_user_removed', 10, 2 );
     382
     383/**
     384 * Delete all notifications about a blog who was removed.
     385 *
     386 * @since BuddyPress (2.4.0)
     387 */
     388function bp_blogs_clean_all_notifications_for_blog( $blog_id = 0 ) {
     389        if ( bp_is_active( 'notifications' ) && ! empty( $blog_id ) ) {
     390                bp_notifications_delete_all_notifications_by_type( $blog_id, buddypress()->blogs->id );
     391        }
     392}
     393add_action( 'bp_blogs_remove_blog', 'bp_blogs_clean_all_notifications_for_blog', 10, 1 );
  • src/bp-blogs/bp-blogs-screens.php

    diff --git src/bp-blogs/bp-blogs-screens.php src/bp-blogs/bp-blogs-screens.php
    index 4b47ef5..99b4cb3 100644
    add_action( 'bp_screens', 'bp_blogs_screen_index', 2 ); 
    7474 * The main theme compat class for BuddyPress Blogs
    7575 *
    7676 * This class sets up the necessary theme compatibility actions to safely output
    77  * group template parts to the_title and the_content areas of a theme.
     77 * blog template parts to the_title and the_content areas of a theme.
    7878 *
    7979 * @since BuddyPress (1.7.0)
    8080 */
    class BP_Blogs_Theme_Compat { 
    9696         */
    9797        public function is_blogs() {
    9898
    99                 // Bail if not looking at a group
    100                 if ( ! bp_is_blogs_component() )
     99                // Bail if not looking at a blog
     100                if ( ! bp_is_blogs_component() ) {
    101101                        return;
     102                }
    102103
    103104                // Bail if looking at a users sites
    104                 if ( bp_is_user() )
     105                if ( bp_is_user() ) {
    105106                        return;
     107                }
    106108
    107109                // Blog Directory
    108                 if ( is_multisite() && ! bp_current_action() ) {
     110                if ( is_multisite() && ! bp_current_action() && ! bp_current_item() ) {
    109111                        bp_update_is_directory( true, 'blogs' );
    110112
    111113                        /**
    class BP_Blogs_Theme_Compat { 
    121123                        add_filter( 'bp_replace_the_content',                    array( $this, 'directory_content'    ) );
    122124
    123125                // Create blog
    124                 } elseif ( is_user_logged_in() && bp_blog_signup_enabled() ) {
     126                } elseif ( is_user_logged_in() && bp_blog_signup_enabled() && bp_is_create_blog() ) {
    125127                        add_filter( 'bp_get_buddypress_template',                array( $this, 'create_template_hierarchy' ) );
    126128                        add_action( 'bp_template_include_reset_dummy_post_data', array( $this, 'create_dummy_post' ) );
    127129                        add_filter( 'bp_replace_the_content',                    array( $this, 'create_content'    ) );
    128                 }
     130                } elseif ( bp_is_single_item() ) {
     131                        add_filter( 'bp_get_buddypress_template',                array( $this, 'single_template_hierarchy' ) );
     132                        add_action( 'bp_template_include_reset_dummy_post_data', array( $this, 'single_dummy_post' ) );
     133                        add_filter( 'bp_replace_the_content',                    array( $this, 'single_content'    ) );
     134                }
    129135        }
    130136
    131137        /** Directory *************************************************************/
    class BP_Blogs_Theme_Compat { 
    183189        }
    184190
    185191        /**
    186          * Filter the_content with the groups index template part.
     192         * Filter the_content with the blogs index template part.
    187193         *
    188194         * @since BuddyPress (1.7.0)
    189195         */
    class BP_Blogs_Theme_Compat { 
    260266        public function create_content() {
    261267                return bp_buffer_template_part( 'blogs/create', null, false );
    262268        }
     269
     270        /** Single ************************************************************/
     271
     272        /**
     273         * Add custom template hierarchy to theme compat for blog single item pages.
     274         *
     275         * This is to mirror how WordPress has
     276         * {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
     277         *
     278         * @since BuddyPress (2.4.0)
     279         *
     280         * @param string $templates The templates from bp_get_theme_compat_templates().
     281         * @return array $templates Array of custom templates to look for.
     282         */
     283        public function single_template_hierarchy( $templates ) {
     284                // Setup some variables we're going to reference in our custom templates
     285                $blog = bp_blogs_blog_get_current_blog();
     286
     287                /**
     288                 * Filters the Blogs single pages template hierarchy based on priority.
     289                 *
     290                 * @since BuddyPress (2.4.0)
     291                 *
     292                 * @param array $value Array of default template files to use.
     293                 */
     294                $new_templates = apply_filters( 'bp_template_hierarchy_blogs_single_item', array(
     295                        'blogs/single/index-id-'     . sanitize_file_name( $blog->blog_id )      . '.php',
     296                        'blogs/single/index-slug-'   . sanitize_file_name( $blog->slug )         . '.php',
     297                        'blogs/single/index-action-' . sanitize_file_name( bp_current_action() ) . '.php',
     298                        'blogs/single/index.php'
     299                ) );
     300
     301                // Merge new templates with existing stack
     302                // @see bp_get_theme_compat_templates()
     303                $templates = array_merge( (array) $new_templates, $templates );
     304
     305                return $templates;
     306        }
     307
     308        /**
     309         * Update the global $post with single blog data.
     310         *
     311         * @since BuddyPress (2.4.0)
     312         */
     313        public function single_dummy_post() {
     314                bp_theme_compat_reset_post( array(
     315                        'ID'             => 0,
     316                        'post_title'     => bp_blogs_blog_get_current_blog_name(),
     317                        'post_author'    => 0,
     318                        'post_date'      => 0,
     319                        'post_content'   => '',
     320                        'post_type'      => 'page',
     321                        'post_status'    => 'publish',
     322                        'is_page'        => true,
     323                        'comment_status' => 'closed'
     324                ) );
     325        }
     326
     327        /**
     328         * Filter the_content with the single blog template part.
     329         *
     330         * @since BuddyPress (2.4.0)
     331         */
     332        public function single_content() {
     333                return bp_buffer_template_part( 'blogs/single/home', null, false );
     334        }
    263335}
    264336new BP_Blogs_Theme_Compat();
  • src/bp-blogs/bp-blogs-template.php

    diff --git src/bp-blogs/bp-blogs-template.php src/bp-blogs/bp-blogs-template.php
    index d0851fd..459fdce 100644
    class BP_Blogs_Template { 
    190190         * @param string $per_page See {@link BP_Blogs_Blog::get()}.
    191191         * @param string $max See {@link BP_Blogs_Blog::get()}.
    192192         * @param string $user_id See {@link BP_Blogs_Blog::get()}.
     193         * @param false|int $user_level whether to get all|only subscriber (0)
     194         *                              or only contributors (1)
    193195         * @param string $search_terms See {@link BP_Blogs_Blog::get()}.
    194196         * @param string $page_arg The string used as a query parameter in
    195197         *        pagination links. Default: 'bpage'.
    196198         * @param bool $update_meta_cache Whether to pre-fetch metadata for
    197199         *        queried blogs.
    198200         * @param array $include_blog_ids Array of blog IDs to include.
     201         * @param string $slug the slug of the blogs single item to get
    199202         */
    200         public function __construct( $type, $page, $per_page, $max, $user_id, $search_terms, $page_arg = 'bpage', $update_meta_cache = true, $include_blog_ids = false ) {
     203        public function __construct( $type, $page, $per_page, $max, $user_id, $user_level = false, $search_terms, $page_arg = 'bpage', $update_meta_cache = true, $include_blog_ids = false, $slug = '' ) {
    201204
    202205                $this->pag_arg  = sanitize_key( $page_arg );
    203206                $this->pag_page = bp_sanitize_pagination_arg( $this->pag_arg, $page     );
    204207                $this->pag_num  = bp_sanitize_pagination_arg( 'num',          $per_page );
    205208
     209                // A blog item is requested
     210                if ( bp_is_active( 'blogs', 'blog' ) && 'single-blog' === $type ) {
     211                        if ( bp_blogs_blog_get_current_blog() ) {
     212                                $blog = bp_blogs_blog_get_current_blog();
     213
     214                        } else {
     215                                $blog = bp_blogs_blog_get_blog( array(
     216                                        'blog_id' => get_id_from_blogname( $slug ),
     217                                ) );
     218                        }
     219
     220                        $this->blogs = array( $blog );
    206221                // Backwards compatibility support for blogs by first letter
    207                 if ( ! empty( $_REQUEST['letter'] ) ) {
     222                } elseif ( ! empty( $_REQUEST['letter'] ) ) {
    208223                        $this->blogs = BP_Blogs_Blog::get_by_letter( $_REQUEST['letter'], $this->pag_num, $this->pag_page );
    209224
    210225                // Typical blogs query
    class BP_Blogs_Template { 
    214229                                'per_page'          => $this->pag_num,
    215230                                'page'              => $this->pag_page,
    216231                                'user_id'           => $user_id,
     232                                'user_level'        => $user_level,
    217233                                'search_terms'      => $search_terms,
    218234                                'update_meta_cache' => $update_meta_cache,
    219235                                'include_blog_ids'  => $include_blog_ids,
    220236                        ) );
    221237                }
    222238
    223                 // Set the total blog count
    224                 if ( empty( $max ) || ( $max >= (int) $this->blogs['total'] ) ) {
    225                         $this->total_blog_count = (int) $this->blogs['total'];
     239                if ( 'single-blog' === $type ) {
     240                        if ( empty( $blog->blog_id ) ) {
     241                                $this->total_blog_count = 0;
     242                                $this->blog_count       = 0;
     243                        } else {
     244                                $this->total_blog_count = 1;
     245                                $this->blog_count       = 1;
     246                        }
     247
    226248                } else {
    227                         $this->total_blog_count = (int) $max;
    228                 }
     249                        // Set the total blog count
     250                        if ( empty( $max ) || ( $max >= (int) $this->blogs['total'] ) ) {
     251                                $this->total_blog_count = (int) $this->blogs['total'];
     252                        } else {
     253                                $this->total_blog_count = (int) $max;
     254                        }
    229255
    230                 // Set the blogs array (to loop through later
    231                 $this->blogs = $this->blogs['blogs'];
     256                        // Set the blogs array (to loop through later
     257                        $this->blogs = $this->blogs['blogs'];
    232258
    233                 // Get the current blog count to compare maximum against
    234                 $blog_count = count( $this->blogs );
     259                        // Get the current blog count to compare maximum against
     260                        $blog_count = count( $this->blogs );
    235261
    236                 // Set the current blog count
    237                 if ( empty( $max ) || ( $max >= (int) $blog_count ) ) {
    238                         $this->blog_count = (int) $blog_count;
    239                 } else {
    240                         $this->blog_count = (int) $max;
     262                        // Set the current blog count
     263                        if ( empty( $max ) || ( $max >= (int) $blog_count ) ) {
     264                                $this->blog_count = (int) $blog_count;
     265                        } else {
     266                                $this->blog_count = (int) $max;
     267                        }
    241268                }
    242269
    243270                // Build pagination links based on total blogs and current page number
    function bp_rewind_blogs() { 
    395422function bp_has_blogs( $args = '' ) {
    396423        global $blogs_template;
    397424
     425        $type         = 'active';
     426        $slug         = '';
     427        $current_blog = '';
     428        $user_level   = false;
     429
     430        if ( bp_is_active( 'blogs', 'blog' ) ) {
     431                $current_blog = bp_blogs_blog_get_current_blog();
     432
     433                if ( bp_is_user() ) {
     434                        // Defaults to blogs the user is a contributor of
     435                        $user_level = 1;
     436
     437                        // On the My Subscriptions screen, blogs the user is a subsriber of
     438                        if ( bp_is_current_action( 'my-subscriptions' ) ) {
     439                                $user_level = 0;
     440                        }
     441                }
     442        }
     443
     444        if ( ! empty( $current_blog ) ) {
     445                $type = 'single-blog';
     446                $slug = bp_blogs_blog_get_current_blog_slug();
     447        }
     448
    398449        // Check for and use search terms
    399450        $search_terms = ! empty( $_REQUEST['s'] )
    400451                ? $_REQUEST['s']
    function bp_has_blogs( $args = '' ) { 
    402453
    403454        // Parse arguments
    404455        $r = bp_parse_args( $args, array(
    405                 'type'              => 'active',
     456                'type'              => $type,
    406457                'page_arg'          => 'bpage',                // See https://buddypress.trac.wordpress.org/ticket/3679
    407458                'page'              => 1,
    408459                'per_page'          => 20,
    409460                'max'               => false,
    410461                'user_id'           => bp_displayed_user_id(), // Pass a user_id to limit to only blogs this user is a member of
     462                'user_level'        => $user_level,
    411463                'include_blog_ids'  => false,
    412464                'search_terms'      => $search_terms,          // Pass search terms to filter on the blog title or description.
    413                 'update_meta_cache' => true
     465                'update_meta_cache' => true,
     466                'slug'              => $slug,                  // Pass the slug of the blog in conjonction with a type set to 'single-blog'
    414467        ), 'has_blogs' );
    415468
    416469        // Set per_page to maximum if max is enforced
    function bp_has_blogs( $args = '' ) { 
    419472        }
    420473
    421474        // Get the blogs
    422         $blogs_template = new BP_Blogs_Template( $r['type'], $r['page'], $r['per_page'], $r['max'], $r['user_id'], $r['search_terms'], $r['page_arg'], $r['update_meta_cache'], $r['include_blog_ids'] );
     475        $blogs_template = new BP_Blogs_Template( $r['type'], $r['page'], $r['per_page'], $r['max'], $r['user_id'], $r['user_level'], $r['search_terms'], $r['page_arg'], $r['update_meta_cache'], $r['include_blog_ids'], $r['slug'] );
    423476
    424477        /**
    425478         * Filters whether or not there are blogs to list.
    function bp_blog_avatar( $args = '' ) { 
    555608                        'type'    => 'full',
    556609                        'width'   => false,
    557610                        'height'  => false,
    558                         'class'   => 'avatar',
     611                        'class'   => 'avatar blog-' . $blogs_template->blog->blog_id . '-avatar',
    559612                        'id'      => false,
    560613                        'alt'     => sprintf( __( 'Profile picture of site author %s', 'buddypress' ), bp_core_get_user_displayname( $blogs_template->blog->admin_user_id ) ),
    561614                        'no_grav' => true,
    562615                ) );
    563616
     617                // Defaults to the admin avatar
     618                $item_id    = $blogs_template->blog->admin_user_id;
     619                $title      = $blogs_template->blog->admin_user_email;
     620                $object     = 'user';
     621                $avatar_dir = 'avatars';
     622
     623                if ( bp_is_active( 'blogs', 'blog' ) ) {
     624                        $object     = 'blog';
     625                        $avatar_dir = 'blog-avatars';
     626                        $item_id    = $blogs_template->blog->blog_id;
     627                        $title      = $blogs_template->blog->name;
     628                        $r['class'] = 'avatar';
     629                        $r['alt']   = sprintf( __( 'Site logo of %s', 'buddypress' ), $blogs_template->blog->name );
     630                }
     631
    564632                // Fetch the avatar
    565633                $avatar = bp_core_fetch_avatar( array(
    566                         'item_id'    => $blogs_template->blog->admin_user_id,
    567                         'title'      => $blogs_template->blog->admin_user_email,
    568                         //'avatar_dir' => 'blog-avatars',
    569                         //'object'     => 'blog',
     634                        'item_id'    => $item_id,
     635                        'title'      => $title,
     636                        'avatar_dir' => $avatar_dir,
     637                        'object'     => $object,
    570638                        'type'       => $r['type'],
    571639                        'alt'        => $r['alt'],
    572640                        'css_id'     => $r['id'],
    function bp_blog_avatar( $args = '' ) { 
    576644                ) );
    577645
    578646                /***
    579                  * In future BuddyPress versions you will be able to set the avatar for a blog.
    580                  * Right now you can use a filter with the ID of the blog to change it if you wish.
    581                  * By default it will return the avatar for the primary blog admin.
    582                  *
    583647                 * This filter is deprecated as of BuddyPress 1.5 and may be removed in a future version.
    584648                 * Use the 'bp_get_blog_avatar' filter instead.
     649                 *
     650                 * @deprecated BuddyPress (2.4.0)
    585651                 */
    586652                $avatar = apply_filters( 'bp_get_blog_avatar_' . $blogs_template->blog->blog_id, $avatar );
    587653
    function bp_blogs_confirm_blog_signup( $domain, $path, $blog_title, $user_name, 
    13751441                <?php printf(__( '<a href="%1$s">%2$s</a> is your new site.  <a href="%3$s">Login</a> as "%4$s" using your existing password.', 'buddypress' ), $blog_url, $blog_url, $blog_url . "wp-login.php", $user_name ); ?>
    13761442        </p>
    13771443
    1378 <?php
     1444        <?php if ( bp_blogs_blog_is_avatar_uploads_enabled() && is_user_logged_in() ) :
     1445                $slug = trim( str_replace( get_current_site()->path, '', $path ), '/' );
     1446                $single_blog_link = trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . '/' .  $slug . '/manage/edit-logo' );
     1447        ?>
     1448                <p>
     1449                        <?php printf( __( 'You can also set a site logo for your site at any time from this <a href="%s">page</a>.', 'buddypress' ), $single_blog_link ); ?>
     1450                </p>
     1451
     1452        <?php endif;
    13791453
    13801454        /**
    13811455         * Fires after the default successful blog registration message markup.
  • src/bp-blogs/classes/class-bp-blogs-blog.php

    diff --git src/bp-blogs/classes/class-bp-blogs-blog.php src/bp-blogs/classes/class-bp-blogs-blog.php
    index 5e88b89..03772c8 100644
    class BP_Blogs_Blog { 
    2121        public $id;
    2222        public $user_id;
    2323        public $blog_id;
     24        public $is_contributor;
    2425
    2526        /**
    2627         * Constructor method.
    2728         *
    2829         * @param int $id Optional. The ID of the blog.
    2930         */
    30         public function __construct( $id = null ) {
    31                 if ( !empty( $id ) ) {
     31        public function __construct( $id = null, $args = array() ) {
     32                $this->args = wp_parse_args( $args, array(
     33                        'blog_id'         => 0,
     34                        'user_id'         => 0,
     35                        'populate_extras' => false,
     36                ) );
     37
     38                if ( ! empty( $id ) || ! empty( $this->args[ 'blog_id'] ) ) {
    3239                        $this->id = $id;
    3340                        $this->populate();
    3441                }
    class BP_Blogs_Blog { 
    4249
    4350                $bp = buddypress();
    4451
    45                 $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->blogs->table_name} WHERE id = %d", $this->id ) );
     52                // Are we getting extra blog data?
     53                if ( ! empty( $this->args['populate_extras'] ) ) {
    4654
    47                 $this->user_id = $blog->user_id;
    48                 $this->blog_id = $blog->blog_id;
     55                        // We need some of the blog details and it's a good
     56                        // way to check the blog is not moderated
     57                        $blog_details = get_blog_details( $this->args['blog_id'] );
     58
     59                        if ( empty( $blog_details ) || 1 === (int) $blog_details->mature || 1 === (int) $blog_details->spam || 1 === (int) $blog_details->archived || 1 === (int) $blog_details->deleted ) {
     60                                $this->blog_id = 0;
     61                                return;
     62                        }
     63
     64                        // Set the blog id
     65                        $this->blog_id = (int) $this->args['blog_id'];
     66
     67                        // Populating BuddyPress blog metas for the requested blog
     68                        foreach ( bp_blogs_get_blogmeta( $this->blog_id ) as $key => $meta ) {
     69                                // Don't fetch private blogmeta
     70                                if ( is_protected_meta( $key ) ) {
     71                                        continue;
     72                                }
     73
     74                                if ( count( $meta ) == 1 ) {
     75                                        $this->{$key} = maybe_unserialize( $meta[0] );
     76                                } else {
     77                                        $this->{$key} = array_map( 'maybe_unserialize', $meta );
     78                                }
     79                        }
     80
     81                        if ( ! isset( $this->url ) ) {
     82                                $this->url = $blog_details->siteurl;
     83                        }
     84
     85                        if ( ! isset( $this->name ) ) {
     86                                $this->name = $blog_details->blogname;
     87                        }
     88
     89                        // The following properties are necessary for the blogs loop
     90                        $this->path   = $blog_details->path;
     91                        $this->domain = $blog_details->domain;
     92                        $current_site = get_current_site();
     93
     94                        if ( (int) $current_site->id === (int) $this->blog_id ) {
     95                                $this->slug = bp_blogs_blog_get_site_slug();
     96                        } else {
     97                                $this->slug = trim( str_replace( $current_site->path, '', $this->path ), '/' );
     98                        }
     99
     100                        if ( bp_get_root_blog_id() !== $this->blog_id ) {
     101                                $needs_reset = true;
     102                                switch_to_blog( $this->blog_id );
     103                        }
     104
     105                        // Who are the admins ?
     106                        $this->admins = get_users( array(
     107                                'role'   => 'administrator',
     108                                'fields' => array( 'ID', 'display_name', 'user_login', 'user_nicename', 'user_email' ),
     109                        ) );
     110
     111                        $this->admin_user_id    = $this->admins[0]->ID;
     112                        $this->admin_user_email = $this->admins[0]->user_email;
     113
     114                        // How many posts ?
     115                        $this->post_count = $blog_details->post_count;
     116
     117                        // Blog visibility
     118                        $this->blog_public = $blog_details->public;
     119
     120                        /**
     121                         * Custom header, filter here to disable, or use another image than
     122                         * @var [type]
     123                         */
     124                        $this->custom_header = apply_filters( 'bp_blogs_blog_get_custom_header', get_header_image(), $this->blog_id );
     125
     126                        if ( isset( $needs_reset ) ) {
     127                                restore_current_blog();
     128                        }
     129
     130                        // How many users ?
     131                        $this->members            = bp_blogs_blog_get_users_for_blog( array( 'blog_id' => $this->blog_id ) );
     132                        $this->total_member_count = count( $this->members );
     133
     134                        $this->is_member      = false;
     135                        $this->is_contributor = false;
     136
     137                        /**
     138                         * Loop throw members to see if the logged in user is a member of the blog
     139                         * and if he's a contributor of the blog
     140                         */
     141                        foreach ( (array) $this->members as $member ) {
     142                                if ( (int) $member->user_id === (int) bp_loggedin_user_id() ) {
     143                                        $this->is_member = true;
     144
     145                                        if ( 1 === (int) $member->is_contributor ) {
     146                                                $this->is_contributor = true;
     147                                        }
     148                                }
     149                        }
     150
     151                /**
     152                 * Populate the user's blog association single row
     153                 *
     154                 * @see bp_blogs_add_user_to_blog()
     155                 */
     156                } else {
     157                        $select = "SELECT * FROM {$bp->blogs->table_name}";
     158
     159                        // Use the blog_id and the user_id
     160                        if ( ! empty( $this->args[ 'blog_id'] ) && ! empty( $this->args[ 'user_id'] ) ) {
     161                                $where = $wpdb->prepare( 'user_id = %d AND blog_id = %d', $this->args[ 'user_id'], $this->args[ 'blog_id'] );
     162
     163                        // Use the id of the association
     164                        } elseif ( ! empty( $this->id ) ) {
     165                                $where = $wpdb->prepare( 'id = %d', $this->id );
     166
     167                        // Not enough data to get the blog's row
     168                        } else {
     169                                $this->id = null;
     170                                return;
     171                        }
     172
     173                        $blog = $wpdb->get_row( "{$select} WHERE {$where}" );
     174
     175                        if ( ! empty( $blog->id ) ) {
     176                                $this->id             = (int) $blog->id;
     177                                $this->user_id        = (int) $blog->user_id;
     178                                $this->blog_id        = (int) $blog->blog_id;
     179                                $this->is_contributor = $blog->is_contributor;
     180                        }
     181                }
    49182        }
    50183
    51184        /**
    class BP_Blogs_Blog { 
    56189        public function save() {
    57190                global $wpdb;
    58191
    59                 $this->user_id = apply_filters( 'bp_blogs_blog_user_id_before_save', $this->user_id, $this->id );
    60                 $this->blog_id = apply_filters( 'bp_blogs_blog_id_before_save', $this->blog_id, $this->id );
     192                $this->user_id        = apply_filters( 'bp_blogs_blog_user_id_before_save', $this->user_id, $this->id );
     193                $this->blog_id        = apply_filters( 'bp_blogs_blog_id_before_save', $this->blog_id, $this->id );
     194                $this->is_contributor = apply_filters( 'bp_blogs_blog_is_contributor_before_save', $this->is_contributor, $this->id );
    61195
    62196                /**
    63197                 * Fires before the current blog item gets saved.
    class BP_Blogs_Blog { 
    82216
    83217                if ( $this->id ) {
    84218                        // Update
    85                         $sql = $wpdb->prepare( "UPDATE {$bp->blogs->table_name} SET user_id = %d, blog_id = %d WHERE id = %d", $this->user_id, $this->blog_id, $this->id );
     219                        $sql = $wpdb->prepare( "UPDATE {$bp->blogs->table_name} SET user_id = %d, blog_id = %d, is_contributor = %d WHERE id = %d", $this->user_id, $this->blog_id, $this->is_contributor, $this->id );
    86220                } else {
    87221                        // Save
    88                         $sql = $wpdb->prepare( "INSERT INTO {$bp->blogs->table_name} ( user_id, blog_id ) VALUES ( %d, %d )", $this->user_id, $this->blog_id );
     222                        $sql = $wpdb->prepare( "INSERT INTO {$bp->blogs->table_name} ( user_id, blog_id, is_contributor ) VALUES ( %d, %d, %d )", $this->user_id, $this->blog_id, $this->is_contributor );
    89223                }
    90224
    91225                if ( !$wpdb->query($sql) )
    class BP_Blogs_Blog { 
    135269         *        Default: false (unlimited results).
    136270         * @param int $user_id Optional. ID of the user whose blogs are being
    137271         *        retrieved. Default: 0.
     272         * @param int|bool $user_level Optional. level of the user on the blogs to
     273         *        retrieve (1 => contributor, 0 => subscriber). Default: false.
    138274         * @param string|bool $search_terms Optional. Search by text stored in
    139275         *        blogmeta (such as the blog name). Default: false.
    140276         * @param bool $update_meta_cache Whether to pre-fetch metadata for
    class BP_Blogs_Blog { 
    144280         *           'blogs' - Array of located blog objects
    145281         *           'total' - A count of the total blogs matching the filter params
    146282         */
    147         public static function get( $type, $limit = false, $page = false, $user_id = 0, $search_terms = false, $update_meta_cache = true, $include_blog_ids = false ) {
     283        public static function get( $type, $limit = false, $page = false, $user_id = 0, $user_level = false, $search_terms = false, $update_meta_cache = true, $include_blog_ids = false ) {
    148284                global $wpdb;
    149285
    150286                $bp = buddypress();
    class BP_Blogs_Blog { 
    187323                        $search_terms_sql = '';
    188324                }
    189325
     326                // Defaults to all blogs for user
     327                $user_level_sql = '';
     328
     329                /**
     330                 * Force the user level to be contributor if the blog
     331                 * single items feature is disabled
     332                 */
     333                if ( ! bp_is_active( 'blogs', 'blog' ) ) {
     334                        $user_level = 1;
     335                }
     336
     337                if ( false !== $user_level ) {
     338                        $user_level_sql = $wpdb->prepare( 'AND b.is_contributor = %d', $user_level );
     339                }
     340
    190341                $paged_blogs = $wpdb->get_results( "
    191342                        SELECT b.blog_id, b.user_id as admin_user_id, u.user_email as admin_user_email, wb.domain, wb.path, bm.meta_value as last_activity, bm_name.meta_value as name
    192343                        FROM
    class BP_Blogs_Blog { 
    199350                        WHERE
    200351                          wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql}
    201352                          AND bm.meta_key = 'last_activity' AND bm_name.meta_key = 'name' AND bm_description.meta_key = 'description'
    202                           {$search_terms_sql} {$user_sql} {$include_sql}
     353                          {$search_terms_sql} {$user_sql} {$user_level_sql} {$include_sql}
    203354                        GROUP BY b.blog_id {$order_sql} {$pag_sql}
    204355                " );
    205356
    class BP_Blogs_Blog { 
    214365                          wb.archived = '0' AND wb.spam = 0 AND wb.mature = 0 AND wb.deleted = 0 {$hidden_sql}
    215366                          AND
    216367                          bm_name.meta_key = 'name' AND bm_description.meta_key = 'description'
    217                           {$search_terms_sql} {$user_sql} {$include_sql}
     368                          {$search_terms_sql} {$user_sql} {$user_level_sql} {$include_sql}
    218369                " );
    219370
    220371                $blog_ids = array();
    class BP_Blogs_Blog { 
    241392                global $wpdb;
    242393
    243394                bp_blogs_delete_blogmeta( $blog_id );
    244                
     395
    245396                $bp = buddypress();
    246397
    247398                return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name} WHERE blog_id = %d", $blog_id ) );
    class BP_Blogs_Blog { 
    376527         *        queried. Defaults to logged-in user.
    377528         * @return int Blog count for the user.
    378529         */
    379         public static function total_blog_count_for_user( $user_id = null ) {
     530        public static function total_blog_count_for_user( $user_id = null, $is_contributor = false ) {
    380531                global $wpdb;
    381532
    382533                $bp = buddypress();
    383534
    384                 if ( !$user_id )
     535                if ( ! $user_id ) {
    385536                        $user_id = bp_displayed_user_id();
     537                }
     538
     539                $sql = array(
     540                        'select'  => "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b LEFT JOIN {$wpdb->base_prefix}blogs wb ON b.blog_id = wb.blog_id",
     541                        'where'   => array( $wpdb->prepare( "wb.deleted = 0 AND wb.spam = 0 AND wb.mature = 0 AND wb.archived = '0' AND user_id = %d", $user_id ) ),
     542                );
     543
     544                if ( ! is_user_logged_in() && (int) $user_id !== (int) bp_loggedin_user_id() && ! bp_current_user_can( 'bp_moderate' ) ) {
     545                        $sql['where'][] = 'wb.public = 1';
     546                }
     547
     548                /**
     549                 * Force to blogs the user is contributing to if the blog
     550                 * single items feature is disabled
     551                 */
     552                if ( ! bp_is_active( 'blogs', 'blog' ) ) {
     553                        $is_contributor = 1;
     554                }
     555
     556                if ( false !== $is_contributor ) {
     557                        $sql['where'][] = $wpdb->prepare( 'b.is_contributor = %d', $is_contributor );
     558                }
     559
     560                // Build the where part of the query
     561                $sql['where'] = 'WHERE ' . implode( ' AND ', $sql['where'] );
     562
     563                return $wpdb->get_var( "{$sql['select']} {$sql['where']}" );
    386564
    387565                // If the user is logged in return the blog count including their hidden blogs.
    388566                if ( ( is_user_logged_in() && $user_id == bp_loggedin_user_id() ) || bp_current_user_can( 'bp_moderate' ) ) {
    class BP_Blogs_Blog { 
    605783
    606784                return $user_blog;
    607785        }
     786
     787        /**
     788         * List members of a blog
     789         *
     790         * @since BuddyPress ( 2.4.0 )
     791         *
     792         * @param int $blog_id ID of blog.
     793         * @param int|bool 0 to get only subscribers, 1 to get only contributors, false to get all
     794         * @return array of blog members object
     795         */
     796        public static function get_users_for_blog( $blog_id, $is_contributor = false ) {
     797                global $wpdb;
     798
     799                $bp = buddypress();
     800
     801                $sql = array(
     802                        'select'  => "SELECT * FROM {$bp->blogs->table_name}",
     803                        'where'   => array( $wpdb->prepare( "blog_id = %d", $blog_id ) ),
     804                );
     805
     806                if ( false !== $is_contributor ) {
     807                        $sql['where'][] = $wpdb->prepare( "is_contributor = %d", $is_contributor );
     808                }
     809
     810                // Build the where part of the query
     811                $sql['where'] = 'WHERE ' . implode( ' AND ', $sql['where'] );
     812
     813                return $wpdb->get_results( "{$sql['select']} {$sql['where']}" );
     814        }
    608815}
  • src/bp-core/admin/bp-core-admin-schema.php

    diff --git src/bp-core/admin/bp-core-admin-schema.php src/bp-core/admin/bp-core-admin-schema.php
    index 9aa6b60..d8c7b8c 100644
    function bp_core_install_blog_tracking() { 
    437437                                id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    438438                                user_id bigint(20) NOT NULL,
    439439                                blog_id bigint(20) NOT NULL,
     440                                is_contributor tinyint(1) NOT NULL DEFAULT '1',
    440441                                KEY user_id (user_id),
    441                                 KEY blog_id (blog_id)
     442                                KEY blog_id (blog_id),
     443                                KEY is_contributor (is_contributor)
    442444                        ) {$charset_collate};";
    443445
    444446        $sql[] = "CREATE TABLE {$bp_prefix}bp_user_blogs_blogmeta (
  • src/bp-core/admin/bp-core-admin-settings.php

    diff --git src/bp-core/admin/bp-core-admin-settings.php src/bp-core/admin/bp-core-admin-settings.php
    index 8b02f4f..6fbe033 100644
    function bp_admin_setting_callback_group_avatar_uploads() { 
    194194<?php
    195195}
    196196
     197/** Blogs Section ************************************************************/
     198
     199/**
     200 * Blogs settings section description for the settings page
     201 *
     202 * @since BuddyPress (2.4.0)
     203 */
     204function bp_admin_setting_callback_blogs_section() { }
     205
     206/**
     207 * Disable the Blogs single items
     208 *
     209 * @since BuddyPress (2.4.0)
     210 *
     211 * @uses checked() To display the checked attribute
     212 */
     213function bp_admin_setting_callback_blog_avatar_uploads() {
     214?>
     215
     216        <input id="bp-disable-blog-avatar-uploads" name="bp-disable-blog-avatar-uploads" type="checkbox" value="1" <?php checked( ! bp_blogs_blog_disable_avatar_uploads() ); ?> />
     217        <label for="bp-disable-blog-avatar-uploads"><?php _e( 'Allow customizable avatars for sites', 'buddypress' ); ?></label>
     218<?php
     219}
     220
    197221/** Forums Section ************************************************************/
    198222
    199223/**
    function bp_core_admin_settings_save() { 
    297321                        'bp-disable-account-deletion',
    298322                        'bp-disable-avatar-uploads',
    299323                        'bp-disable-group-avatar-uploads',
     324                        'bp-disable-blog-avatar-uploads',
    300325                        'bp_disable_blogforum_comments',
    301326                        'bp-disable-profile-sync',
    302327                        'bp_restrict_group_creation',
  • src/bp-core/admin/bp-core-admin-tools.php

    diff --git src/bp-core/admin/bp-core-admin-tools.php src/bp-core/admin/bp-core-admin-tools.php
    index 7b426ae..871f0ed 100644
    function bp_admin_repair_blog_records() { 
    277277        // Default to unrepaired
    278278        $repair    = false;
    279279
     280        /**
     281         * To completely reset the users/blogs association
     282         * the Blog single item feature needs to be disabled.
     283         * This is to avoid removing blogs subscriptions.
     284         */
     285        $reset = ! bp_is_active( 'blogs', 'blog' );
     286
    280287        // Run function if blogs component is active
    281288        if ( bp_is_active( 'blogs' ) ) {
    282                 $repair = bp_blogs_record_existing_blogs();
     289                $repair = bp_blogs_record_existing_blogs( $reset );
    283290        }
    284291
    285292        // Setup success/fail messaging
  • src/bp-core/bp-core-admin.php

    diff --git src/bp-core/bp-core-admin.php src/bp-core/bp-core-admin.php
    index 94b7a13..065247a 100644
    class BP_Admin { 
    395395                                register_setting( 'buddypress', '_bp_enable_akismet', 'intval' );
    396396                        }
    397397                }
     398
     399                /** Blogs Section ****************************************************/
     400
     401                if ( bp_is_active( 'blogs', 'blog' ) && is_multisite() ) {
     402
     403                        // Add the main section
     404                        add_settings_section( 'bp_blogs', __( 'Sites Settings',  'buddypress' ), 'bp_admin_setting_callback_blogs_section', 'buddypress' );
     405
     406                        // Allow subscriptions setting
     407                        add_settings_field( 'bp-disable-blog-avatar-uploads', __( 'Site Photo Uploads', 'buddypress' ), 'bp_admin_setting_callback_blog_avatar_uploads', 'buddypress', 'bp_blogs' );
     408                        register_setting  ( 'buddypress', 'bp-disable-blog-avatar-uploads', 'intval' );
     409                }
    398410        }
    399411
    400412        /**
  • src/bp-core/bp-core-attachments.php

    diff --git src/bp-core/bp-core-attachments.php src/bp-core/bp-core-attachments.php
    index 3156e8b..a7a4e95 100644
    function bp_attachments_current_user_can( $capability, $args = array() ) { 
    328328                        // User profile photo
    329329                        } elseif ( bp_is_active( 'xprofile' ) && 'user' === $args['object'] ) {
    330330                                $can = bp_loggedin_user_id() === (int) $args['item_id'] || bp_current_user_can( 'bp_moderate' );
     331                        // Site logo
     332                        } elseif ( bp_is_active( 'blogs' ) && 'blog' === $args['object'] ) {
     333                                $can = current_user_can_for_blog( (int) $args['item_id'], 'manage_options' );
    331334                        }
    332335                /**
    333336                 * No avatar arguments, fallback to bp_user_can_create_groups()
  • src/bp-core/bp-core-avatars.php

    diff --git src/bp-core/bp-core-avatars.php src/bp-core/bp-core-avatars.php
    index bef7735..edff737 100644
    function bp_core_fetch_avatar( $args = '' ) { 
    213213                switch ( $params['object'] ) {
    214214
    215215                        case 'blog'  :
    216                                 $params['item_id'] = $current_blog->id;
     216                                if ( bp_is_active( 'blogs', 'blog' ) ) {
     217                                        $params['item_id'] = bp_blogs_blog_get_current_blog_id();
     218                                } else {
     219                                        $params['item_id'] = false;
     220                                }
     221
    217222                                break;
    218223
    219224                        case 'group' :
    function bp_core_delete_existing_avatar( $args = '' ) { 
    664669        extract( $args, EXTR_SKIP );
    665670
    666671        if ( empty( $item_id ) ) {
    667                 if ( 'user' == $object )
     672                if ( 'user' === $object ) {
    668673                        $item_id = bp_displayed_user_id();
    669                 elseif ( 'group' == $object )
     674                } elseif ( 'group' === $object && bp_is_active( 'groups' ) ) {
    670675                        $item_id = buddypress()->groups->current_group->id;
    671                 elseif ( 'blog' == $object )
    672                         $item_id = $current_blog->id;
     676                } elseif ( 'blog' === $object && bp_is_active( 'blogs', 'blog' ) ) {
     677                        $item_id = bp_blogs_blog_get_current_blog_id();
     678                }
    673679
    674680                /** This filter is documented in bp-core/bp-core-avatars.php */
    675681                $item_id = apply_filters( 'bp_core_avatar_item_id', $item_id, $object );
    function bp_avatar_ajax_upload() { 
    920926                                'populate_extras' => false,
    921927                        ) );
    922928                }
     929        } elseif ( 'blog' === $bp_params['object'] && bp_is_active( 'blogs', 'blog' ) ) {
     930                $bp_params['upload_dir_filter'] = 'blogs_avatar_upload_dir';
     931
     932                if ( ! bp_blogs_blog_get_current_blog_id() && ! empty( $bp_params['item_id'] ) ) {
     933                        $needs_reset = array( 'component' => 'blogs', 'key' => 'current_blog', 'value' => $bp->blogs->current_blog );
     934                        $bp->blogs->current_blog = bp_blogs_get_blog( array(
     935                                'blog_id'        => $bp_params['item_id'],
     936                                'populate_extras' => true,
     937                        ) );
     938                }
    923939        } else {
    924940                /**
    925941                 * Filter here to deal with other components
    function bp_avatar_is_front_edit() { 
    18211837                }
    18221838        }
    18231839
     1840        if ( bp_is_active( 'blogs', 'blog' ) && bp_is_blog_manage_screen( 'edit-logo' ) ) {
     1841                $retval = ! bp_blogs_blog_disable_avatar_uploads();
     1842        }
     1843
    18241844        /**
    18251845         * Use this filter if you need to :
    18261846         * - Load the avatar UI for a component that is !groups or !user (return true regarding your conditions)
  • src/bp-core/bp-core-classes.php

    diff --git src/bp-core/bp-core-classes.php src/bp-core/bp-core-classes.php
    index 41be065..0a65aa1 100644
    require dirname( __FILE__ ) . '/classes/class-bp-recursive-query.php'; 
    2323require dirname( __FILE__ ) . '/classes/class-bp-media-extractor.php';
    2424require dirname( __FILE__ ) . '/classes/class-bp-attachment.php';
    2525require dirname( __FILE__ ) . '/classes/class-bp-attachment-avatar.php';
     26require dirname( __FILE__ ) . '/classes/class-bp-single-item-navigation.php';
  • src/bp-core/bp-core-filters.php

    diff --git src/bp-core/bp-core-filters.php src/bp-core/bp-core-filters.php
    index b5e857a..1c23fbe 100644
    function bp_modify_page_title( $title = '', $sep = '&raquo;', $seplocation = 'ri 
    731731
    732732        // A single item from a component other than groups
    733733        } elseif ( bp_is_single_item() ) {
    734                 $title_parts = array( $bp->bp_options_title, $bp->bp_options_nav[ bp_current_item() ][ bp_current_action() ]['name'] );
     734                if ( isset( $bp->{$bp->current_component}->nav->main ) ) {
     735                        $component_nav_section = '';
     736
     737                        // Get the component nav section name
     738                        foreach ( $bp->{$bp->current_component}->nav->main as $component_nav_item ) {
     739                                if ( bp_current_action() !== $component_nav_item['slug'] ) {
     740                                        continue;
     741                                }
     742
     743                                $component_nav_section = $component_nav_item['name'];
     744                        }
     745
     746                        $title_parts = array( $bp->bp_options_title, $component_nav_section );
     747                } else {
     748                        $title_parts = array( $bp->bp_options_title, $bp->bp_options_nav[ bp_current_item() ][ bp_current_action() ]['name'] );
     749                }
    735750
    736751        // An index or directory
    737752        } elseif ( bp_is_directory() ) {
  • src/bp-core/bp-core-options.php

    diff --git src/bp-core/bp-core-options.php src/bp-core/bp-core-options.php
    index 1ca2ee6..cafb7e8 100644
    function bp_get_default_options() { 
    5858                // Group Profile Photos
    5959                'bp-disable-group-avatar-uploads' => false,
    6060
     61                // Blog Profile Photos
     62                'bp-disable-blog-avatar-uploads'  => false,
     63
    6164                // Allow users to delete their own accounts
    6265                'bp-disable-account-deletion'     => false,
    6366
    function bp_disable_group_avatar_uploads( $default = null ) { 
    618621}
    619622
    620623/**
     624 * Are blog avatars disabled?
     625 *
     626 * @since BuddyPress (2.4.0)
     627 *
     628 * @param bool $default Optional. Fallback value if not found in the database.
     629 *                      Defaults: False.
     630 * @return bool True if blog avatar uploads are disabled, otherwise false.
     631 */
     632function bp_blogs_blog_disable_avatar_uploads( $default = false ) {
     633        /**
     634         * Filters whether or not members are able to upload blog avatars.
     635         *
     636         * @since BuddyPress (2.4.0)
     637         *
     638         * @param bool $disabled Whether or not members are able to upload their blog avatars.
     639         * @param bool $default  Default value passed to the function.
     640         */
     641        return (bool) apply_filters( 'bp_blogs_blog_disable_avatar_uploads', (bool) bp_get_option( 'bp-disable-blog-avatar-uploads', $default ) );
     642}
     643
     644/**
    621645 * Are members able to delete their own accounts?
    622646 *
    623647 * @since BuddyPress (1.6.0)
  • src/bp-core/bp-core-template.php

    diff --git src/bp-core/bp-core-template.php src/bp-core/bp-core-template.php
    index f6c88ed..eee4018 100644
    function bp_get_options_nav( $parent_slug = '' ) { 
    8787}
    8888
    8989/**
     90 * Output a component's single item main nav
     91 *
     92 * @since BuddyPress (2.4.0)
     93 *
     94 * @param  string $component the component id
     95 */
     96function bp_single_item_main_nav( $component = '' ) {
     97        $bp = buddypress();
     98
     99        if ( empty( $component ) ) {
     100                $component = bp_current_component();
     101        }
     102
     103        if ( ! isset( $bp->{$component}->nav ) || ! is_a( $bp->{$component}->nav, 'BP_Single_Item_Navigation' ) ) {
     104                return;
     105        }
     106
     107        $bp->{$component}->nav->display_main_nav();
     108}
     109
     110/**
     111 * Output a component's single item options nav
     112 *
     113 * @since BuddyPress (2.4.0)
     114 *
     115 * @param array  $subnav the subnav containing the nav items to output
     116 * @param string $the_index the subnav index containing the nav items
     117 * @param string $selected_item the current item displayed
     118 * @param string $list_type extra css attribute
     119 */
     120function bp_component_sub_nav( $component = '' ) {
     121        $bp = buddypress();
     122
     123        if ( empty( $component ) ) {
     124                $component = bp_current_component();
     125        }
     126
     127        if ( ! bp_is_single_item() || ! isset( $bp->{$component}->nav ) || ! is_a( $bp->{$component}->nav, 'BP_Single_Item_Navigation' ) ) {
     128                return;
     129        }
     130
     131        $bp->{$component}->nav->display_sub_nav();
     132}
     133
     134/**
    90135 * Get the 'bp_options_title' property from the BP global.
    91136 *
    92137 * Not currently used in BuddyPress.
    function bp_is_create_blog() { 
    25642609 * @return True if the current page is the blogs directory.
    25652610 */
    25662611function bp_is_blogs_directory() {
    2567         if ( is_multisite() && bp_is_blogs_component() && ! bp_current_action() ) {
     2612        if ( is_multisite() && bp_is_blogs_component() && ! bp_current_action() && ! bp_current_item() && ! bp_is_user() ) {
    25682613                return true;
    25692614        }
    25702615
    25712616        return false;
    25722617}
    25732618
     2619/**
     2620 * Does the current page belong to a single blog ?
     2621 *
     2622 * Will return true for any subpage of a single blog.
     2623 *
     2624 * @since  BuddyPress (2.4.0)
     2625 *
     2626 * @return bool True if the current page is part of a single blog.
     2627 */
     2628function bp_is_blog() {
     2629        $retval = bp_is_active( 'blogs', 'blog' );
     2630
     2631        if ( ! empty( $retval ) ) {
     2632                $retval = bp_is_blogs_component() && bp_blogs_blog_get_current_blog();
     2633        }
     2634
     2635        return (bool) $retval;
     2636}
     2637
     2638/**
     2639 * Is the current page a single blog's home page?
     2640 *
     2641 * URL will vary depending on which blog tab is set to be the "home". By
     2642 * default, it's the blog's recent activity.
     2643 *
     2644 * @since  BuddyPress (2.4.0)
     2645 *
     2646 * @return bool True if the current page is a single blog's home page.
     2647 */
     2648function bp_is_blog_home() {
     2649        if ( bp_is_single_item() && bp_is_blogs_component() && ( ! bp_current_action() || bp_is_current_action( 'home' ) ) ) {
     2650                return true;
     2651        }
     2652
     2653        return false;
     2654}
     2655
     2656/**
     2657 * Is the current page a blog's activity page?
     2658 *
     2659 * Eg http://example.com/sites/mysite/activity/.
     2660 *
     2661 * @since  BuddyPress (2.4.0)
     2662 *
     2663 * @return bool True if the current page is a blog's activity page.
     2664 */
     2665function bp_is_blog_activity() {
     2666        return (bool) ( bp_is_blogs_component() && bp_is_current_action( 'activity' ) );
     2667}
     2668
     2669/**
     2670 * Is the current page a blog's members page?
     2671 *
     2672 * Eg http://example.com/sites/mysite/members/.
     2673 *
     2674 * @since  BuddyPress (2.4.0)
     2675 *
     2676 * @return bool True if the current page is a blog's members page.
     2677 */
     2678function bp_is_blog_members() {
     2679        return (bool) ( bp_is_blogs_component() && bp_is_current_action( 'members' ) );
     2680}
     2681
     2682/**
     2683 * Is the current page a blog's manage page?
     2684 *
     2685 * Eg http://example.com/sites/mysite/manage/.
     2686 *
     2687 * @since  BuddyPress (2.4.0)
     2688 *
     2689 * @return bool True if the current page is a blog's manage page.
     2690 */
     2691function bp_is_blog_manage() {
     2692        return (bool) ( bp_is_blogs_component() && bp_is_current_action( 'manage' ) );
     2693}
     2694
     2695/**
     2696 * Is the current page a specific blog manage screen?
     2697 *
     2698 * @since BuddyPress (2.4.0)
     2699 *
     2700 * @param string $slug
     2701 * @return bool
     2702 */
     2703function bp_is_blog_manage_screen( $slug = '' ) {
     2704        return (bool) ( bp_is_blog_manage() && bp_is_action_variable( $slug ) );
     2705}
     2706
    25742707/** Messages ******************************************************************/
    25752708
    25762709/**
  • src/bp-core/bp-core-update.php

    diff --git src/bp-core/bp-core-update.php src/bp-core/bp-core-update.php
    index fb8e468..62825fe 100644
    function bp_version_updater() { 
    258258                if ( $raw_db_version < 9615 ) {
    259259                        bp_update_to_2_3();
    260260                }
     261
     262                // 2.4.0
     263                if ( $raw_db_version < 9943 ) {
     264                        bp_update_to_2_4();
     265                }
    261266        }
    262267
    263268        /** All done! *************************************************************/
    function bp_update_to_2_3() { 
    482487}
    483488
    484489/**
     490 * 2.4.0 update routine.
     491 *
     492 * - Add the is_contributor field to the bp_user_blogs table
     493 *
     494 * @since BuddyPress (2.4.0)
     495 */
     496function bp_update_to_2_4() {
     497        // Also handled by `bp_core_install()`
     498        if ( bp_is_active( 'blogs' ) ) {
     499                bp_core_install_blog_tracking();
     500        }
     501}
     502
     503/**
    485504 * Updates the component field for new_members type.
    486505 *
    487506 * @since BuddyPress (2.2.0)
  • src/bp-core/bp-core-wpabstraction.php

    diff --git src/bp-core/bp-core-wpabstraction.php src/bp-core/bp-core-wpabstraction.php
    index 7344245..74f2f42 100644
    if ( !function_exists( 'mb_strrpos' ) ) { 
    217217                }
    218218        }
    219219}
     220
     221/**
     222 * WordPress user_can() function does not have an equivalent for multisite configs
     223 *
     224 * @since BuddyPress (2.4.0)
     225 *
     226 * @param  int    $user_id the user ID we need to check the capability for
     227 * @param  string $capability the cpability to check
     228 * @param  int    $blog_id the blog id to check the capability for
     229 * @return bool  True if user can for the requested blog, false otherwise
     230 */
     231function bp_user_can_for_blog( $user_id, $capability, $blog_id = 0 ) {
     232        // Bail if no valid user_id provided
     233        if ( empty( $user_id ) ) {
     234                return false;
     235        }
     236
     237        if ( empty( $blog_id ) ) {
     238                $blog_id = get_current_blog_id();
     239        }
     240
     241        if ( is_multisite() && (int) $blog_id !== (int) bp_get_root_blog_id() ) {
     242                switch_to_blog( $blog_id );
     243                $switched = true;
     244        }
     245
     246        $can = user_can( $user_id, $capability );
     247
     248        if ( ! empty( $switched ) ) {
     249                restore_current_blog();
     250        }
     251
     252        return $can;
     253}
  • src/bp-core/classes/class-bp-attachment-avatar.php

    diff --git src/bp-core/classes/class-bp-attachment-avatar.php src/bp-core/classes/class-bp-attachment-avatar.php
    index 5ea1bd1..848b873 100644
    class BP_Attachment_Avatar extends BP_Attachment { 
    312312        }
    313313
    314314        /**
     315         * Get the blog id to set its avatar
     316         *
     317         * @since BuddyPress (2.4.0)
     318         *
     319         * @return integer the blog id
     320         */
     321        private function get_blog_id() {
     322                $blog_id = 0;
     323
     324                if ( bp_is_blog() ) {
     325                        $blog_id = bp_blogs_blog_get_current_blog_id();
     326                }
     327
     328                return $blog_id;
     329        }
     330
     331        /**
    315332         * Build script datas for the Uploader UI
    316333         *
    317334         * @since BuddyPress (2.3.0)
    class BP_Attachment_Avatar extends BP_Attachment { 
    331348                // Get the possible item ids
    332349                $user_id  = $this->get_user_id();
    333350                $group_id = $this->get_group_id();
     351                $blog_id  = $this->get_blog_id();
    334352
    335353                if ( ! empty( $user_id ) ) {
    336354                        // Should we load the the Webcam Avatar javascript file
    class BP_Attachment_Avatar extends BP_Attachment { 
    373391                                3 => __( 'There was a problem deleting the group profile photo. Please try again.', 'buddypress' ),
    374392                                4 => __( 'The group profile photo was deleted successfully!', 'buddypress' ),
    375393                        );
     394                } elseif( ! empty( $blog_id ) ) {
     395                        $script_data['bp_params'] = array(
     396                                'object'     => 'blog',
     397                                'item_id'    => $blog_id,
     398                                'has_avatar' => bp_get_blog_has_avatar( $blog_id ),
     399                                'nonces'     => array(
     400                                        'set'    => wp_create_nonce( 'bp_avatar_cropstore' ),
     401                                        'remove' => wp_create_nonce( 'bp_delete_avatar_link' ),
     402                                ),
     403                        );
     404
     405                        // Set feedback messages
     406                        $script_data['feedback_messages'] = array(
     407                                1 => __( 'There was a problem cropping the site logo.', 'buddypress' ),
     408                                2 => __( 'The site logo was uploaded successfully.', 'buddypress' ),
     409                                3 => __( 'There was a problem deleting the site logo. Please try again.', 'buddypress' ),
     410                                4 => __( 'The site logo was deleted successfully!', 'buddypress' ),
     411                        );
    376412                } else {
    377413                        /**
    378414                         * Use this filter to include specific BuddyPress params for your object
    379                          * e.g. Blavatar
    380415                         *
    381416                         * @since BuddyPress (2.3.0)
    382417                         *
  • src/bp-core/classes/class-bp-single-item-navigation.php

    diff --git src/bp-core/classes/class-bp-single-item-navigation.php src/bp-core/classes/class-bp-single-item-navigation.php
    index e69de29..3fae7a1 100644
     
     1<?php
     2/**
     3 * Core component classes.
     4 *
     5 * @package BuddyPress
     6 * @subpackage Core
     7 */
     8
     9// Exit if accessed directly
     10defined( 'ABSPATH' ) || exit;
     11
     12/**
     13 * API to create a component's single item navigation.
     14 *
     15 * @since BuddyPress (2.4.0)
     16 */
     17class BP_Single_Item_Navigation {
     18
     19        /**
     20         * The single item main nav
     21         *
     22         * @since BuddyPress (2.4.0)
     23         * @var array
     24         */
     25        public $main = array();
     26
     27        /**
     28         * The single item sub nav
     29         *
     30         * @since BuddyPress (2.4.0)
     31         * @var array
     32         */
     33        public $sub  = array();
     34
     35        /**
     36         * The default args to be merged with the
     37         * ones passed to the constructor
     38         *
     39         * @since BuddyPress (2.4.0)
     40         * @var array
     41         */
     42        protected $default_args = array(
     43                'component_id'   => '',
     44                'component_slug' => '',
     45                'single_item'    => '',
     46        );
     47
     48        /**
     49         * Constructor
     50         *
     51         * @since BuddyPress (2.4.0)
     52         *
     53         * @param array $args {
     54         *     Array of arguments.
     55         *     @type string $component_id String describing the component id (eg: blogs, groups...).
     56         *     @type string $component_slug The root slug of the component (eg: blogs, sites, groups...)
     57         *     @type string $single_item Required. The single item name (eg: blog, group...)
     58         * }
     59         */
     60        public function __construct( $args = array() ) {
     61                if ( empty( $args['single_item'] ) ) {
     62                        return false;
     63                }
     64
     65                // Merge args
     66                $params = wp_parse_args( $args, $this->default_args, $args['single_item'] . '_single_nav_params' );
     67
     68                foreach ( $params as $key => $param ) {
     69                        // Sanitize slug
     70                        if ( 'component_slug' === $key ) {
     71                                $this->{$key} = sanitize_title( $param );
     72
     73                        // Sanitize other keys
     74                        } else {
     75                                $this->{$key} = sanitize_key( $param );
     76                        }
     77                }
     78
     79                // Use the current component as a fallback
     80                if ( empty( $component_id ) ) {
     81                        $this->component_id = bp_current_component();
     82                }
     83
     84                // Use the component root slug as a fallback
     85                if ( empty( $component_id ) && is_callable( 'bp_get_' . $this->component_id . '_root_slug' ) ) {
     86                        $this->component_slug = call_user_func( 'bp_get_' . $this->component_id . '_root_slug' );
     87                }
     88        }
     89
     90        /**
     91         * Setup the single item navigation
     92         *
     93         * @since BuddyPress (2.4.0)
     94         *
     95         * @param  array  $main_nav list of associative arrays containing the nav items params
     96         * @param  array  $sub_nav  list of associative arrays containing the sub nav items params
     97         */
     98        public function setup_nav( $main_nav = array(), $sub_nav = array() ) {
     99                // Bail if the component slug or the component id are not set
     100                if ( ! $this->component_slug || ! $this->component_id ) {
     101                        return false;
     102                }
     103
     104                // No sub nav items without a main nav item
     105                if ( ! empty( $main_nav ) ) {
     106                        foreach( (array) $main_nav as $item ) {
     107                                $this->new_main_nav_item( $item );
     108                        }
     109
     110                        // Sub nav items are not required
     111                        if ( ! empty( $sub_nav ) ) {
     112                                foreach( (array) $sub_nav as $sub_item ) {
     113                                        $this->new_sub_nav_item( $sub_item );
     114                                }
     115                        }
     116                }
     117
     118                /**
     119                 * Fires at the end of the setup_nav method inside BP_Single_Item_Navigation.
     120                 *
     121                 * This is a dynamic hook that is based on the component string ID.
     122                 *
     123                 * @since BuddyPress (2.4.0)
     124                 */
     125                do_action( 'bp_' . $this->component_id . '_single_item_setup_nav' );
     126        }
     127
     128        /**
     129         * Add a new nav item to main nav
     130         *
     131         * @since BuddyPress (2.4.0)
     132         *
     133         * @param  array  $args associative array containing the item params
     134         */
     135        public function new_main_nav_item( $args = array() ) {
     136                // Bail if the component slug or the component id are not set
     137                if ( ! $this->component_slug || ! $this->component_id ) {
     138                        return false;
     139                }
     140
     141                // Get BuddyPress instance
     142                $bp = buddypress();
     143
     144                $slug = false;
     145                if ( ! empty( $args['slug'] ) ) {
     146                        $slug = $args['slug'];
     147                }
     148
     149                $item = bp_parse_args( $args, array(
     150                        'name'                    => false, // Display name for the nav item
     151                        'slug'                    => false, // URL slug for the nav item
     152                        'item_css_id'             => false, // The CSS ID to apply to the HTML of the nav item
     153                        'item_admin_only'         => false, // Can only site admins see this nav item?
     154                        'position'                => 99,    // Index of where this nav item should be positioned
     155                        'screen_function'         => false, // The name of the function to run when clicked
     156                        'default_subnav_slug'     => false  // The slug of the default subnav item to select when clicked
     157                ), $this->single_item . '_main_nav_item_' . $slug );
     158
     159                // If we don't have the required info we need, don't create this nav item
     160                if ( empty( $item['name'] ) || empty( $item['slug'] ) || empty( $item['screen_function'] ) ) {
     161                        return false;
     162                }
     163
     164                // If this is for site admins only and the user is not one, don't create the subnav item
     165                if ( ! empty( $item['item_admin_only'] ) && ! bp_is_item_admin() ) {
     166                        return false;
     167                }
     168
     169                if ( empty( $item['item_css_id'] ) ) {
     170                        $item['item_css_id'] = $item['slug'];
     171                }
     172
     173                /**
     174                 * Link is composed by:
     175                 * 1. the root domain          eg: http://site.url
     176                 * 2. the component root slug  eg: sites
     177                 * 3. the current item slug    eg: blog_slug
     178                 * 4. the nav item slug        eg: home
     179                 */
     180                $link = bp_get_root_domain() . '/' . $this->component_slug . '/' . bp_current_item() . '/' . $item['slug'];
     181
     182                $this->main[ $item['slug'] ] = array(
     183                        'name'                    => $item['name'],
     184                        'slug'                    => $item['slug'],
     185                        'link'                    => trailingslashit( $link ),
     186                        'css_id'                  => $item['item_css_id'],
     187                        'position'                => $item['position'],
     188                        'screen_function'         => &$item['screen_function'],
     189                        'default_subnav_slug'     => $item['default_subnav_slug']
     190                );
     191
     192                /**
     193                 * If this condition is true, this means the url looks like
     194                 * http://site.url/sites/blog_slug/home
     195                 */
     196                if ( bp_is_current_action( $item['slug'] ) ) {
     197                        /**
     198                         * If the default subnav match the first action variable move all left
     199                         */
     200                        if ( ! empty( $item['default_subnav_slug'] ) && bp_is_action_variable( $item['default_subnav_slug'], 0 ) && ! bp_action_variable( 1 ) ) {
     201                                unset( $bp->canonical_stack['action_variables'][0] );
     202
     203                        // No action variable it's the root of the nav
     204                        } elseif ( ! bp_action_variable( 0 ) ) {
     205
     206                                // Add our screen hook if screen function is callable
     207                                if ( is_callable( $item['screen_function'] ) ) {
     208                                        add_action( 'bp_screens', $item['screen_function'], 3 );
     209                                }
     210
     211                                if ( ! empty( $item['default_subnav_slug'] ) ) {
     212                                        /**
     213                                         * Filters the component's single nav default subnav item.
     214                                         *
     215                                         * @since BuddyPress (2.4.0)
     216                                         *
     217                                         * @param string $default_subnav_slug The slug of the default subnav item
     218                                         *                                    to select when clicked.
     219                                         * @param array  $r                   Parsed arguments for the nav item.
     220                                         */
     221                                        $bp->current_action = apply_filters( 'bp_single_item_default_subnav', $item['default_subnav_slug'], $item );
     222                                }
     223                        }
     224                }
     225        }
     226
     227        /**
     228         * Add a new sub nav item to sub nav
     229         *
     230         * @since BuddyPress (2.4.0)
     231         *
     232         * @param  array  $args associative array containing the sub item params
     233         */
     234        public function new_sub_nav_item( $args = array() ) {
     235                // Bail if the component slug or the component id are not set
     236                if ( ! $this->component_slug || ! $this->component_id ) {
     237                        return false;
     238                }
     239
     240                $slug = false;
     241                if ( ! empty( $args['slug'] ) ) {
     242                        $slug = $args['slug'];
     243                }
     244
     245                $sub_item = bp_parse_args( $args, array(
     246                        'name'              => false, // Display name for the nav item
     247                        'slug'              => false, // URL slug for the nav item
     248                        'parent_slug'       => false, // URL slug of the parent nav item
     249                        'parent_url'        => false, // URL of the parent item
     250                        'item_css_id'       => false, // The CSS ID to apply to the HTML of the nav item
     251                        'user_has_access'   => true,  // Can the logged in user see this nav item?
     252                        'no_access_url'     => '',
     253                        'item_admin_only'   => false, // Can only site admins see this nav item?
     254                        'position'          => 90,    // Index of where this nav item should be positioned
     255                        'screen_function'   => false, // The name of the function to run when clicked
     256                        'link'              => '',    // The link for the subnav item; optional, not usually required.
     257                        'show_in_admin_bar' => false, // Show the Manage link in the current group's "Edit" Admin Bar menu
     258                ), $this->single_item . '_sub_nav_item_' . $slug );
     259
     260
     261                // If we don't have the required info we need, don't create this subnav item
     262                if ( empty( $sub_item['name'] ) || empty( $sub_item['slug'] ) || empty( $sub_item['parent_slug'] ) || empty( $sub_item['parent_url'] ) || empty( $sub_item['screen_function'] ) ) {
     263                        return false;
     264                }
     265
     266                // If this is for site admins only and the user is not one, don't create the subnav item
     267                if ( ! empty( $sub_item['item_admin_only'] ) && ! bp_is_item_admin() ) {
     268                        return false;
     269                }
     270
     271                if ( empty( $sub_item['link'] ) ) {
     272                        $sub_item['link'] = trailingslashit( $sub_item['parent_url'] . $sub_item['slug'] );
     273
     274                        // If this sub item is the default for its parent, skip the slug
     275                        if ( $sub_item['slug'] === $this->main[ $sub_item['parent_slug'] ]['default_subnav_slug'] ) {
     276                                $sub_item['link'] = trailingslashit( $sub_item['parent_url'] );
     277                        }
     278                }
     279
     280                if ( empty( $sub_item['item_css_id'] ) ) {
     281                        $sub_item['item_css_id'] = $sub_item['slug'];
     282                }
     283
     284                $this->sub[ $sub_item['parent_slug'] ][ $sub_item['slug'] ] = array(
     285                        'name'              => $sub_item['name'],
     286                        'link'              => $sub_item['link'],
     287                        'slug'              => $sub_item['slug'],
     288                        'css_id'            => $sub_item['item_css_id'],
     289                        'position'          => $sub_item['position'],
     290                        'user_has_access'   => $sub_item['user_has_access'],
     291                        'no_access_url'     => $sub_item['no_access_url'],
     292                        'screen_function'   => &$sub_item['screen_function'],
     293                        'show_in_admin_bar' => (bool) $sub_item['show_in_admin_bar'],
     294                );
     295
     296                if ( ! bp_is_current_component( $this->component_id ) && ! bp_is_current_action( $sub_item['parent_slug'] ) ) {
     297                        return false;
     298                }
     299
     300                if ( bp_action_variable( 0 ) && bp_is_action_variable( $sub_item['slug'], 0 ) ) {
     301
     302                        $hooked = bp_core_maybe_hook_new_subnav_screen_function( $this->sub[ $sub_item['parent_slug'] ][ $sub_item['slug'] ] );
     303
     304                        // If redirect args have been returned, perform the redirect now
     305                        if ( ! empty( $hooked['status'] ) && 'failure' === $hooked['status'] && isset( $hooked['redirect_args'] ) ) {
     306                                bp_core_no_access( $hooked['redirect_args'] );
     307                        }
     308                }
     309        }
     310
     311        /**
     312         * Sort the main nav items and output the main nav.
     313         *
     314         * @since BuddyPress (2.4.0)
     315         *
     316         * @return HTML output
     317         */
     318        public function display_main_nav() {
     319                // Bail if the component slug or the component id are not set
     320                if ( ! $this->component_slug || ! $this->component_id ) {
     321                        return false;
     322                }
     323
     324                // Sort the main nav just before it's displayed
     325                $this->main = bp_sort_by_key( $this->main, 'position', 'num' );
     326
     327                // Loop throw each nav item
     328                foreach ( (array) $this->main as $main_nav_item ) {
     329                        // Defaults to none
     330                        $selected = '';
     331
     332                        if ( bp_is_current_action( $main_nav_item['slug'] ) ) {
     333                                $selected = ' class="current selected"';
     334                        }
     335
     336                        /**
     337                         * Filters the component's "main nav", the first-level single item navigation menu.
     338                         *
     339                         * This is a dynamic filter that is dependent on the component's single item and the provided css_id value.
     340                         *
     341                         * @since BuddyPress (2.4.0)
     342                         *
     343                         * @param string $value         HTML list item for the submenu item.
     344                         * @param array  $subnav_item   Main nav array item being displayed.
     345                         */
     346                        echo apply_filters_ref_array( 'bp_' . $this->single_item . '_main_nav_' . $main_nav_item['css_id'], array( '<li id="' . esc_attr( $main_nav_item['css_id'] ) . '-' . esc_attr( $this->component_id ) . '-li" ' . $selected . '><a id="' . esc_attr( $this->single_item ) . '-' . esc_attr( $main_nav_item['slug'] ) . '" href="' . esc_url( $main_nav_item['link'] ) . '">' . $main_nav_item['name'] . '</a></li>', &$main_nav_item ) );
     347                }
     348        }
     349
     350        /**
     351         * Sort the sub nav items and output the sub nav
     352         *
     353         * @since BuddyPress (2.4.0)
     354         *
     355         * @return HTML output
     356         */
     357        public function display_sub_nav() {
     358                // Bail if the component slug or the component id are not set
     359                if ( ! $this->component_slug || ! $this->component_id ) {
     360                        return false;
     361                }
     362
     363                $the_index = bp_current_action();
     364
     365                if ( bp_action_variable( 0 ) ) {
     366                        $selected_item = bp_action_variable( 0 );
     367                } else {
     368                        $selected_item = $the_index;
     369                }
     370
     371                if ( empty( $this->sub[ $the_index ] ) ) {
     372                        return;
     373                }
     374
     375                // Sort the main nav just before it's displayed
     376                $this->sub[ $the_index ] = bp_sort_by_key( $this->sub[ $the_index ], 'position', 'num' );
     377
     378                // Loop throw each nav item
     379                foreach ( (array) $this->sub[ $the_index ] as $sub_nav_item ) {
     380
     381                        if ( empty( $sub_nav_item['user_has_access'] ) ) {
     382                                continue;
     383                        }
     384
     385                        // If the current action or an action variable matches the nav item id, then add a highlight CSS class.
     386                        if ( $sub_nav_item['slug'] === $selected_item ) {
     387                                $selected = ' class="current selected"';
     388                        } else {
     389                                $selected = '';
     390                        }
     391
     392                        /**
     393                         * Filters the component's "single nav", the secondary-level single item navigation menu.
     394                         *
     395                         * This is a dynamic filter that is dependent on the component's id and the provided css_id value.
     396                         *
     397                         * @since BuddyPress (2.4.0)
     398                         *
     399                         * @param string $value         HTML list item for the submenu item.
     400                         * @param array  $subnav_item   Submenu array item being displayed.
     401                         * @param string $selected_item Current action.
     402                         */
     403                        echo apply_filters( 'bp_' . $this->single_item . '_single_subnav_' . $sub_nav_item['css_id'], '<li id="' . esc_attr( $sub_nav_item['css_id'] . '-' . $this->component_id . '-' . $this->single_item . '-li' ) . '" ' . $selected . '><a id="' . esc_attr( $sub_nav_item['css_id'] ) . '" href="' . esc_url( $sub_nav_item['link'] ) . '">' . $sub_nav_item['name'] . '</a></li>', $sub_nav_item, $selected_item );
     404                }
     405        }
     406
     407        /**
     408         * Get the sub nav items for the provided parent slug
     409         *
     410         * @since BuddyPress (2.4.0)
     411         *
     412         * @param  string $parent_slug the main nav parent slug
     413         * @return HTML   output
     414         */
     415        public function get_sub_nav_by_parent_slug( $parent_slug = '' ) {
     416                if ( empty( $parent_slug ) || empty( $this->sub[ $parent_slug ] ) ) {
     417                        return false;
     418                }
     419
     420                // Sort the sub nav items
     421                $this->sub[ $parent_slug ] = bp_sort_by_key( $this->sub[ $parent_slug ], 'position', 'num' );
     422
     423                return $this->sub[ $parent_slug ];
     424        }
     425
     426        /**
     427         * Remove a main nav item for component's single item
     428         *
     429         * @since BuddyPress (2.4.0)
     430         *
     431         * @param  string $component        the component id
     432         * @param  string $main_nav_item_id the main nav item id
     433         * @return bool                     true if the main nav was removed, false otherwise
     434         */
     435        public static function remove_main_nav_item( $component ='', $main_nav_item_id = '' ) {
     436                $bp = buddypress();
     437
     438                if ( empty( $component ) || empty( $main_nav_item_id ) || ! isset( $bp->{$component}->nav->main[ $main_nav_item_id ] ) ) {
     439                        return false;
     440                }
     441
     442                // Unset sub_nav items for this nav item
     443                if ( isset( $bp->{$component}->nav->sub[ $main_nav_item_id ] ) && is_array( $bp->{$component}->nav->sub[ $main_nav_item_id ] ) ) {
     444                        foreach( (array) $bp->{$component}->nav->sub[ $main_nav_item_id ] as $sub_nav_item ) {
     445                                self::remove_sub_nav_item( $component, $main_nav_item_id, $sub_nav_item['slug'] );
     446                        }
     447                }
     448
     449                $screen_function = false;
     450                if ( isset( $bp->{$component}->nav->main[ $main_nav_item_id ]['screen_function'] ) ) {
     451                        $screen_function = $bp->{$component}->nav->main[ $main_nav_item_id ]['screen_function'];
     452                }
     453
     454                if ( ! empty( $screen_function ) ) {
     455                        // Remove our screen hook if screen function is callable
     456                        if ( is_callable( $screen_function ) ) {
     457                                remove_action( 'bp_screens', $screen_function, 3 );
     458                        }
     459                }
     460
     461                unset( $bp->{$component}->nav->main[ $main_nav_item_id ] );
     462                return true;
     463        }
     464
     465        /**
     466         * Remove a sub nav item for component's single item main nav
     467         *
     468         * @since BuddyPress (2.4.0)
     469         *
     470         * @param  string $component         the component id
     471         * @param  string $main_nav_item_id  the main nav item id
     472         * @param  string $sub_nav_item_slug the sub nav slug
     473         * @return bool                      true if the sub nav was removed, false otherwise
     474         */
     475        public static function remove_sub_nav_item( $component ='', $main_nav_item_id = '', $sub_nav_item_slug = '' ) {
     476                $bp = buddypress();
     477
     478                if ( empty( $component ) || empty( $main_nav_item_id ) || empty( $sub_nav_item_slug ) || ! isset( $bp->{$component}->nav->sub[ $main_nav_item_id ][ $sub_nav_item_slug ] ) ) {
     479                        return false;
     480                }
     481
     482                $screen_function = false;
     483                if ( isset( $bp->{$component}->nav->sub[ $main_nav_item_id ][ $sub_nav_item_slug ]['screen_function'] ) ) {
     484                        $screen_function = $bp->{$component}->nav->sub[ $main_nav_item_id ][ $sub_nav_item_slug ]['screen_function'];
     485                }
     486
     487                if ( ! empty( $screen_function ) ) {
     488                        // Remove our screen hook if screen function is callable
     489                        if ( is_callable( $screen_function ) ) {
     490                                remove_action( 'bp_screens', $screen_function, 3 );
     491                        }
     492                }
     493
     494                unset( $bp->{$component}->nav->sub[ $main_nav_item_id ][ $sub_nav_item_slug ] );
     495                return true;
     496        }
     497}
  • src/bp-friends/bp-friends-template.php

    diff --git src/bp-friends/bp-friends-template.php src/bp-friends/bp-friends-template.php
    index 41821d8..165ccf6 100644
    function bp_member_add_friend_button() { 
    211211        bp_add_friend_button( bp_get_member_user_id() );
    212212}
    213213add_action( 'bp_directory_members_actions', 'bp_member_add_friend_button' );
     214add_action( 'bp_blog_members_actions', 'bp_member_add_friend_button' );
    214215
    215216/**
    216217 * Output the friend count for the current member in the loop.
  • src/bp-loader.php

    diff --git src/bp-loader.php src/bp-loader.php
    index a71c216..4df840b 100644
    class BuddyPress { 
    309309
    310310                /** Versions **********************************************************/
    311311
    312                 $this->version    = '2.3.0';
    313                 $this->db_version = 9909;
     312                $this->version    = '2.4.0-alpha';
     313                $this->db_version = 9943;
    314314
    315315                /** Loading ***********************************************************/
    316316
  • src/bp-members/bp-members-functions.php

    diff --git src/bp-members/bp-members-functions.php src/bp-members/bp-members-functions.php
    index 08a0314..63d68db 100644
    function bp_core_activate_signup( $key ) { 
    19381938
    19391939                $user_id = $user['user_id'];
    19401940
     1941                /**
     1942                 * If it's a blog signup and site logos are enabled
     1943                 * save a transient so that the user once loggedin will
     1944                 * be redirected to the edit-logo manage page of his site
     1945                 */
     1946                if ( ! empty( $user['blog_id'] ) && bp_is_active( 'blogs', 'blog' ) ) {
     1947                        // Taking no risk
     1948                        if ( bp_blogs_blog_is_avatar_uploads_enabled() ) {
     1949                                $transient_key = sprintf( '_bp_activation_%d_redirect', $user_id );
     1950
     1951                                // Five minutes should be ok.
     1952                                set_transient( $transient_key, intval( $user['blog_id'] ), 300 );
     1953                        }
     1954                }
     1955
    19411956        } else {
    19421957                $signups = BP_Signup::get( array(
    19431958                        'activation_key' => $key,
  • src/bp-templates/bp-legacy/buddypress-functions.php

    diff --git src/bp-templates/bp-legacy/buddypress-functions.php src/bp-templates/bp-legacy/buddypress-functions.php
    index 457e20d..d2e3d80 100644
    function bp_legacy_theme_ajax_querystring( $query_string, $object ) { 
    707707                if ( 'personal' == $_BP_COOKIE['bp-' . $object . '-scope'] ) {
    708708                        $user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id();
    709709                        $qs[] = 'user_id=' . $user_id;
     710
     711                        // Blogs directory, list blogs the user is contributing to
     712                        if ( 'blogs' === $object && bp_is_blogs_directory() ) {
     713                                $qs[] = 'user_level=1';
     714                        }
     715
     716                // Blogs directory, list blogs the user subscribed to
     717                } elseif ( 'blogs' === $object && 'subscriptions' === $_BP_COOKIE['bp-' . $object . '-scope'] ) {
     718                        $qs[] = 'user_id=' . bp_loggedin_user_id();
     719                        $qs[] = 'user_level=0';
    710720                }
    711721
    712722                // Activity stream scope only on activity directory.
  • src/bp-templates/bp-legacy/buddypress/activity/index.php

    diff --git src/bp-templates/bp-legacy/buddypress/activity/index.php src/bp-templates/bp-legacy/buddypress/activity/index.php
    index acce864..bfb1c07 100644
    do_action( 'bp_before_directory_activity' ); ?> 
    8989                                <?php
    9090
    9191                                /**
     92                                 * Fires before the listing of blogs activity type tab.
     93                                 *
     94                                 * @since BuddyPress (2.4.0)
     95                                 */
     96                                do_action( 'bp_before_activity_type_tab_blogs' ); ?>
     97
     98                                <?php if ( bp_is_active( 'blogs', 'blog' ) ) : ?>
     99
     100                                        <?php if ( bp_get_total_blog_count_for_user( bp_loggedin_user_id() ) ) : ?>
     101
     102                                                <li id="activity-blogs"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_blogs_slug() . '/'; ?>" title="<?php esc_attr_e( 'The activity of sites I am a member of.', 'buddypress' ); ?>"><?php printf( __( 'My Sites <span>%s</span>', 'buddypress' ), bp_get_total_blog_count_for_user( bp_loggedin_user_id() ) ); ?></a></li>
     103
     104                                        <?php endif; ?>
     105
     106                                <?php endif; ?>
     107
     108                                <?php
     109
     110                                /**
    92111                                 * Fires before the listing of favorites activity type tab.
    93112                                 *
    94113                                 * @since BuddyPress (1.2.0)
  • src/bp-templates/bp-legacy/buddypress/assets/_attachments/avatars/index.php

    diff --git src/bp-templates/bp-legacy/buddypress/assets/_attachments/avatars/index.php src/bp-templates/bp-legacy/buddypress/assets/_attachments/avatars/index.php
    index 82c401f..0656495 100644
    do_action( 'bp_attachments_avatar_check_template' ); 
    3939        <# } else if ( 'group' === data.object ) { #>
    4040                <p><?php _e( "If you'd like to remove the existing group profile photo but not upload a new one, please use the delete group profile photo button.", 'buddypress' ); ?></p>
    4141                <p><a class="button edit" id="bp-delete-avatar" href="#" title="<?php esc_attr_e( 'Delete Group Profile Photo', 'buddypress' ); ?>"><?php esc_html_e( 'Delete Group Profile Photo', 'buddypress' ); ?></a></p>
     42        <# } else if ( 'blog' === data.object ) { #>
     43                <p><?php _e( "If you'd like to remove the existing site logo but not upload a new one, please use the delete site logo button.", 'buddypress' ); ?></p>
     44                <p><a class="button edit" id="bp-delete-avatar" href="#" title="<?php esc_attr_e( 'Delete Site Logo', 'buddypress' ); ?>"><?php esc_html_e( 'Delete Site Logo', 'buddypress' ); ?></a></p>
    4245        <# } else { #>
    4346                <?php do_action( 'bp_attachments_avatar_delete_template' ); ?>
    4447        <# } #>
  • src/bp-templates/bp-legacy/buddypress/blogs/blogs-loop.php

    diff --git src/bp-templates/bp-legacy/buddypress/blogs/blogs-loop.php src/bp-templates/bp-legacy/buddypress/blogs/blogs-loop.php
    index ae83183..c957b19 100644
    do_action( 'bp_before_blogs_loop' ); ?> 
    4848        <?php while ( bp_blogs() ) : bp_the_blog(); ?>
    4949
    5050                <li <?php bp_blog_class() ?>>
    51                         <div class="item-avatar">
    52                                 <a href="<?php bp_blog_permalink(); ?>"><?php bp_blog_avatar( 'type=thumb' ); ?></a>
    53                         </div>
     51                        <?php if ( ! bp_blogs_blog_disable_avatar_uploads() ) : ?>
     52                                <div class="item-avatar">
     53                                        <a href="<?php bp_blog_permalink(); ?>"><?php bp_blog_avatar( 'type=thumb' ); ?></a>
     54                                </div>
     55                        <?php endif ; ?>
    5456
    5557                        <div class="item">
    5658                                <div class="item-title"><a href="<?php bp_blog_permalink(); ?>"><?php bp_blog_name(); ?></a></div>
  • src/bp-templates/bp-legacy/buddypress/blogs/index.php

    diff --git src/bp-templates/bp-legacy/buddypress/blogs/index.php src/bp-templates/bp-legacy/buddypress/blogs/index.php
    index 0c4a15c..21283a7 100644
    do_action( 'bp_before_directory_blogs_page' ); ?> 
    4646                        <ul>
    4747                                <li class="selected" id="blogs-all"><a href="<?php bp_root_domain(); ?>/<?php bp_blogs_root_slug(); ?>"><?php printf( __( 'All Sites <span>%s</span>', 'buddypress' ), bp_get_total_blog_count() ); ?></a></li>
    4848
    49                                 <?php if ( is_user_logged_in() && bp_get_total_blog_count_for_user( bp_loggedin_user_id() ) ) : ?>
     49                                <?php if ( is_user_logged_in() ) : ?>
    5050
    51                                         <li id="blogs-personal"><a href="<?php echo bp_loggedin_user_domain() . bp_get_blogs_slug(); ?>"><?php printf( __( 'My Sites <span>%s</span>', 'buddypress' ), bp_get_total_blog_count_for_user( bp_loggedin_user_id() ) ); ?></a></li>
     51                                        <?php if ( bp_get_total_blog_count_for_user( bp_loggedin_user_id() ) ) : ?>
     52
     53                                                <li id="blogs-personal"><a href="<?php echo bp_loggedin_user_domain() . bp_get_blogs_slug(); ?>"><?php printf( __( 'My Sites <span>%s</span>', 'buddypress' ), bp_get_total_blog_count_for_user( bp_loggedin_user_id() ) ); ?></a></li>
     54
     55                                        <?php endif; ?>
     56
     57                                        <?php if ( bp_is_active( 'blogs', 'blog') && bp_blogs_total_blogs_for_user_level( bp_loggedin_user_id() ) ) : ?>
     58
     59                                                <li id="blogs-subscriptions"><a href="<?php echo trailingslashit( bp_loggedin_user_domain() . bp_get_blogs_slug() ) . 'my-subscriptions'; ?>"><?php printf( __( 'My Subscriptions <span>%s</span>', 'buddypress' ), bp_blogs_total_blogs_for_user_level( bp_loggedin_user_id() ) ); ?></a></li>
     60
     61                                        <?php endif; ?>
    5262
    5363                                <?php endif; ?>
    5464
  • src/bp-templates/bp-legacy/buddypress/blogs/single/activity.php

    diff --git src/bp-templates/bp-legacy/buddypress/blogs/single/activity.php src/bp-templates/bp-legacy/buddypress/blogs/single/activity.php
    index e69de29..f61c4ea 100644
     
     1<?php
     2/**
     3 * BuddyPress Blog single item activity
     4 *
     5 * @since 2.4.0
     6 *
     7 * @package BuddyPress
     8 * @subpackage blogs
     9 */
     10
     11// Exit if accessed directly
     12defined( 'ABSPATH' ) or die; ?>
     13
     14<div class="item-list-tabs no-ajax" id="subnav" role="navigation">
     15        <ul>
     16                <?php do_action( 'bp_blog_activity_syndication_options' ); ?>
     17
     18                <li id="activity-filter-select" class="last">
     19                        <label for="activity-filter-by"><?php _e( 'Show:', 'buddypress' ); ?></label>
     20                        <select id="activity-filter-by">
     21                                <option value="-1"><?php _e( '&mdash; Everything &mdash;', 'buddypress' ); ?></option>
     22
     23                                <?php bp_activity_show_filters( 'blog' ); ?>
     24                        </select>
     25                </li>
     26        </ul>
     27</div><!-- .item-list-tabs -->
     28
     29<?php do_action( 'bp_before_blog_activity_content' ); ?>
     30
     31<div class="activity single-blog" role="main">
     32
     33        <?php if ( bp_blog_is_public() ) :
     34                bp_get_template_part( 'activity/activity-loop' );
     35
     36                else : ?>
     37
     38                <div id="message" class="info">
     39                        <p><?php _e( 'Sorry, as this site is private, no activity are available.', 'buddypress' ); ?></p>
     40                </div>
     41
     42        <?php endif; ?>
     43
     44</div><!-- .activity.single-blog -->
     45
     46<?php do_action( 'bp_after_blog_activity_content' ); ?>
  • src/bp-templates/bp-legacy/buddypress/blogs/single/blog-header.php

    diff --git src/bp-templates/bp-legacy/buddypress/blogs/single/blog-header.php src/bp-templates/bp-legacy/buddypress/blogs/single/blog-header.php
    index e69de29..d78e411 100644
     
     1<?php
     2/**
     3 * BuddyPress Blog single item header
     4 *
     5 * @since 2.4.0
     6 *
     7 * @package BuddyPress
     8 * @subpackage blogs
     9 */
     10
     11// Exit if accessed directly
     12defined( 'ABSPATH' ) or die; ?>
     13
     14<?php do_action( 'bp_before_blog_header' ); ?>
     15
     16<div id="item-actions">
     17
     18        <?php bp_blog_list_admins();
     19
     20        do_action( 'bp_after_blog_menu_admins' ); ?>
     21
     22</div><!-- #item-actions -->
     23
     24<?php if ( bp_blogs_blog_is_avatar_uploads_enabled() ) : ?>
     25
     26<div id="item-header-avatar">
     27        <a href="<?php bp_blog_view_details_link(); ?>" title="<?php bp_blog_name(); ?>">
     28
     29                <?php bp_blog_avatar(); ?>
     30
     31        </a>
     32</div><!-- #item-header-avatar -->
     33
     34<?php endif ; ?>
     35
     36<div id="item-header-content">
     37        <span class="highlight"><?php bp_blog_status(); ?></span>
     38        <span class="activity"><?php bp_blog_last_active(); ?></span>
     39
     40        <?php do_action( 'bp_before_blog_header_meta' ); ?>
     41
     42        <div id="item-meta">
     43
     44                <?php bp_blog_description(); ?>
     45
     46                <div id="item-buttons">
     47
     48                        <?php do_action( 'bp_blog_header_actions' ); ?>
     49
     50                </div><!-- #item-buttons -->
     51
     52                <?php do_action( 'bp_blog_header_meta' ); ?>
     53
     54        </div>
     55</div><!-- #item-header-content -->
     56
     57<?php
     58do_action( 'bp_after_blog_header' );
     59do_action( 'template_notices' );
     60?>
  • src/bp-templates/bp-legacy/buddypress/blogs/single/home.php

    diff --git src/bp-templates/bp-legacy/buddypress/blogs/single/home.php src/bp-templates/bp-legacy/buddypress/blogs/single/home.php
    index e69de29..dc952bc 100644
     
     1<?php
     2/**
     3 * BuddyPress Blog single item home page
     4 *
     5 * @since 2.4.0
     6 *
     7 * @package BuddyPress
     8 * @subpackage blogs
     9 */
     10
     11// Exit if accessed directly
     12defined( 'ABSPATH' ) or die; ?>
     13
     14<div id="buddypress">
     15
     16        <?php if ( bp_has_blogs() ) : while ( bp_blogs() ) : bp_the_blog(); ?>
     17
     18        <?php bp_blog_custom_header() ;?>
     19
     20        <?php do_action( 'bp_before_blog_home_content' ); ?>
     21
     22        <div id="item-header" role="complementary">
     23
     24                <?php bp_get_template_part( 'blogs/single/blog-header' ); ?>
     25
     26        </div><!-- #item-header -->
     27
     28        <div id="item-nav">
     29                <div class="item-list-tabs no-ajax" id="object-nav" role="navigation">
     30                        <ul>
     31
     32                                <?php bp_single_item_main_nav( 'blogs' ); ?>
     33
     34                                <?php do_action( 'bp_blog_main_nav' ); ?>
     35
     36                        </ul>
     37                </div>
     38        </div><!-- #item-nav -->
     39
     40        <div id="item-body">
     41
     42                <?php do_action( 'bp_before_blog_body' );
     43
     44                /**
     45                 * Does this next bit look familiar? If not, go check out WordPress's
     46                 */
     47
     48                        // Looking at home location
     49                        if ( bp_is_blog_home() ) :
     50
     51                                if ( bp_blog_has_access() ) {
     52
     53                                        // Load the appropriate front template
     54                                        bp_blogs_blog_load_front_template();
     55
     56                                } else {
     57
     58                                        /**
     59                                         * Fires before the display of the blog status message.
     60                                         *
     61                                         * @since BuddyPress (2.4.0)
     62                                         */
     63                                        do_action( 'bp_before_blog_status_message' ); ?>
     64
     65                                        <div id="message" class="info">
     66                                                <p><?php bp_blog_status_message(); ?></p>
     67                                        </div>
     68
     69                                        <?php
     70
     71                                        /**
     72                                         * Fires after the display of the blog status message.
     73                                         *
     74                                         * @since BuddyPress (2.4.0)
     75                                         */
     76                                        do_action( 'bp_after_blog_status_message' );
     77
     78                                }
     79
     80                        // Not looking at home
     81                        else :
     82
     83                                // Blog manage
     84                                if     ( bp_is_blog_manage()   ) : bp_get_template_part( 'blogs/single/manage'   );
     85
     86                                // Blog Activity
     87                                elseif ( bp_is_blog_activity() ) : bp_get_template_part( 'blogs/single/activity' );
     88
     89                                // Blog Members
     90                                elseif ( bp_is_blog_members()  ) : bp_get_template_part( 'blogs/single/members'  );