Skip to:
Content

BuddyPress.org

Ticket #6026: 6026.01.patch

File 6026.01.patch, 128.6 KB (added by imath, 4 years ago)
  • src/bp-activity/bp-activity-template.php

    diff --git src/bp-activity/bp-activity-template.php src/bp-activity/bp-activity-template.php
    index 690c816..33ab121 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_get_current_blog_id();
     632                $show_hidden = false;
    629633        } else {
    630634                $object      = false;
    631635                $primary_id  = false;
  • src/bp-blogs/bp-blogs-actions.php

    diff --git src/bp-blogs/bp-blogs-actions.php src/bp-blogs/bp-blogs-actions.php
    index 2d77f11..2bbe104 100644
    function bp_blogs_redirect_to_random_blog() { 
    3232        }
    3333}
    3434add_action( 'bp_actions', 'bp_blogs_redirect_to_random_blog' );
     35
     36/**
     37 * Check if the user needs to set an avatar for his just registered blog.
     38 *
     39 * @since BuddyPress (2.3.0)
     40 */
     41function bp_blogs_maybe_redirect_to_single_blog() {
     42        if ( ! is_multisite() || ! is_user_logged_in() || ! bp_blogs_is_avatar_uploads_enabled() ) {
     43                return;
     44        }
     45
     46        $transient_key = sprintf( '_bp_activation_%d_redirect', bp_loggedin_user_id() );
     47        $blog_id = get_transient( $transient_key );
     48
     49        if ( empty( $blog_id ) ) {
     50                return;
     51        }
     52
     53        // Delete the redirect transient
     54        delete_transient( $transient_key );
     55
     56        $single_blog = bp_blogs_get_blog( array( 'blog_id' => $blog_id ) );
     57
     58        if ( empty( $single_blog->path ) ) {
     59                return;
     60        }
     61
     62        $redirect = trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . $single_blog->path . 'manage/edit-logo' );
     63
     64        bp_core_add_message( __( 'Welcome to the profile area of your new site, please consider adding a site logo for your site', 'buddypress' ) );
     65        bp_core_redirect( esc_url( $redirect ) );
     66}
     67add_action( 'bp_blogs_setup_nav', 'bp_blogs_maybe_redirect_to_single_blog' );
  • src/bp-blogs/bp-blogs-activity.php

    diff --git src/bp-blogs/bp-blogs-activity.php src/bp-blogs/bp-blogs-activity.php
    index 1cace2a..11f79fc 100644
    function bp_blogs_register_activity_actions() { 
    3232                        __( 'New site created', 'buddypress' ),
    3333                        'bp_blogs_format_activity_action_new_blog',
    3434                        __( 'New Sites', 'buddypress' ),
    35                         0
     35                        array()
    3636                );
    3737        }
    3838
    function bp_blogs_register_activity_actions() { 
    4444                        __( 'New post comment posted', 'buddypress' ),
    4545                        'bp_blogs_format_activity_action_new_blog_comment',
    4646                        __( 'Comments', 'buddypress' ),
    47                         array( 'activity', 'member' ),
     47                        array( 'activity', 'member', 'blog' ),
    4848                        10
    4949                );
    5050        }
    5151
     52        // Only add subscription actions if blog is public
     53        if ( bp_current_blog_is_public() ) {
     54                bp_activity_set_action(
     55                buddypress()->blogs->id,
     56                        'site_subscription',
     57                        __( 'New site subscription', 'buddypress' ),
     58                        'bp_blogs_format_activity_action_new_site_subscription',
     59                        __( 'Site Subscription', 'buddypress' ),
     60                        array( 'activity', 'member', 'blog' ),
     61                        20
     62                );
     63        }
     64
    5265        /**
    5366         * Fires after the registry of the default blog component activity actions.
    5467         *
    function bp_blogs_format_activity_action_new_blog_comment( $action, $activity ) 
    281294}
    282295
    283296/**
     297 * Activity action callback for new site subscriptions
     298 *
     299 * @since BuddyPress (2.3.0)
     300 *
     301 * @param  string  $action      the content of the action
     302 * @param  BP_Activity_Activity the activity object
     303 * @return string  $action      the content of the action
     304 */
     305function bp_blogs_format_activity_action_new_site_subscription( $action = '', $activity = null ) {
     306        if ( empty( $activity->item_id ) ) {
     307                return $action;
     308        }
     309
     310        $user_link         = bp_core_get_userlink( $activity->user_id );
     311        $blog_name         = bp_blogs_get_blogmeta( $activity->item_id, 'name' );
     312        $blog_url          = bp_blogs_get_blogmeta( $activity->item_id, 'url' );
     313        $root_domain       = trailingslashit( bp_get_root_domain() );
     314
     315        if ( (int) $activity->item_id !== (int) bp_get_root_blog_id() ) {
     316                $view_details_link = trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . str_replace( $root_domain, '/', $blog_url ) );
     317        } else {
     318                $view_details_link = trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . '/' . apply_filters( 'bp_blogs_get_site_slug', 'root' ) );
     319        }
     320
     321        $action = sprintf(
     322                __( '%1$s subscribed to the site %2$s', 'bp-blogs-extended' ),
     323                $user_link,
     324                '<a href="' . esc_url( $view_details_link ) . '">' . esc_html( $blog_name ) . '</a>'
     325        );
     326
     327        return apply_filters( 'bp_blogs_format_activity_action_new_site_subscription', $action, $activity );
     328}
     329
     330/**
    284331 * Fetch data related to blogs at the beginning of an activity loop.
    285332 *
    286333 * This reduces database overhead during the activity loop.
  • 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..e66bcf2 100644
    add_action( 'bp_blogs_remove_blog_for_user', 'bp_blogs_clear_blog_object_cache', 
    5656add_action( 'wpmu_new_blog',                 'bp_blogs_clear_blog_object_cache', 10, 2 );
    5757add_action( 'bp_blogs_remove_blog',          'bp_blogs_clear_blog_object_cache' );
    5858
     59/**
     60 * Bust blog caches when editing or deleting.
     61 *
     62 * @since BuddyPress (2.3.0)
     63 *
     64 * @param int $blog_id The blog being edited.
     65 */
     66function bp_blogs_delete_blog_cache( $blog_id = 0 ) {
     67        wp_cache_delete( $blog_id, 'bp_blogs' );
     68}
     69add_action( 'refresh_blog_details',          'bp_blogs_delete_blog_cache' );
     70add_action( 'bp_blogs_remove_blog',          'bp_blogs_delete_blog_cache' );
     71add_action( 'bp_blogs_remove_data_for_blog', 'bp_blogs_delete_blog_cache' );
     72add_action( 'bp_blogs_remove_blog_for_user', 'bp_blogs_delete_blog_cache' );
     73
     74/**
     75 * Bust blogs caches when a user was deleted or marked as spam
     76 *
     77 * @since BuddyPress (2.3.0)
     78 *
     79 * @param int $blog_id The blog being edited.
     80 */
     81function bp_blogs_delete_blogs_cache( $user_id = 0 ) {
     82        $blogs = get_blogs_of_user( $user_id );
     83
     84        if ( empty( $blogs ) ) {
     85                return;
     86        }
     87
     88        foreach ( $blogs as $blog ) {
     89                wp_cache_delete( $blog->userblog_id, 'bp_blogs' );
     90        }
     91}
     92add_action( 'bp_blogs_before_remove_data', 'bp_blogs_delete_blogs_cache' );
     93
     94/**
     95 * Bust blog caches when a user or a blog option was edited
     96 *
     97 * @since BuddyPress (2.3.0)
     98 *
     99 * @param int $blog_id The blog being edited.
     100 */
     101function bp_blogs_delete_blog_cache_on_change() {
     102        if ( ! is_multisite() ) {
     103                return;
     104        }
     105
     106        $blog_id = get_current_blog_id();
     107
     108        wp_cache_delete( $blog_id, 'bp_blogs' );
     109}
     110add_action( 'set_user_role',                              'bp_blogs_delete_blog_cache_on_change' );
     111add_action( 'update_option_blogname',                     'bp_blogs_delete_blog_cache_on_change' );
     112add_action( 'update_option_blogdescription',              'bp_blogs_delete_blog_cache_on_change' );
     113add_action( 'update_option_thread_comments_depth',        'bp_blogs_delete_blog_cache_on_change' );
     114add_action( 'update_option_thread_comments',              'bp_blogs_delete_blog_cache_on_change' );
     115add_action( 'update_option_close_comments_days_old',      'bp_blogs_delete_blog_cache_on_change' );
     116add_action( 'update_option_close_comments_for_old_posts', 'bp_blogs_delete_blog_cache_on_change' );
     117
    59118// List actions to clear super cached pages on, if super cache is installed
    60119add_action( 'bp_blogs_remove_data_for_blog', 'bp_core_clear_cache' );
    61120add_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 d29e005..ee1262d 100644
    function bp_blogs_has_directory() { 
    2323}
    2424
    2525/**
     26 * Fetch a single blog object.
     27 *
     28 * @since  BuddyPress (2.3.0)
     29 *
     30 * @param array $args {
     31 *      Array of arguments.
     32 *      @type int $blog_id ID of the blog.
     33 *      @type bool $populate_extras Whether to fetch extra information about the blog.
     34 *                 Default: True.
     35 * @return BP_Blogs_Blog $blog The blog object.
     36 */
     37function bp_blogs_get_blog( $args = '' ) {
     38        // Parse query arguments
     39        $r = bp_parse_args( $args, array(
     40                'blog_id'         => 0,
     41                'populate_extras' => true // Whether to populate blogmeta
     42        ), 'blogs_get_blog' );
     43
     44        $blog_args = array(
     45                'populate_extras' => $r['populate_extras'],
     46        );
     47
     48        if ( $r['populate_extras'] ) {
     49                // Check cache for blog data
     50                $blog = wp_cache_get( $r['blog_id'], 'bp_blogs' );
     51
     52                // Got Cache
     53                if ( false !== $blog ) {
     54                        return $blog;
     55                }
     56        }
     57
     58        $blog = new BP_Blogs_Blog( $r['blog_id'], $blog_args );
     59
     60        if ( $r['populate_extras'] && ! empty( $blog->id ) ) {
     61                wp_cache_set( $blog->id, $blog, 'bp_blogs' );
     62        }
     63
     64        /**
     65         * Filters a single blog object.
     66         *
     67         * @since BuddyPress (2.3.0)
     68         *
     69         * @param BP_Blogs_Blog $blog Single blog object.
     70         */
     71        return apply_filters( 'bp_blogs_get_blog', $blog );
     72}
     73
     74/**
     75 * Get the BP_Blogs_Blog object corresponding to the current blog.
     76 *
     77 * @since BuddyPress (2.3.0)
     78 *
     79 * @return BP_Blogs_Blog The current blog object.
     80 */
     81function bp_blogs_get_current_blog() {
     82        $bp = buddypress();
     83
     84        $current_blog = false;
     85
     86        if ( isset( $bp->blogs->current_blog ) ) {
     87                $current_blog = $bp->blogs->current_blog;
     88        }
     89
     90        /**
     91         * Filters the BP_Blogs_Blog object corresponding to the current blog.
     92         *
     93         * @since BuddyPress (2.3.0)
     94         *
     95         * @param BP_Blogs_Blog $current_blog Current BP_Blogs_Blog object.
     96         */
     97        return apply_filters( 'bp_blogs_get_current_blog', $current_blog );
     98}
     99
     100/**
     101 * Is the user able to access to single blog's content
     102 *
     103 * @since BuddyPress (2.3.0)
     104 * @uses apply_filters() Filter bp_current_blog_has_access to modify the access to the blog
     105 *
     106 * @return bool true if the user can access, false otherwise
     107 */
     108function bp_current_blog_has_access() {
     109        $current_blog    = bp_blogs_get_current_blog();
     110        $has_access      = false;
     111
     112        if ( isset( $current_blog->user_has_access ) ) {
     113                $has_access = $current_blog->user_has_access;
     114        }
     115
     116        /**
     117         * Filters the access to the current blog
     118         *
     119         * @since BuddyPress (2.3.0)
     120         *
     121         * @param bool   $has_access true if user can access, false otherwise.
     122         * @param object $current_blog Instance holding the current blog.
     123         */
     124        return (bool) apply_filters( 'bp_current_blog_has_access', $has_access, $current_blog );
     125}
     126
     127/**
     128 * Is the current blog item public
     129 *
     130 * @since BuddyPress (2.3.0)
     131 * @uses apply_filters() Filter bp_is_blog_public to edit the blog visibility
     132 *
     133 * @return bool true if the blog is public, false otherwise
     134 */
     135function bp_current_blog_is_public() {
     136        $current_blog    = bp_blogs_get_current_blog();
     137        $is_public       = false;
     138
     139        if ( isset( $current_blog->blog_public ) ) {
     140                $is_public = $current_blog->blog_public;
     141        }
     142
     143        /**
     144         * Filters activity visibility of the blog
     145         *
     146         * @since BuddyPress (2.3.0)
     147         *
     148         * @param bool   $is_public true if blog is public, false otherwise.
     149         * @param object $current_blog Instance holding the current blog.
     150         */
     151        return (bool) apply_filters( 'bp_is_blog_public', $is_public, $current_blog );
     152}
     153
     154/**
     155 * Can users subscribe to the current blog
     156 *
     157 * @since BuddyPress (2.3.0)
     158 * @uses apply_filters() Filter bp_current_blog_can_subscribe to edit the ability to join the blog
     159 *
     160 * @return bool true if users can subscribe to the current blog, false otherwise
     161 */
     162function bp_current_blog_can_subscribe() {
     163        $current_blog    = bp_blogs_get_current_blog();
     164
     165        // Defaults to site's visibility
     166        $can_subscribe   = bp_current_blog_is_public();
     167
     168
     169        if ( isset( $current_blog->disallow_subscriptions ) ) {
     170                $can_subscribe = ! $current_blog->disallow_subscriptions;
     171        }
     172
     173        /**
     174         * Filters subscriptions setting for the blog
     175         *
     176         * @since BuddyPress (2.3.0)
     177         *
     178         * @param bool   $can_subscribe true if subscription are enabled, false otherwise.
     179         * @param object $current_blog Instance holding the current blog.
     180         */
     181        return (bool) apply_filters( 'bp_current_blog_can_subscribe', $can_subscribe, $current_blog );
     182}
     183
     184/**
     185 * Is current user a member of the current blog ?
     186 *
     187 * @since BuddyPress (2.3.0)
     188 * @uses apply_filters() Filter bp_current_blog_is_member to edit the user membership
     189 *
     190 * @return bool true if the user is a member of the current blog, false otherwise
     191 */
     192function bp_current_blog_is_member() {
     193        $current_blog    = bp_blogs_get_current_blog();
     194        $is_member       = false;
     195
     196
     197        if ( isset( $current_blog->is_member ) ) {
     198                $is_member = $current_blog->is_member;
     199        }
     200
     201        /**
     202         * Filters subscriptions setting for the blog
     203         *
     204         * @since BuddyPress (2.3.0)
     205         *
     206         * @param bool   $is_member true if the user is a member of the current blog, false otherwise.
     207         * @param object $current_blog Instance holding the current blog.
     208         */
     209        return (bool) apply_filters( 'bp_current_blog_is_member', $is_member, $current_blog );
     210}
     211
     212/**
     213 * Adds a relationship between a user and a blog
     214 *
     215 * We don't use bp_blogs_add_user_to_blog() to avoid recording blogmetas
     216 * @see bp_blogs_record_blog()
     217 *
     218 * @since BuddyPress (2.3.0)
     219 *
     220 * @return bool true if the relationship was created, false otherwise
     221 */
     222function bp_blogs_link_user_to_blog( $user_id = 0, $blog_id = 0 ) {
     223        if ( empty( $user_id ) || empty( $blog_id ) ) {
     224                return false;
     225        }
     226
     227        // Create the relationship between user & blog
     228        $join_blog = new BP_Blogs_Blog;
     229        $join_blog->user_id = $user_id;
     230        $join_blog->blog_id = $blog_id;
     231
     232        if ( ! $join_blog->save() ) {
     233                return false;
     234        }
     235
     236        return true;
     237}
     238
     239/**
     240 * Subscribe a user to a blog
     241 *
     242 * @since BuddyPress (2.3.0)
     243 *
     244 * @return array the result in a feedback array
     245 */
     246function bp_blogs_join_blog() {
     247        $blog = bp_blogs_get_current_blog();
     248
     249        if ( ! bp_current_blog_can_subscribe() || empty( $blog->id ) ) {
     250                return array(
     251                        'message' => __( 'We were not able to perform this action, please try again later', 'bp-blogs-extended' ),
     252                        'type'    => 'error',
     253                );
     254        }
     255
     256        // No need to use this action
     257        remove_action( 'add_user_to_blog', 'bp_blogs_add_user_to_blog', 10, 3 );
     258
     259        // First WordPress
     260        $subscribed = add_user_to_blog( $blog->id, bp_loggedin_user_id(), 'subscriber' );
     261
     262        // Restore the action
     263        add_action( 'add_user_to_blog', 'bp_blogs_add_user_to_blog', 10, 3 );
     264
     265        if ( is_wp_error( $subscribed ) ) {
     266                $result = array(
     267                        'message' => $subscribed->get_error_message(),
     268                        'type'    => 'error',
     269                );
     270        } else {
     271                // Then BuddyPress
     272                bp_blogs_link_user_to_blog( bp_loggedin_user_id(), $blog->id );
     273
     274                $result = array(
     275                        'message' => __( 'You successfully joined to the site.', 'bp-blogs-extended' ),
     276                        'type'    => '',
     277                );
     278
     279                $user_link = bp_core_get_userlink( bp_loggedin_user_id() );
     280
     281                $action = sprintf(
     282                        __( '%1$s subscribed to the site %2$s', 'bp-blogs-extended' ),
     283                        $user_link,
     284                        '<a href="' . esc_url( bp_get_blog_view_details_link() ) . '">' . esc_html( $blog->name ) . '</a>'
     285                );
     286
     287                bp_blogs_record_activity( array(
     288                        'action'  => $action,
     289                        'type'    => 'site_subscription',
     290                        'item_id' => $blog->id,
     291                ) );
     292
     293                // Update the blog's last activity.
     294                bp_blogs_update_blogmeta( $blog->id, 'last_activity', bp_core_current_time() );
     295        }
     296
     297        return $result;
     298}
     299
     300/**
     301 * Unsubscribe a user from a blog
     302 *
     303 * @since BuddyPress (2.3.0)
     304 *
     305 * @return array the result in a feedback array
     306 */
     307function bp_blogs_leave_blog() {
     308        $blog = bp_blogs_get_current_blog();
     309
     310        if ( empty( $blog->id ) || bp_is_item_admin() ) {
     311                return array(
     312                        'message' => __( 'We were not able to perform this action, please try again later', 'bp-blogs-extended' ),
     313                        'type'    => 'error',
     314                );
     315        }
     316
     317        /**
     318         * bp_blogs_remove_user_from_blog() will hook WordPress to remove
     319         * the link between the user and the blog
     320         */
     321        $unsubscribed = remove_user_from_blog( bp_loggedin_user_id(), $blog->id );
     322
     323        if ( is_wp_error( $unsubscribed ) ) {
     324                $result = array(
     325                        'message' => $unsubscribed->get_error_message(),
     326                        'type'    => 'error',
     327                );
     328        } else {
     329                $result = array(
     330                        'message' => __( 'You successfully left the site.', 'buddypress' ),
     331                        'type'    => '',
     332                );
     333
     334                bp_blogs_delete_activity( array(
     335                        'user_id' => bp_loggedin_user_id(),
     336                        'item_id' => $blog->id,
     337                        'type'    => 'site_subscription',
     338                ) );
     339        }
     340
     341        return $result;
     342}
     343
     344/** Blog Avatars ***************************************************************/
     345
     346/**
     347 * Generate the avatar upload directory path for a given blog.
     348 *
     349 * @since BuddyPress (2.3.0)
     350 *
     351 * @param int $blog_id Optional. ID of the blog. Default: ID of the
     352 *        current blog.
     353 * @return string
     354 */
     355function blogs_avatar_upload_dir( $blog_id = 0 ) {
     356
     357        if ( empty( $blog_id ) ) {
     358                $blog_id = bp_get_current_blog_id();
     359        }
     360
     361        $directory = 'blog-avatars';
     362        $path      = bp_core_avatar_upload_path() . '/' . $directory . '/' . $blog_id;
     363        $newbdir   = $path;
     364        $newurl    = bp_core_avatar_url() . '/' . $directory . '/' . $blog_id;
     365        $newburl   = $newurl;
     366        $newsubdir = '/' . $directory . '/' . $blog_id;
     367
     368        /**
     369         * Filters the avatar upload directory path for a given blog.
     370         *
     371         * @since BuddyPress (2.3.0)
     372         *
     373         * @param array $value Array of parts related to the blog avatar upload directory.
     374         */
     375        return apply_filters( 'blogs_avatar_upload_dir', array(
     376                'path'    => $path,
     377                'url'     => $newurl,
     378                'subdir'  => $newsubdir,
     379                'basedir' => $newbdir,
     380                'baseurl' => $newburl,
     381                'error'   => false
     382        ) );
     383}
     384
     385/**
     386 * Check if avatar uploads are enabled
     387 *
     388 * @since BuddyPress (2.3.0)
     389 *
     390 * @return bool true if avatar uploads are enabled, false otherwise.
     391 */
     392function bp_blogs_is_avatar_uploads_enabled() {
     393        $bp = buddypress();
     394
     395        // If Blogs single items are disabled no need to carry on.
     396        if ( true === (bool) apply_filters( 'bp_blogs_disable_single_items', false ) ) {
     397                return false;
     398        }
     399
     400        /**
     401         * Check if :
     402         * - user can upload avatars
     403         * - the WordPress show avatars setting is enabled
     404         * - the new avatar UI is not disabled.
     405         */
     406        $is_avatar_enabled = ! (int) $bp->site_options['bp-disable-avatar-uploads'] && $bp->avatar->show_avatars && false !== (bool) apply_filters( 'bp_avatar_is_front_edit', true );
     407
     408        /**
     409         * Filters the ability to set an avatar for a given blog.
     410         *
     411         * @since BuddyPress (2.3.0)
     412         *
     413         * @param bool $is_avatar_enabled true if avatar uploads are enabled, false otherwise.
     414         */
     415        return (bool) apply_filters( 'bp_blogs_is_avatar_uploads_enabled', $is_avatar_enabled );
     416}
     417
     418/**
    26419 * Retrieve a set of blogs
    27420 *
    28421 * @see BP_Blogs_Blog::get() for a description of arguments and return value.
  • src/bp-blogs/bp-blogs-loader.php

    diff --git src/bp-blogs/bp-blogs-loader.php src/bp-blogs/bp-blogs-loader.php
    index 36c2799..f1b7b00 100644
    class BP_Blogs_Component extends BP_Component { 
    7777                // Setup the globals
    7878                parent::setup_globals( $args );
    7979
    80                 /*
     80                /**
    8181                 * Set up the post post type to track.
    8282                 *
    8383                 * In case the config is not multisite, the blog_public option is ignored.
    class BP_Blogs_Component extends BP_Component { 
    100100
    101101                // Filter the generic track parameters for the 'post' post type.
    102102                add_filter( 'bp_activity_get_post_type_tracking_args', array( $this, 'post_tracking_args' ), 10, 2 );
     103
     104                /** Single Blog globals ***********************************************/
     105
     106                /**
     107                 * Use th filter 'bp_blogs_disable_single_items' to disable blogs single item for your network
     108                 *
     109                 * @since  BuddyPress (2.3.0)
     110                 *
     111                 * @param  boolean true to disable the blogs single item feature, false otherwise
     112                 */
     113                if ( is_multisite() && bp_is_blogs_component() && bp_current_action() && true !== apply_filters( 'bp_blogs_disable_single_items', false ) ) {
     114
     115                        /**
     116                         * Set the blogs single nav
     117                         *
     118                         * We need to do this early so that we can manage item access
     119                         * within the single nav
     120                         */
     121                        $this->single_nav    = array();
     122                        $this->single_subnav = array();
     123
     124                        // Sort the single item nav
     125                        add_action( 'wp_head', array( $this, 'sort_single_item_nav' ) );
     126
     127                        /**
     128                         * Use this filter to define a new slug for the network root site
     129                         *
     130                         * @since  BuddyPress (2.3.0)
     131                         *
     132                         * @param  string $slug the alias for the network root slug
     133                         */
     134                        if ( bp_is_current_action( apply_filters( 'bp_blogs_get_site_slug', 'root' ) ) ) {
     135                                $blog_id = get_current_site()->id;
     136                        } else {
     137                                $blog_id = get_id_from_blogname( bp_current_action() );
     138                        }
     139
     140                        // Set the current blog data
     141                        $this->current_blog = bp_blogs_get_blog( array( 'blog_id' => $blog_id ) );
     142
     143                        if ( empty( $this->current_blog->id ) ) {
     144                                $this->current_blog = 0;
     145                                bp_do_404();
     146                                return;
     147                        }
     148
     149                        // It's a blog single item
     150                        $bp->is_single_item  = true;
     151                        $bp->current_item   = $this->current_blog->slug;
     152                        $bp->current_action = bp_action_variable( 0 );
     153                        array_shift( $bp->action_variables );
     154
     155                        // By Default grant access
     156                        $this->current_blog->user_has_access = true;
     157
     158                        // If blog is not public, non members can't access
     159                        if ( ! $this->current_blog->blog_public && ! $this->current_blog->is_member ) {
     160                                $this->current_blog->user_has_access = false;
     161                        }
     162
     163                        $admin_keys = array_flip( wp_list_pluck( $this->current_blog->admins, 'ID' ) );
     164
     165                        if ( is_super_admin() || isset( $admin_keys[ bp_loggedin_user_id() ] ) ) {
     166                                bp_update_is_item_admin( true, $bp->blogs->id );
     167                        }
     168
     169                        // Check once if the current blog has a custom front template
     170                        $this->current_blog->front_template = bp_blogs_get_blog_front_template( $this->current_blog );
     171                }
     172        }
     173
     174        /**
     175         * Set up canonical stack for this component.
     176         *
     177         * @since BuddyPress (2.3.0)
     178         */
     179        public function setup_canonical_stack() {
     180                $bp = buddypress();
     181
     182                if ( ! bp_is_blogs_component() ) {
     183                        return;
     184                }
     185
     186                if ( empty( $this->current_blog ) ) {
     187                        return;
     188                }
     189
     190                if ( ! bp_current_action() ) {
     191                        $bp->current_action = 'home';
     192                }
     193
     194                // Prepare for a redirect to the canonical URL
     195                $bp->canonical_stack['base_url'] = trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . '/'. $this->current_blog->slug );
     196
     197                if ( bp_current_action() ) {
     198                        $bp->canonical_stack['action'] = bp_current_action();
     199                }
     200
     201                if ( ! empty( $bp->action_variables ) ) {
     202                        $bp->canonical_stack['action_variables'] = bp_action_variables();
     203                }
     204
     205                // When viewing the default extension, the canonical URL should not have
     206                // that extension's slug, unless more has been tacked onto the URL via
     207                // action variables
     208                if ( bp_is_current_action( 'home' ) && empty( $bp->action_variables ) )  {
     209                        unset( $bp->canonical_stack['action'] );
     210                }
    103211        }
    104212
    105213        /**
    class BP_Blogs_Component extends BP_Component { 
    153261                        return false;
    154262                }
    155263
    156                 // Add 'Sites' to the main navigation
    157                 $count    = (int) bp_get_total_blog_count_for_user();
    158                 $class    = ( 0 === $count ) ? 'no-count' : 'count';
    159                 $nav_text = sprintf( __( 'Sites <span class="%s">%s</span>', 'buddypress' ), esc_attr( $class ), number_format_i18n( $count )  );
    160                 $main_nav = array(
    161                         'name'                => $nav_text,
    162                         'slug'                => $this->slug,
    163                         'position'            => 30,
    164                         'screen_function'     => 'bp_blogs_screen_my_blogs',
    165                         'default_subnav_slug' => 'my-sites',
    166                         'item_css_id'         => $this->id
    167                 );
    168 
    169264                // Determine user to use
    170265                if ( bp_displayed_user_domain() ) {
    171266                        $user_domain = bp_displayed_user_domain();
    172267                } elseif ( bp_loggedin_user_domain() ) {
    173268                        $user_domain = bp_loggedin_user_domain();
    174269                } else {
    175                         return;
     270                        $user_domain = false;
    176271                }
    177272
    178                 $parent_url = trailingslashit( $user_domain . bp_get_blogs_slug() );
     273                if ( ! empty( $user_domain ) ) {
     274                        // Add 'Sites' to the main navigation
     275                        $count    = (int) bp_get_total_blog_count_for_user();
     276                        $class    = ( 0 === $count ) ? 'no-count' : 'count';
     277                        $nav_text = sprintf( __( 'Sites <span class="%s">%s</span>', 'buddypress' ), esc_attr( $class ), number_format_i18n( $count )  );
     278                        $main_nav = array(
     279                                'name'                => $nav_text,
     280                                'slug'                => $this->slug,
     281                                'position'            => 30,
     282                                'screen_function'     => 'bp_blogs_screen_my_blogs',
     283                                'default_subnav_slug' => 'my-sites',
     284                                'item_css_id'         => $this->id
     285                        );
    179286
    180                 $sub_nav[] = array(
    181                         'name'            => __( 'My Sites', 'buddypress' ),
    182                         'slug'            => 'my-sites',
    183                         'parent_url'      => $parent_url,
    184                         'parent_slug'     => $bp->blogs->slug,
    185                         'screen_function' => 'bp_blogs_screen_my_blogs',
    186                         'position'        => 10
    187                 );
     287                        $parent_url = trailingslashit( $user_domain . bp_get_blogs_slug() );
     288
     289                        $sub_nav[] = array(
     290                                'name'            => __( 'My Sites', 'buddypress' ),
     291                                'slug'            => 'my-sites',
     292                                'parent_url'      => $parent_url,
     293                                'parent_slug'     => $bp->blogs->slug,
     294                                'screen_function' => 'bp_blogs_screen_my_blogs',
     295                                'position'        => 10
     296                        );
     297
     298                        // Setup navigation
     299                        parent::setup_nav( $main_nav, $sub_nav );
     300                }
     301
     302                if ( bp_is_blogs_component() && bp_is_single_item() ) {
     303
     304                        $main_nav_items = array(
     305                                array(
     306                                        'name'                => __( 'Home', 'buddypress' ),
     307                                        'slug'                => 'home',
     308                                        'position'            => 0,
     309                                        'screen_function'     => 'bp_blogs_screen_blog_home',
     310                                        'default_subnav_slug' => false,
     311                                        'item_css_id'         => 'all',
     312                                        'single_nav'          => $this->id,
     313                                ),
     314                        );
     315
     316                        if ( bp_current_blog_has_access() ) {
     317
     318                                if ( $this->current_blog->front_template || ( bp_is_active( 'activity' ) && bp_current_blog_is_public() ) ) {
     319                                        /**
     320                                         * Only add the members nav if it's not the home's nav
     321                                         */
     322                                        $main_nav_items[] = array(
     323                                                'name'                => sprintf( _x( 'Members <span>%s</span>', 'Single Blog members screen nav', 'buddypress' ), $this->current_blog->total_member_count ),
     324                                                'slug'                => 'members',
     325                                                'position'            => 20,
     326                                                'screen_function'     => 'bp_blogs_screen_blog_home',
     327                                                'default_subnav_slug' => false,
     328                                                'item_css_id'         => 'all',
     329                                                'single_nav'          => $this->id,
     330                                        );
     331
     332                                        /**
     333                                         * If the theme is using a custom front, create
     334                                         * an activity nav if the blog is public
     335                                         */
     336                                        if ( $this->current_blog->front_template && bp_is_active( 'activity' ) && bp_current_blog_is_public() ) {
     337                                                $main_nav_items[] = array(
     338                                                        'name'                => _x( 'Activity', 'Single Blog activity screen nav', 'buddypress' ),
     339                                                        'slug'                => 'activity',
     340                                                        'position'            => 10,
     341                                                        'screen_function'     => 'bp_blogs_screen_blog_home',
     342                                                        'default_subnav_slug' => false,
     343                                                        'item_css_id'         => 'all',
     344                                                        'single_nav'          => $this->id,
     345                                                );
     346                                        }
     347                                }
     348
     349                                if ( bp_is_item_admin() ) {
     350                                        // Manage Main nav
     351                                        $main_nav_items[] = array(
     352                                                'name'                => _x( 'Manage', 'Single Blog manage screen nav', 'buddypress' ),
     353                                                'slug'                => 'manage',
     354                                                'position'            => 1000,
     355                                                'screen_function'     => 'bp_blogs_screen_blog_settings',
     356                                                'default_subnav_slug' => 'manage',
     357                                                'single_nav'          => $this->id,
     358                                        );
     359                                }
     360                        }
    188361
    189                 // Setup navigation
    190                 parent::setup_nav( $main_nav, $sub_nav );
     362                        /**
     363                         * Use this filter if you want to add/remove nav items
     364                         *
     365                         * @since  BuddyPress (2.3.0)
     366                         *
     367                         * @param  array         $main_nav_items the current blog subnav items
     368                         * @param  BP_Blogs_Blog $current_blog the current blog object
     369                         */
     370                        foreach ( (array) apply_filters( 'bp_blogs_current_blog_nav_items', $main_nav_items, $this->current_blog ) as $main_nav_item ) {
     371                                bp_core_new_nav_item( $main_nav_item );
     372                        }
     373
     374                        /** Sub nav items - only manage needs some for now */
     375
     376                        $sub_nav_items = array();
     377                        $blog_link     = trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . '/'. $this->current_blog->slug );
     378
     379                        if ( bp_is_item_admin() ) {
     380                                /**
     381                                 * General settings
     382                                 *
     383                                 * Edit the preferences for the current blog
     384                                 * Access is restricted to The blog admins
     385                                 */
     386
     387                                $sub_nav_items[] = array(
     388                                        'name'            => _x( 'Edit Settings', 'Single Blog setting screen', 'buddypress' ),
     389                                        'slug'            => 'manage',
     390                                        'parent_url'      => trailingslashit( $blog_link . 'manage' ),
     391                                        'parent_slug'     => 'manage',
     392                                        'screen_function' => 'bp_blogs_screen_blog_settings',
     393                                        'position'        => 0,
     394                                        'user_has_access' => bp_is_item_admin(),
     395                                        'single_subnav'   => $this->id,
     396                                );
     397
     398                                /**
     399                                 * Site logo
     400                                 *
     401                                 * Edit the logo for the current blog
     402                                 * Access is restricted to The blog admins
     403                                 */
     404                                if ( bp_blogs_is_avatar_uploads_enabled() ) {
     405                                        $sub_nav_items[] = array(
     406                                                'name'            => _x( 'Edit Logo', 'Single Blog photo screen', 'buddypress' ),
     407                                                'slug'            => 'edit-logo',
     408                                                'parent_url'      => trailingslashit( $blog_link . 'manage' ),
     409                                                'parent_slug'     => 'manage',
     410                                                'screen_function' => 'bp_blogs_screen_blog_settings',
     411                                                'position'        => 10,
     412                                                'user_has_access' => bp_is_item_admin(),
     413                                                'single_subnav'   => $this->id,
     414                                        );
     415                                }
     416                        }
     417
     418                        /**
     419                         * Use this filter if you want to add/remove subnav items
     420                         *
     421                         * @since  BuddyPress (2.3.0)
     422                         *
     423                         * @param  array         $sub_nav_items the current blog subnav items
     424                         * @param  BP_Blogs_Blog $current_blog the current blog object
     425                         * @param  string        $blog_link the current blog view details link
     426                         */
     427                        foreach ( (array) apply_filters( 'bp_blogs_current_blog_subnav_items', $sub_nav_items, $this->current_blog, $blog_link ) as $sub_nav_item ) {
     428                                bp_core_new_subnav_item( $sub_nav_item );
     429                        }
     430                }
    191431        }
    192432
    193433        /**
    class BP_Blogs_Component extends BP_Component { 
    260500                                        $bp->bp_options_title = __( 'My Sites', 'buddypress' );
    261501                                }
    262502
     503                        // We are viewing a single blog, so set up the
     504                        // blog title tag using the $this->current_blog global.
     505                        } elseif ( bp_is_single_item() ) {
     506                                $bp->bp_options_title  = $this->current_blog->name;
     507                                $bp->bp_options_avatar = bp_core_fetch_avatar( array(
     508                                        'item_id'    => $this->current_blog->id,
     509                                        'object'     => 'blog',
     510                                        'type'       => 'thumb',
     511                                        'avatar_dir' => 'blog-avatars',
     512                                        'alt'        => __( 'Site logo', 'buddypress' )
     513                                ) );
     514
     515                                if ( empty( $bp->bp_options_avatar ) ) {
     516                                        $bp->bp_options_avatar = '<img src="' . esc_url( bp_core_avatar_default_thumb() ) . '" alt="' . esc_attr__( 'No Site logo', 'buddypress' ) . '" class="avatar" />';
     517                                }
     518
    263519                        // If we are not viewing the logged in user, set up the current
    264520                        // users avatar and name
    265521                        } else {
    class BP_Blogs_Component extends BP_Component { 
    284540
    285541                // Global groups
    286542                wp_cache_add_global_groups( array(
    287                         'blog_meta'
     543                        'blog_meta',
     544                        'bp_blogs'
    288545                ) );
    289546
    290547                parent::setup_cache_groups();
    class BP_Blogs_Component extends BP_Component { 
    308565                $params->admin_filter    = __( 'New post published', 'buddypress' );
    309566                $params->format_callback = 'bp_blogs_format_activity_action_new_blog_post';
    310567                $params->front_filter    = __( 'Posts', 'buddypress' );
    311                 $params->contexts        = array( 'activity', 'member' );
     568                $params->contexts        = array( 'activity', 'member', 'blog' );
    312569                $params->position        = 5;
    313570
    314571                return $params;
    315572        }
     573
     574        /**
     575         * Sort the current blog's nav
     576         *
     577         * @since BuddyPress (2.3.0)
     578         */
     579        public function sort_single_item_nav() {
     580                bp_core_sort_nav_items( $this->id );
     581                bp_core_sort_subnav_items( $this->id );
     582        }
    316583}
    317584
    318585/**
  • 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..d2cb240 100644
    function bp_blogs_screen_index() { 
    6868}
    6969add_action( 'bp_screens', 'bp_blogs_screen_index', 2 );
    7070
     71/**
     72 * Home screen for the blogs single item
     73 *
     74 * @since BuddyPress (2.3.0)
     75 */
     76function bp_blogs_screen_blog_home() {
     77        if ( ! bp_is_single_item() ) {
     78                return false;
     79        }
     80
     81        do_action( 'bp_blogs_screen_blog_home' );
     82
     83        if ( ! empty( $_GET['action'] ) && ( 'join' === $_GET['action'] || 'leave' === $_GET['action'] ) ) {
     84                $action = sanitize_key( $_GET['action'] );
     85
     86                check_admin_referer( 'blogs_' . $action . '_blog' );
     87
     88                $referer = wp_get_referer();
     89                $result = array(
     90                        'message' => __( 'We were not able to perform this action, please try again later', 'bp-blogs-extended' ),
     91                        'type'    => 'error',
     92                );
     93
     94                if ( is_callable( 'bp_blogs_' . $action . '_blog' ) ) {
     95                        $result = call_user_func( 'bp_blogs_' . $action . '_blog' );
     96                }
     97
     98                bp_core_add_message( $result['message'], $result['type'] );
     99                bp_core_redirect( $referer );
     100        }
     101
     102        bp_core_load_template( apply_filters( 'bp_blogs_template_blog_home', 'blogs/single/home' ) );
     103}
     104
     105/**
     106 * Settings screen for the blogs single item
     107 *
     108 * @since BuddyPress (2.3.0)
     109 */
     110function bp_blogs_screen_blog_settings() {
     111        if ( ! bp_is_single_item() ) {
     112                return false;
     113        }
     114
     115        do_action( 'blogs_screen_blog_settings' );
     116
     117        if ( ! empty( $_POST['bp_blog']['submit'] ) ) {
     118
     119                check_admin_referer( 'blog_settings_general' );
     120
     121                unset( $_POST['bp_blog']['submit'] );
     122                $options = $_POST['bp_blog'];
     123
     124                if ( ! isset( $options['blog_public'] ) ) {
     125                        $options['blog_public'] = 0;
     126                }
     127
     128                $blog_id = bp_get_current_blog_id();
     129                $referer = wp_unslash( $_POST['_wp_http_referer'] );
     130                $message = __( 'We were not able to perform this action, please try again later', 'buddypress' );
     131
     132                if ( empty( $blog_id ) ) {
     133                        bp_core_add_message( $message, 'error' );
     134                        bp_core_redirect( $referer );
     135                }
     136
     137                $success = 'error';
     138
     139                // Update general settings
     140                if ( bp_get_root_blog_id() !== $blog_id ) {
     141                        $needs_reset = true;
     142                        switch_to_blog( $blog_id );
     143                }
     144
     145                if ( current_user_can( 'manage_options' ) ) {
     146
     147                        // This option will only be saved in BuddyPress blog metas
     148                        if ( isset( $options['disallow_subscriptions'] ) ) {
     149                                bp_blogs_update_blogmeta( $blog_id, 'disallow_subscriptions', intval( $options['disallow_subscriptions'] ) );
     150                                unset( $options['disallow_subscriptions'] );
     151                        } else {
     152                                bp_blogs_delete_blogmeta( $blog_id, 'disallow_subscriptions' );
     153                        }
     154
     155                        foreach ( $options as $key => $option ) {
     156                                $sanitized_option = sanitize_option( $key, $option );
     157
     158                                update_option( $key, $sanitized_option );
     159                        }
     160                        $message = __( 'Settings saved.', 'buddypress' );
     161                        $success = '';
     162
     163                } else {
     164                        $message = __( 'You cannot update this site&#39;s options.', 'buddypress' );
     165                }
     166
     167                if ( isset( $needs_reset ) ) {
     168                        restore_current_blog();
     169                }
     170
     171                // Redirect the user once done
     172                bp_core_add_message( $message, $success );
     173                bp_core_redirect( $referer );
     174        }
     175
     176        bp_core_load_template( apply_filters( 'bp_blogs_template_blog_settings', 'blogs/single/home' ) );
     177}
     178
    71179/** Theme Compatibility *******************************************************/
    72180
    73181/**
    74182 * The main theme compat class for BuddyPress Blogs
    75183 *
    76184 * 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.
     185 * blog template parts to the_title and the_content areas of a theme.
    78186 *
    79187 * @since BuddyPress (1.7.0)
    80188 */
    class BP_Blogs_Theme_Compat { 
    96204         */
    97205        public function is_blogs() {
    98206
    99                 // Bail if not looking at a group
     207                // Bail if not looking at a blog
    100208                if ( ! bp_is_blogs_component() )
    101209                        return;
    102210
    class BP_Blogs_Theme_Compat { 
    105213                        return;
    106214
    107215                // Blog Directory
    108                 if ( is_multisite() && ! bp_current_action() ) {
     216                if ( is_multisite() && ! bp_current_action() && ! bp_current_item() ) {
    109217                        bp_update_is_directory( true, 'blogs' );
    110218
    111219                        /**
    class BP_Blogs_Theme_Compat { 
    121229                        add_filter( 'bp_replace_the_content',                    array( $this, 'directory_content'    ) );
    122230
    123231                // Create blog
    124                 } elseif ( is_user_logged_in() && bp_blog_signup_enabled() ) {
     232                } elseif ( is_user_logged_in() && bp_blog_signup_enabled() && bp_is_create_blog() ) {
    125233                        add_filter( 'bp_get_buddypress_template',                array( $this, 'create_template_hierarchy' ) );
    126234                        add_action( 'bp_template_include_reset_dummy_post_data', array( $this, 'create_dummy_post' ) );
    127235                        add_filter( 'bp_replace_the_content',                    array( $this, 'create_content'    ) );
     236                } elseif ( bp_is_single_item() ) {
     237                        add_filter( 'bp_get_buddypress_template',                array( $this, 'single_template_hierarchy' ) );
     238                        add_action( 'bp_template_include_reset_dummy_post_data', array( $this, 'single_dummy_post' ) );
     239                        add_filter( 'bp_replace_the_content',                    array( $this, 'single_content'    ) );
    128240                }
    129241        }
    130242
    class BP_Blogs_Theme_Compat { 
    183295        }
    184296
    185297        /**
    186          * Filter the_content with the groups index template part.
     298         * Filter the_content with the blogs index template part.
    187299         *
    188300         * @since BuddyPress (1.7.0)
    189301         */
    class BP_Blogs_Theme_Compat { 
    260372        public function create_content() {
    261373                return bp_buffer_template_part( 'blogs/create', null, false );
    262374        }
     375
     376        /** Single ************************************************************/
     377
     378        /**
     379         * Add custom template hierarchy to theme compat for blog pages.
     380         *
     381         * This is to mirror how WordPress has
     382         * {@link https://codex.wordpress.org/Template_Hierarchy template hierarchy}.
     383         *
     384         * @since BuddyPress (2.3.0)
     385         *
     386         * @param string $templates The templates from bp_get_theme_compat_templates().
     387         * @return array $templates Array of custom templates to look for.
     388         */
     389        public function single_template_hierarchy( $templates ) {
     390                // Setup some variables we're going to reference in our custom templates
     391                $blog = bp_blogs_get_current_blog();
     392
     393                /**
     394                 * Filters the Blogs single pages template hierarchy based on priority.
     395                 *
     396                 * @since BuddyPress (2.3.0)
     397                 *
     398                 * @param array $value Array of default template files to use.
     399                 */
     400                $new_templates = apply_filters( 'bp_template_hierarchy_blogs_single_item', array(
     401                        'blogs/single/index-id-'     . sanitize_file_name( $blog->id )           . '.php',
     402                        'blogs/single/index-slug-'   . sanitize_file_name( $blog->slug )         . '.php',
     403                        'blogs/single/index-action-' . sanitize_file_name( bp_current_action() ) . '.php',
     404                        'blogs/single/index.php'
     405                ) );
     406
     407                // Merge new templates with existing stack
     408                // @see bp_get_theme_compat_templates()
     409                $templates = array_merge( (array) $new_templates, $templates );
     410
     411                return $templates;
     412        }
     413
     414        /**
     415         * Update the global $post with single blog data.
     416         *
     417         * @since BuddyPress (2.3.0)
     418         */
     419        public function single_dummy_post() {
     420                bp_theme_compat_reset_post( array(
     421                        'ID'             => 0,
     422                        'post_title'     => bp_get_current_blog_name(),
     423                        'post_author'    => 0,
     424                        'post_date'      => 0,
     425                        'post_content'   => '',
     426                        'post_type'      => 'page',
     427                        'post_status'    => 'publish',
     428                        'is_page'        => true,
     429                        'comment_status' => 'closed'
     430                ) );
     431        }
     432
     433        /**
     434         * Filter the_content with the single blog template part.
     435         *
     436         * @since BuddyPress (2.3.0)
     437         */
     438        public function single_content() {
     439                return bp_buffer_template_part( 'blogs/single/home', null, false );
     440        }
    263441}
    264442new 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 bd5f62d..4e00193 100644
    class BP_Blogs_Template { 
    197197         *        queried blogs.
    198198         * @param array $include_blog_ids Array of blog IDs to include.
    199199         */
    200         public function __construct( $type, $page, $per_page, $max, $user_id, $search_terms, $page_arg = 'bpage', $update_meta_cache = true, $include_blog_ids = false ) {
     200        public function __construct( $type, $page, $per_page, $max, $user_id, $search_terms, $page_arg = 'bpage', $update_meta_cache = true, $include_blog_ids = false, $slug = '' ) {
    201201
    202202                $this->pag_arg  = sanitize_key( $page_arg );
    203203                $this->pag_page = bp_sanitize_pagination_arg( $this->pag_arg, $page     );
    204204                $this->pag_num  = bp_sanitize_pagination_arg( 'num',          $per_page );
    205205
     206                // A blog item is requested
     207                if ( 'single-blog' === $type ) {
     208                        if ( bp_blogs_get_current_blog() ) {
     209                                $blog = bp_blogs_get_current_blog();
     210
     211                        } else {
     212                                $blog = bp_blogs_get_blog( array(
     213                                        'blog_id' => get_id_from_blogname( $slug ),
     214                                ) );
     215                        }
     216
     217                        $this->blogs = array( $blog );
     218
    206219                // Backwards compatibility support for blogs by first letter
    207                 if ( ! empty( $_REQUEST['letter'] ) ) {
     220                } elseif ( ! empty( $_REQUEST['letter'] ) ) {
    208221                        $this->blogs = BP_Blogs_Blog::get_by_letter( $_REQUEST['letter'], $this->pag_num, $this->pag_page );
    209222
    210223                // Typical blogs query
    class BP_Blogs_Template { 
    220233                        ) );
    221234                }
    222235
    223                 // Set the total blog count
    224                 if ( empty( $max ) || ( $max >= (int) $this->blogs['total'] ) ) {
    225                         $this->total_blog_count = (int) $this->blogs['total'];
     236                if ( 'single-blog' === $type ) {
     237                        if ( empty( $blog->id ) ) {
     238                                $this->total_blog_count = 0;
     239                                $this->blog_count       = 0;
     240                        } else {
     241                                $this->total_blog_count = 1;
     242                                $this->blog_count       = 1;
     243                        }
     244
    226245                } else {
    227                         $this->total_blog_count = (int) $max;
    228                 }
     246                        // Set the total blog count
     247                        if ( empty( $max ) || ( $max >= (int) $this->blogs['total'] ) ) {
     248                                $this->total_blog_count = (int) $this->blogs['total'];
     249                        } else {
     250                                $this->total_blog_count = (int) $max;
     251                        }
    229252
    230                 // Set the blogs array (to loop through later
    231                 $this->blogs = $this->blogs['blogs'];
     253                        // Set the blogs array (to loop through later
     254                        $this->blogs = $this->blogs['blogs'];
    232255
    233                 // Get the current blog count to compare maximum against
    234                 $blog_count = count( $this->blogs );
     256                        // Get the current blog count to compare maximum against
     257                        $blog_count = count( $this->blogs );
    235258
    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;
     259                        // Set the current blog count
     260                        if ( empty( $max ) || ( $max >= (int) $blog_count ) ) {
     261                                $this->blog_count = (int) $blog_count;
     262                        } else {
     263                                $this->blog_count = (int) $max;
     264                        }
    241265                }
    242266
    243267                // Build pagination links based on total blogs and current page number
    function bp_rewind_blogs() { 
    395419function bp_has_blogs( $args = '' ) {
    396420        global $blogs_template;
    397421
     422        $type         = 'active';
     423        $slug         = '';
     424        $current_blog = bp_blogs_get_current_blog();
     425
     426        if ( bp_get_current_blog_slug() ) {
     427                $type = 'single-blog';
     428                $slug = bp_get_current_blog_slug();
     429        }
     430
     431
    398432        // Check for and use search terms
    399433        $search_terms = ! empty( $_REQUEST['s'] )
    400434                ? $_REQUEST['s']
    function bp_has_blogs( $args = '' ) { 
    402436
    403437        // Parse arguments
    404438        $r = bp_parse_args( $args, array(
    405                 'type'              => 'active',
     439                'type'              => $type,
    406440                'page_arg'          => 'bpage',                // See https://buddypress.trac.wordpress.org/ticket/3679
    407441                'page'              => 1,
    408442                'per_page'          => 20,
    function bp_has_blogs( $args = '' ) { 
    410444                'user_id'           => bp_displayed_user_id(), // Pass a user_id to limit to only blogs this user is a member of
    411445                'include_blog_ids'  => false,
    412446                'search_terms'      => $search_terms,          // Pass search terms to filter on the blog title or description.
    413                 'update_meta_cache' => true
     447                'update_meta_cache' => true,
     448                'slug'              => $slug                   // Pass the slug of the blog in conjonction with a type set to 'single-blog'
    414449        ), 'has_blogs' );
    415450
    416451        // Set per_page to maximum if max is enforced
    function bp_has_blogs( $args = '' ) { 
    419454        }
    420455
    421456        // 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'] );
     457        $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'], $r['slug'] );
    423458
    424459        /**
    425460         * Filters whether or not there are blogs to list.
    function bp_blog_avatar( $args = '' ) { 
    555590                        'type'    => 'full',
    556591                        'width'   => false,
    557592                        'height'  => false,
    558                         'class'   => 'avatar',
     593                        'class'   => 'avatar blog-' . $blogs_template->blog->blog_id . '-avatar',
    559594                        'id'      => false,
    560595                        'alt'     => sprintf( __( 'Profile picture of site author %s', 'buddypress' ), bp_core_get_user_displayname( $blogs_template->blog->admin_user_id ) ),
    561596                        'no_grav' => true,
    562597                ) );
    563598
     599                /**
     600                 * If the Blogs single items are allowed, as people can subscribe to
     601                 * sites, when a subsriber looks at my sites, he can see his avatar
     602                 * for a site he's not an admin off. That's because BP_Blogs_Blog::get()
     603                 * is not really getting the admin of a blog but any member linked to it
     604                 * in the bp_user_blogs table.
     605                 *
     606                 * So as Blogs can now set avatars, let's use the mystery man to avoid
     607                 * some confusions..
     608                 */
     609                if ( true !== apply_filters( 'bp_blogs_disable_single_items', false ) ) {
     610                        $object     = 'blog';
     611                        $avatar_dir = 'blog-avatars';
     612                        $item_id    = $blogs_template->blog->blog_id;
     613                        $title      = $blogs_template->blog->name;
     614                        $r['class'] = 'avatar';
     615                        $r['alt']   = sprintf( __( 'Site logo of %s', 'buddypress' ), $blogs_template->blog->name );
     616
     617                } else {
     618                        // Defaults to the admin avatar
     619                        $item_id    = $blogs_template->blog->admin_user_id;
     620                        $title      = $blogs_template->blog->admin_user_email;
     621                        $object     = 'user';
     622                        $avatar_dir = 'avatars';
     623                }
     624
    564625                // Fetch the avatar
    565626                $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',
     627                        'item_id'    => $item_id,
     628                        'title'      => $title,
     629                        'avatar_dir' => $avatar_dir,
     630                        'object'     => $object,
    570631                        'type'       => $r['type'],
    571632                        'alt'        => $r['alt'],
    572633                        'css_id'     => $r['id'],
    function bp_blog_avatar( $args = '' ) { 
    575636                        'height'     => $r['height']
    576637                ) );
    577638
    578                 /***
    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                  *
    583                  * This filter is deprecated as of BuddyPress 1.5 and may be removed in a future version.
    584                  * Use the 'bp_get_blog_avatar' filter instead.
    585                  */
    586                 $avatar = apply_filters( 'bp_get_blog_avatar_' . $blogs_template->blog->blog_id, $avatar );
    587 
    588639                /**
    589640                 * Filters a blog's avatar.
    590641                 *
    function bp_blog_avatar( $args = '' ) { 
    598649                return apply_filters( 'bp_get_blog_avatar', $avatar, $blogs_template->blog->blog_id, $r );
    599650        }
    600651
     652/**
     653 * Output the link to the single blog item
     654 *
     655 * @since  BuddyPress (2.3.0)
     656 */
     657function bp_blog_view_details_link() {
     658        echo bp_get_blog_view_details_link();
     659}
     660
     661        /**
     662         * Return the link to the single blog item
     663         *
     664         * @since  BuddyPress (2.3.0)
     665         *
     666         * @param  object $blog the blog to get the view details link for
     667         * @return string the  link to the blog's single item
     668         */
     669        function bp_get_blog_view_details_link() {
     670                global $blogs_template;
     671                $slug = false;
     672
     673                if ( isset( $blogs_template->blog ) ) {
     674                        $blog = $blogs_template->blog;
     675                } else {
     676                        $blog = bp_blogs_get_current_blog();
     677                }
     678
     679                if ( isset( $blog->slug ) ) {
     680                        $slug = $blog->slug;
     681                } elseif ( isset( $blog->path ) ) {
     682                        $slug = str_replace( '/', '', $blog->path );
     683
     684                        if ( empty( $slug ) && bp_get_root_blog_id() == $blog->blog_id ) {
     685                                $slug = apply_filters( 'bp_blogs_get_site_slug', 'root' );
     686                        }
     687                }
     688
     689                $view_details_link = trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . '/' . $slug );
     690
     691                /**
     692                 * Filters the blog view details link.
     693                 *
     694                 * @since BuddyPress (2.3.0)
     695                 *
     696                 * @param string $view_details_link Permalink URL to the profile of the blog.
     697                 */
     698                return apply_filters( 'bp_get_blog_view_details_link', $view_details_link );
     699        }
     700
    601701function bp_blog_permalink() {
    602702        echo bp_get_blog_permalink();
    603703}
    604704        function bp_get_blog_permalink() {
    605705                global $blogs_template;
    606706
    607                 if ( empty( $blogs_template->blog->domain ) )
     707                if ( empty( $blogs_template->blog->domain ) ) {
    608708                        $permalink = bp_get_root_domain() . $blogs_template->blog->path;
    609                 else {
     709                } else {
    610710                        $protocol = 'http://';
    611711                        if ( is_ssl() )
    612712                                $protocol = 'https://';
    function bp_total_blog_count_for_user( $user_id = 0 ) { 
    11081208        }
    11091209        add_filter( 'bp_get_total_blog_count_for_user', 'bp_core_number_format' );
    11101210
     1211/**
     1212 * Prints a message if the user has no access to the blog's content
     1213 *
     1214 * @since BuddyPress (2.3.0)
     1215 *
     1216 * @global BP_Blogs_Template $blogs_template Blogs template object
     1217 * @param object $blog Blog to get status message for. Optional; defaults to current blog.
     1218 */
     1219function bp_blog_status_message( $blog = null ) {
     1220        global $blogs_template;
     1221
     1222        // Blog not passed so look for loop
     1223        if ( empty( $blog ) ) {
     1224                $blog =& $blogs_template->blog;
     1225        }
     1226
     1227        $message = false;
     1228
     1229        // For now display a message if the blog is not public
     1230        if ( empty( $blog->blog_public ) ) {
     1231                $message = __( 'The details of this site are restricted to its members.', 'buddypress' );
     1232        }
     1233
     1234        /**
     1235         * Filters a message if the blog is not public.
     1236         *
     1237         * @since BuddyPress (2.3.0)
     1238         *
     1239         * @param string $message Message to display to the current user.
     1240         * @param object $blog   Blog to get status message for.
     1241         */
     1242        echo apply_filters( 'bp_blog_status_message', $message, $blog );
     1243}
    11111244
    11121245/** Blog Registration ********************************************************/
    11131246
    function bp_blogs_confirm_blog_signup( $domain, $path, $blog_title, $user_name, 
    13711504                <?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 ); ?>
    13721505        </p>
    13731506
    1374 <?php
     1507        <?php if ( bp_blogs_is_avatar_uploads_enabled() && is_user_logged_in() ) :
     1508                $single_blog_link = trailingslashit( bp_get_root_domain() . '/' . bp_get_blogs_root_slug() . $path . 'manage/edit-logo' );
     1509        ?>
     1510                <p>
     1511                        <?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 ); ?>
     1512                </p>
     1513
     1514        <?php endif;
    13751515
    13761516        /**
    13771517         * Fires after the default successful blog registration message markup.
    function bp_blog_backcompat_create_nav_item() { 
    15541694add_action( 'bp_blogs_directory_blog_types', 'bp_blog_backcompat_create_nav_item', 1000 );
    15551695
    15561696/**
     1697 * Output button for visiting a the blogs single item.
     1698 *
     1699 * @since BuddyPress (2.3.0)
     1700 *
     1701 * @see bp_get_blogs_view_details_blog_button() for description of arguments.
     1702 *
     1703 * @param array $args See {@link bp_get_blogs_view_details_blog_button()}.
     1704 */
     1705function bp_blogs_view_details_blog_button( $args = '' ) {
     1706        echo bp_get_blogs_view_details_blog_button( $args );
     1707}
     1708add_action( 'bp_directory_blogs_actions', 'bp_blogs_view_details_blog_button' );
     1709
     1710        /**
     1711         * Return button for visiting a blog in a loop.
     1712         *
     1713         * @since BuddyPress (2.3.0)
     1714         *
     1715         * @see BP_Button for a complete description of arguments and return
     1716         *      value.
     1717         *
     1718         * @param array $args {
     1719         *     Arguments are listed below, with their default values. For a
     1720         *     complete description of arguments, see {@link BP_Button}.
     1721         *     @type string $id Default: 'view_blog_profile'.
     1722         *     @type string $component Default: 'blogs'.
     1723         *     @type bool $must_be_logged_in Default: false.
     1724         *     @type bool $block_self Default: false.
     1725         *     @type string $wrapper_class Default: 'blog-button profile'.
     1726         *     @type string $link_href View details link of the current blog in the loop.
     1727         *     @type string $link_class Default: 'blog-button profile'.
     1728         *     @type string $link_text Default: 'View Details'.
     1729         *     @type string $link_title Default: 'View Details'.
     1730         * }
     1731         * @return string The HTML for the Visit button.
     1732         */
     1733        function bp_get_blogs_view_details_blog_button( $args = '' ) {
     1734                // Do not display the button if the single blog feature is disabled
     1735                if ( true === apply_filters( 'bp_blogs_disable_single_items', false ) ) {
     1736                        return;
     1737                }
     1738
     1739                $button = wp_parse_args( $args, array(
     1740                        'id'                => 'view_blog_profile',
     1741                        'component'         => 'blogs',
     1742                        'must_be_logged_in' => false,
     1743                        'block_self'        => false,
     1744                        'wrapper_class'     => 'blog-button profile',
     1745                        'link_href'         => bp_get_blog_view_details_link(),
     1746                        'link_class'        => 'blog-button profile',
     1747                        'link_text'         => __( 'View Details', 'buddypress' ),
     1748                        'link_title'        => __( 'View Details', 'buddypress' ),
     1749                ) );
     1750
     1751                // Filter and return the HTML button
     1752                return bp_get_button( apply_filters( 'bp_get_blogs_view_details_blog_button', $button ) );
     1753        }
     1754
     1755/**
    15571756 * Output button for visiting a blog in a loop.
    15581757 *
    15591758 * @see bp_get_blogs_visit_blog_button() for description of arguments.
    add_action( 'bp_blogs_directory_blog_types', 'bp_blog_backcompat_create_nav_item 
    15631762function bp_blogs_visit_blog_button( $args = '' ) {
    15641763        echo bp_get_blogs_visit_blog_button( $args );
    15651764}
     1765add_action( 'bp_blog_header_actions', 'bp_blogs_visit_blog_button', 10 );
     1766
    15661767        /**
    15671768         * Return button for visiting a blog in a loop.
    15681769         *
    function bp_blogs_visit_blog_button( $args = '' ) { 
    16091810                return bp_get_button( apply_filters( 'bp_get_blogs_visit_blog_button', $button ) );
    16101811        }
    16111812
     1813/**
     1814 * Add a subcribe button in blog's header
     1815 *
     1816 * @since BuddyPress (2.3.0)
     1817 */
     1818function bp_blogs_join_blog_button( $blog = null ) {
     1819        echo bp_get_blogs_join_blog_button( $blog );
     1820}
     1821add_action( 'bp_blog_header_actions', 'bp_blogs_join_blog_button', 5 );
     1822
     1823        /**
     1824         * Get the blog's subcribe button
     1825         *
     1826         * @since BuddyPress (2.3.0)
     1827         */
     1828        function bp_get_blogs_join_blog_button( $blog = null ) {
     1829
     1830                if ( empty( $blog ) ) {
     1831                        $blog = bp_blogs_get_current_blog();
     1832                }
     1833
     1834                if ( ! is_user_logged_in() || ! isset( $blog->id ) || ! bp_current_blog_can_subscribe() ) {
     1835                        return false;
     1836                }
     1837
     1838                // Already a member
     1839                if ( bp_current_blog_is_member() ) {
     1840
     1841                        if ( bp_is_item_admin() ) {
     1842                                return false;
     1843                        }
     1844
     1845                        $button = array(
     1846                                'id'                => 'leave_blog',
     1847                                'component'         => 'blogs',
     1848                                'must_be_logged_in' => true,
     1849                                'block_self'        => false,
     1850                                'wrapper_class'     => 'blog-button leave',
     1851                                'wrapper_id'        => 'blogbutton-' . $blog->id,
     1852                                'link_href'         => wp_nonce_url( bp_get_blog_view_details_link() . '?action=leave', 'blogs_leave_blog' ),
     1853                                'link_text'         => __( 'Leave', 'buddypress' ),
     1854                                'link_title'        => __( 'Leave', 'buddypress' ),
     1855                                'link_class'        => 'blog-button leave-blog confirm',
     1856                        );
     1857
     1858                // Not a member
     1859                } else {
     1860
     1861                        $button = array(
     1862                                'id'                => 'join_blog',
     1863                                'component'         => 'blogs',
     1864                                'must_be_logged_in' => true,
     1865                                'block_self'        => false,
     1866                                'wrapper_class'     => 'blog-button join',
     1867                                'wrapper_id'        => 'blogbutton-' . $blog->id,
     1868                                'link_href'         => wp_nonce_url( bp_get_blog_view_details_link() . '?action=join', 'blogs_join_blog' ),
     1869                                'link_text'         => __( 'Join', 'buddypress' ),
     1870                                'link_title'        => __( 'Join', 'buddypress' ),
     1871                                'link_class'        => 'blog-button join-blog',
     1872                        );
     1873                }
     1874
     1875                // Filter and return the HTML button
     1876                return bp_get_button( apply_filters( 'bp_get_blogs_join_blog_button', $button ) );
     1877        }
     1878
    16121879/** Stats **********************************************************************/
    16131880
    16141881/**
    function bp_blogs_get_profile_stats( $args = '' ) { 
    16691936         */
    16701937        return apply_filters( 'bp_blogs_get_profile_stats', $r['output'], $r );
    16711938}
     1939
     1940/**
     1941 * Output the blogs single item sub nav
     1942 *
     1943 * @since BuddyPress (2.3.0)
     1944 */
     1945function bp_blogs_item_subnav() {
     1946        $bp = buddypress();
     1947
     1948        if ( $bp->blogs->id !== bp_current_component() || ! bp_is_single_item() ) {
     1949                return;
     1950        }
     1951
     1952        $component = bp_current_component();
     1953        $the_index = bp_current_action();
     1954
     1955        // Default subnav
     1956        $selected_item = bp_current_action();
     1957
     1958        if ( bp_action_variable( 0 ) ) {
     1959                $selected_item = bp_action_variable( 0 );
     1960        }
     1961
     1962        if ( empty( $bp->{$component}->single_subnav[ $the_index ] ) ) {
     1963                return;
     1964        }
     1965
     1966        return bp_component_options_nav( $bp->{$component}->single_subnav, $the_index, $selected_item, $component );
     1967}
     1968
     1969/**
     1970 * Load the appropriate current blog's home page
     1971 *
     1972 * @since BuddyPress (2.3.0)
     1973 */
     1974function bp_blogs_load_blog_front_template( $require_once = false, $blog = null ) {
     1975        $located = bp_blogs_get_blog_front_template( $blog );
     1976
     1977        if ( false !== $located ) {
     1978                $slug = str_replace( '.php', '', $located );
     1979
     1980                /**
     1981                 * Let plugins adding an action to bp_get_template_part get it from here
     1982                 *
     1983                 * @param string $slug Template part slug requested.
     1984                 * @param string $name Template part name requested.
     1985                 */
     1986                do_action( 'get_template_part_' . $slug, $slug, false );
     1987
     1988                load_template( $located, $require_once );
     1989
     1990        } else if ( bp_is_active( 'activity' ) && bp_current_blog_is_public() ) {
     1991                bp_get_template_part( 'blogs/single/activity' );
     1992
     1993        } else if ( bp_is_active( 'members' ) ) {
     1994                bp_get_template_part( 'blogs/single/members' );
     1995        }
     1996
     1997        return $located;
     1998}
     1999
     2000/**
     2001 * Locate a custom blog front template if it exsists
     2002 *
     2003 * @since BuddyPress (2.3.0)
     2004 */
     2005function bp_blogs_get_blog_front_template( $blog = null ) {
     2006        if ( ! is_a( $blog, 'BP_Blogs_Blog' ) ) {
     2007                $blog = bp_blogs_get_current_blog();
     2008        }
     2009
     2010        if ( ! isset( $blog->id ) ) {
     2011                return false;
     2012        }
     2013
     2014        if ( isset( $blog->front_template ) ) {
     2015                return $blog->front_template;
     2016        }
     2017
     2018        $template_names = apply_filters( 'bp_blogs_get_front_template', array(
     2019                'blogs/single/front-id-'     . sanitize_file_name( $blog->id )     . '.php',
     2020                'blogs/single/front-slug-'   . sanitize_file_name( $blog->slug )   . '.php',
     2021                'blogs/single/front.php'
     2022        ) );
     2023
     2024        return bp_locate_template( $template_names, false, true );
     2025}
     2026
     2027/**
     2028 * Is the current page a specific blog manage screen?
     2029 *
     2030 * @since BuddyPress (2.3.0)
     2031 *
     2032 * @param string $slug
     2033 * @return bool
     2034 */
     2035function bp_is_blog_manage_screen( $slug = '' ) {
     2036        return (bool) ( bp_is_blog_manage() && bp_is_action_variable( $slug ) );
     2037}
     2038
     2039/**
     2040 * Return whether a blog has an avatar
     2041 *
     2042 * @since BuddyPress (2.3.0)
     2043 *
     2044 * @param  int $blog_id
     2045 * @return boolean
     2046 */
     2047function bp_get_blog_has_avatar( $blog_id = false ) {
     2048
     2049        if ( false === $blog_id ) {
     2050                $blog_id = bp_get_current_blog_id();
     2051        }
     2052
     2053        $blog_avatar = bp_core_fetch_avatar( array(
     2054                'item_id' => $blog_id,
     2055                'object'  => 'blog',
     2056                'no_grav' => true,
     2057                'html'    => false,
     2058        ) );
     2059
     2060        if ( bp_core_avatar_default( 'local' ) === $blog_avatar ) {
     2061                return false;
     2062        }
     2063
     2064        return true;
     2065}
     2066
     2067/** Current blog *************************************************************/
     2068
     2069/**
     2070 * Echoes the output of bp_get_current_blog_id()
     2071 *
     2072 * @since BuddyPress (2.3.0)
     2073 */
     2074function bp_current_blog_id() {
     2075        echo bp_get_current_blog_id();
     2076}
     2077        /**
     2078         * Returns the ID of the current blog
     2079         *
     2080         * @since BuddyPress (2.3.0)
     2081         * @uses apply_filters() Filter bp_get_current_blog_id to modify this output
     2082         *
     2083         * @return string The ID of the current blog, if there is one
     2084         */
     2085        function bp_get_current_blog_id() {
     2086                $current_blog    = bp_blogs_get_current_blog();
     2087                $current_blog_id = '';
     2088
     2089                if ( isset( $current_blog->id ) ) {
     2090                        $current_blog_id = $current_blog->id;
     2091                }
     2092
     2093                /**
     2094                 * Filters the ID of the current blog
     2095                 *
     2096                 * @since BuddyPress (2.3.0)
     2097                 *
     2098                 * @param string $current_blog_id ID of the current blog.
     2099                 * @param object $current_blog Instance holding the current blog.
     2100                 */
     2101                return apply_filters( 'bp_get_current_blog_id', $current_blog_id, $current_blog );
     2102        }
     2103
     2104/**
     2105 * Echoes the output of bp_get_current_blog_name()
     2106 *
     2107 * @since BuddyPress (2.3.0)
     2108 */
     2109function bp_current_blog_name() {
     2110        echo bp_get_current_blog_name();
     2111}
     2112        /**
     2113         * Returns the name of the current blog
     2114         *
     2115         * @since BuddyPress (2.3.0)
     2116         * @uses apply_filters() Filter bp_get_current_blog_name to modify this output
     2117         *
     2118         * @return string The name of the current blog, if there is one
     2119         */
     2120        function bp_get_current_blog_name() {
     2121                $current_blog      = bp_blogs_get_current_blog();
     2122                $current_blog_name = '';
     2123
     2124                if ( isset( $current_blog->name ) ) {
     2125                        $current_blog_name = $current_blog->name;
     2126                }
     2127
     2128                /**
     2129                 * Filters the name of the current blog
     2130                 *
     2131                 * @since BuddyPress (2.3.0)
     2132                 *
     2133                 * @param string $current_blog_name Name of the current blog.
     2134                 * @param object $current_blog Instance holding the current blog.
     2135                 */
     2136                return apply_filters( 'bp_get_current_blog_name', $current_blog_name, $current_blog );
     2137        }
     2138
     2139/**
     2140 * Echoes the output of bp_get_current_blog_slug()
     2141 *
     2142 * @since BuddyPress (2.3.0)
     2143 */
     2144function bp_current_blog_slug() {
     2145        echo bp_get_current_blog_slug();
     2146}
     2147        /**
     2148         * Returns the slug of the current blog
     2149         *
     2150         * @since BuddyPress (2.3.0)
     2151         * @uses apply_filters() Filter bp_get_current_blog_slug to modify this output
     2152         *
     2153         * @return string The slug of the current blog, if there is one
     2154         */
     2155        function bp_get_current_blog_slug() {
     2156                $current_blog      = bp_blogs_get_current_blog();
     2157                $current_blog_slug = '';
     2158
     2159                if ( isset( $current_blog->slug ) ) {
     2160                        $current_blog_slug = $current_blog->slug;
     2161                }
     2162
     2163                /**
     2164                 * Filters the slug of the current blog
     2165                 *
     2166                 * @since BuddyPress (2.3.0)
     2167                 *
     2168                 * @param string $current_blog_slug Slug of the current blog.
     2169                 * @param object $current_blog Instance holding the current blog.
     2170                 */
     2171                return apply_filters( 'bp_get_current_blog_slug', $current_blog_slug, $current_blog );
     2172        }
     2173
     2174/**
     2175 * Display the admins in the blog's header
     2176 *
     2177 * @since BuddyPress (2.3.0)
     2178 */
     2179function bp_current_blog_admins() {
     2180        echo bp_get_current_blog_admins();
     2181}
     2182        /**
     2183         * Get the admins list
     2184         *
     2185         * @since BuddyPress (2.3.0)
     2186         */
     2187        function bp_get_current_blog_admins() {
     2188                $current_blog = bp_blogs_get_current_blog();
     2189                $pre_output   = false;
     2190
     2191                // Do not display admins if the user has no access
     2192                if ( ! bp_current_blog_has_access() ) {
     2193                        $pre_output = '';
     2194                }
     2195
     2196                /**
     2197                 * Use this filter if you need to hide the blog admins by returning false
     2198                 *
     2199                 * @since BuddyPress (2.3.0)
     2200                 *
     2201                 * @param boolean $pre_output whether to output the list of the current blog admins
     2202                 */
     2203                $pre_output = apply_filters( 'bp_pre_get_current_blog_admins', $pre_output, $current_blog );
     2204                if ( false !== $pre_output ) {
     2205                        return $pre_output;
     2206                }
     2207
     2208                $output = '<h3>' . esc_html__( 'Site Admins', 'bp-blogs-extended' ) . '</h3>';
     2209                $output .= '<span class="activity">' . esc_html__( 'No Admins', 'bp-blogs-extended' ) . '</span>';
     2210
     2211                if ( ! empty( $current_blog->admins ) ) {
     2212                        $output = '<ul id="blog-admins">';
     2213
     2214                        foreach( (array) $current_blog->admins as $admin ) {
     2215                                $output .= '<li>';
     2216
     2217                                if ( ! buddypress()->avatar->show_avatars ) {
     2218                                        $output .= sprintf(
     2219                                                '<a href="%s" title="%s">%s</a>',
     2220                                                esc_url( bp_core_get_user_domain( $admin->ID, $admin->user_nicename, $admin->user_login ) ),
     2221                                                sprintf( esc_attr__( 'Profile of %s', 'bp-blogs-extended' ), $admin->display_name ),
     2222                                                esc_html( $admin->user_nicename )
     2223                                        );
     2224                                } else {
     2225                                        $output .= sprintf(
     2226                                                '<a href="%s">%s</a>',
     2227                                                esc_url( bp_core_get_user_domain( $admin->ID, $admin->user_nicename, $admin->user_login ) ),
     2228                                                bp_core_fetch_avatar( array(
     2229                                                        'item_id' => esc_attr( $admin->ID ),
     2230                                                        'email'   => esc_attr( $admin->user_email ),
     2231                                                        'alt'     => sprintf( esc_attr__( 'Profile picture of %s', 'bp-blogs-extended' ), $admin->display_name )
     2232                                                ) )
     2233                                        );
     2234                                }
     2235
     2236                                $output .= '</li>';
     2237                        }
     2238
     2239                        $output .= '</ul>';
     2240                }
     2241
     2242                return apply_filters( 'bp_get_current_blog_admins', $output, $current_blog );
     2243        }
     2244
     2245/**
     2246 * Display the current blog type
     2247 *
     2248 * @since BuddyPress (2.3.0)
     2249 */
     2250function bp_current_blog_type() {
     2251        echo bp_get_current_blog_type();
     2252}
     2253
     2254        /**
     2255         * Get the current blog type
     2256         *
     2257         * @since BuddyPress (2.3.0)
     2258         */
     2259        function bp_get_current_blog_type() {
     2260                $type = esc_html__( 'Private', 'buddypress' );
     2261
     2262                if ( bp_current_blog_is_public() ) {
     2263                        $type = esc_html__( 'Public', 'buddypress' );
     2264                }
     2265
     2266                /**
     2267                 * Use this filter if you need to edit the blog type
     2268                 *
     2269                 * @since BuddyPress (2.3.0)
     2270                 *
     2271                 * @param string $type the blog type
     2272                 */
     2273                return apply_filters( 'bp_get_current_blog_type', $type );
     2274        }
     2275
     2276/** Blog Members **************************************************************/
     2277
     2278/**
     2279 * The following functions are wrapping some Members loop template functions
     2280 * It might be interesting in the future to use a specific class to extend
     2281 * BP_User_Query the same way the groups component is doing to add new filter
     2282 * options.
     2283 */
     2284
     2285/**
     2286 * bp_has_members wrapper to fetch the current blog's members
     2287 *
     2288 * @since BuddyPress (2.3.0)
     2289 *
     2290 * @see bp_has_members() for detailed available arguments
     2291 */
     2292function bp_blog_has_members( $args = '' ) {
     2293        global $wpdb;
     2294
     2295        $meta_key = $wpdb->get_blog_prefix( bp_get_current_blog_id() ) . 'capabilities';
     2296
     2297        $r = bp_parse_args( $args, array(
     2298                'type'            => 'active',
     2299                'page'            => 1,
     2300                'per_page'        => 20,
     2301                'max'             => false,
     2302                'page_arg'        => 'blogpage',
     2303                'user_id'         => 0,
     2304                'meta_key'        => $meta_key,    // Only return users of the current blog
     2305        ), 'blog_has_members' );
     2306
     2307        return bp_has_members( $r );
     2308}
     2309
     2310/**
     2311 * bp_members wrapper for the current blog's
     2312 *
     2313 * @since BuddyPress (2.3.0)
     2314 */
     2315function bp_blog_members() {
     2316        return bp_members();
     2317}
     2318
     2319/**
     2320 * bp_the_member wrapper for the current blog's
     2321 *
     2322 * @since BuddyPress (2.3.0)
     2323 */
     2324function bp_blog_the_member() {
     2325        return bp_the_member();
     2326}
     2327
     2328/**
     2329 * bp_member_permalink wrapper for the current blog's
     2330 *
     2331 * @since BuddyPress (2.3.0)
     2332 */
     2333function bp_blog_member_permalink() {
     2334        return bp_member_permalink();
     2335}
     2336
     2337/**
     2338 * bp_member_avatar wrapper for the current blog's
     2339 *
     2340 * @since BuddyPress (2.3.0)
     2341 */
     2342function bp_blog_member_avatar() {
     2343        return bp_member_avatar();
     2344}
     2345
     2346/**
     2347 * bp_member_name wrapper for the current blog's
     2348 *
     2349 * @since BuddyPress (2.3.0)
     2350 */
     2351function bp_blog_member_name() {
     2352        return bp_member_name();
     2353}
     2354
     2355/**
     2356 * bp_get_member_latest_update wrapper for the current blog's
     2357 *
     2358 * @since BuddyPress (2.3.0)
     2359 */
     2360function bp_blog_get_member_latest_update() {
     2361        return bp_get_member_latest_update();
     2362}
     2363
     2364/**
     2365 * bp_member_latest_update wrapper for the current blog's
     2366 *
     2367 * @since BuddyPress (2.3.0)
     2368 */
     2369function bp_blog_member_latest_update() {
     2370        return bp_member_latest_update();
     2371}
     2372
     2373/**
     2374 * bp_member_last_active wrapper for the current blog's
     2375 *
     2376 * @since BuddyPress (2.3.0)
     2377 */
     2378function bp_blog_member_last_active() {
     2379        return bp_member_last_active();
     2380}
  • 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..a279058 100644
    class BP_Blogs_Blog { 
    2727         *
    2828         * @param int $id Optional. The ID of the blog.
    2929         */
    30         public function __construct( $id = null ) {
    31                 if ( !empty( $id ) ) {
     30        public function __construct( $id = null, $args = array() ) {
     31                $this->args = wp_parse_args( $args, array(
     32                        'populate_extras' => false,
     33                ) );
     34
     35                if ( ! empty( $id ) ) {
    3236                        $this->id = $id;
    3337                        $this->populate();
    3438                }
    class BP_Blogs_Blog { 
    4246
    4347                $bp = buddypress();
    4448
    45                 $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->blogs->table_name} WHERE id = %d", $this->id ) );
     49                // Are we getting extra blog data?
     50                if ( ! empty( $this->args['populate_extras'] ) ) {
     51
     52                        // We need some of the blog details and it's a good
     53                        // way to check the blog is not moderated
     54                        $blog_details = get_blog_details( $this->id );
     55
     56                        if ( empty( $blog_details ) || 1 === (int) $blog_details->mature || 1 === (int) $blog_details->spam || 1 === (int) $blog_details->archived || 1 === (int) $blog_details->deleted ) {
     57                                $this->id = 0;
     58                                return;
     59                        }
     60
     61                        $site_domain   = get_home_url( get_current_site()->id );
     62                        $this->blog_id = $this->id;
     63
     64                        // Populating BuddyPress blog metas for the requested blog
     65                        foreach ( bp_blogs_get_blogmeta( $this->id ) as $key => $meta ) {
     66                                // Don't fetch private blogmeta
     67                                if ( is_protected_meta( $key ) ) {
     68                                        continue;
     69                                }
     70
     71                                if ( count( $meta ) == 1 ) {
     72                                        $this->{$key} = maybe_unserialize( $meta[0] );
     73                                } else {
     74                                        $this->{$key} = array_map( 'maybe_unserialize', $meta );
     75                                }
     76                        }
     77
     78                        if ( ! isset( $this->url ) ) {
     79                                $this->url = $blog_details->siteurl;
     80                        }
     81
     82                        if ( $site_domain === $this->url ) {
     83                                $this->slug = apply_filters( 'bp_blogs_get_site_slug', 'root' );
     84                        } else {
     85                                $this->slug = str_replace( trailingslashit( $site_domain ), '', $this->url );
     86                        }
    4687
    47                 $this->user_id = $blog->user_id;
    48                 $this->blog_id = $blog->blog_id;
     88                        if ( ! isset( $this->name ) ) {
     89                                $this->name = $blog_details->blogname;
     90                        }
     91
     92                        // The following properties are necessary for the blogs loop
     93                        $this->path = $blog_details->path;
     94                        $this->domain = $blog_details->domain;
     95
     96                        if ( bp_get_root_blog_id() !== $this->id ) {
     97                                $needs_reset = true;
     98                                switch_to_blog( $this->id );
     99                        }
     100
     101                        // Who are the admins ?
     102                        $this->admins = get_users( array(
     103                                'role'   => 'administrator',
     104                                'fields' => array( 'ID', 'display_name', 'user_login', 'user_nicename', 'user_email' ),
     105                        ) );
     106
     107                        $this->admin_user_id    = $this->admins[0]->ID;
     108                        $this->admin_user_email = $this->admins[0]->user_email;
     109
     110                        // How many users ?
     111                        $blog_users               = count_users();
     112                        $this->total_member_count = $blog_users['total_users'];
     113
     114                        // How many posts ?
     115                        $this->post_count = $blog_details->post_count;
     116
     117                        // Is current user a member of the blog ?
     118                        $this->is_member = current_user_can( 'read' );
     119
     120                        // Blog visibility
     121                        $this->blog_public = $blog_details->public;
     122
     123                        if ( isset( $needs_reset ) ) {
     124                                restore_current_blog();
     125                        }
     126
     127                } else {
     128                        $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->blogs->table_name} WHERE id = %d", $this->id ) );
     129
     130                        $this->user_id = $blog->user_id;
     131                        $this->blog_id = $blog->blog_id;
     132                }
    49133        }
    50134
    51135        /**
    class BP_Blogs_Blog { 
    241325                global $wpdb;
    242326
    243327                bp_blogs_delete_blogmeta( $blog_id );
    244                
     328
    245329                $bp = buddypress();
    246330
    247331                return $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name} WHERE blog_id = %d", $blog_id ) );
  • src/bp-core/bp-core-attachments.php

    diff --git src/bp-core/bp-core-attachments.php src/bp-core/bp-core-attachments.php
    index d454d88..5b0595a 100644
    function bp_attachments_current_user_can( $capability, $args = array() ) { 
    312312                        // User profile photo
    313313                        } elseif ( bp_is_active( 'xprofile' ) && 'user' === $args['object'] ) {
    314314                                $can = bp_loggedin_user_id() === (int) $args['item_id'] || bp_current_user_can( 'bp_moderate' );
     315                        // Site logo
     316                        } elseif ( bp_is_active( 'blogs' ) && 'blog' === $args['object'] ) {
     317                                $can = current_user_can_for_blog( (int) $args['item_id'], 'manage_options' );
    315318                        }
    316319                /**
    317320                 * 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 8457c03..fbfd3f4 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' ) ) {
     217                                        $params['item_id'] = bp_get_current_blog_id();
     218                                } else {
     219                                        $params['item_id'] = false;
     220                                }
    217221                                break;
    218222
    219223                        case 'group' :
    function bp_core_delete_existing_avatar( $args = '' ) { 
    664668        extract( $args, EXTR_SKIP );
    665669
    666670        if ( empty( $item_id ) ) {
    667                 if ( 'user' == $object )
     671                if ( 'user' == $object ) {
    668672                        $item_id = bp_displayed_user_id();
    669                 elseif ( 'group' == $object )
     673                } elseif ( 'group' == $object && bp_is_active( 'groups' ) ) {
    670674                        $item_id = buddypress()->groups->current_group->id;
    671                 elseif ( 'blog' == $object )
    672                         $item_id = $current_blog->id;
     675                } elseif ( 'blog' == $object && bp_is_active( 'blogs' ) ) {
     676                        $item_id = bp_get_current_blog_id();
     677                }
    673678
    674679                /** This filter is documented in bp-core/bp-core-avatars.php */
    675680                $item_id = apply_filters( 'bp_core_avatar_item_id', $item_id, $object );
    676681
    677                 if ( !$item_id ) return false;
     682                if ( ! $item_id ) {
     683                        return false;
     684                }
    678685        }
    679686
    680687        if ( empty( $avatar_dir ) ) {
    function bp_avatar_ajax_upload() { 
    920927                                'populate_extras' => false,
    921928                        ) );
    922929                }
     930        } elseif ( 'blog' === $bp_params['object'] && bp_is_active( 'blogs' ) ) {
     931                $bp_params['upload_dir_filter'] = 'blogs_avatar_upload_dir';
     932
     933                if ( ! bp_get_current_blog_id() && ! empty( $bp_params['item_id'] ) ) {
     934                        $needs_reset = array( 'component' => 'blogs', 'key' => 'current_blog', 'value' => $bp->blogs->current_blog );
     935                        $bp->blogs->current_blog = bp_blogs_get_blog( array(
     936                                'blog_id'        => $bp_params['item_id'],
     937                                'populate_extras' => true,
     938                        ) );
     939                }
    923940        } else {
    924941                /**
    925942                 * Filter here to deal with other components
    function bp_avatar_is_front_edit() { 
    18081825                }
    18091826        }
    18101827
     1828        if ( bp_is_active( 'blogs' ) && bp_is_blog_manage_screen( 'edit-logo' ) ) {
     1829                $retval = ! bp_core_get_root_option( 'bp-disable-avatar-uploads' );
     1830        }
     1831
    18111832        /**
    18121833         * Use this filter if you need to :
    18131834         * - Load the avatar UI for a component that is !groups or !user (return true regarding your conditions)
  • src/bp-core/bp-core-buddybar.php

    diff --git src/bp-core/bp-core-buddybar.php src/bp-core/bp-core-buddybar.php
    index ca87d9a..ca0383c 100644
    function bp_core_new_nav_item( $args = '' ) { 
    4646                'site_admin_only'         => false, // Can only site admins see this nav item?
    4747                'position'                => 99,    // Index of where this nav item should be positioned
    4848                'screen_function'         => false, // The name of the function to run when clicked
    49                 'default_subnav_slug'     => false  // The slug of the default subnav item to select when clicked
     49                'default_subnav_slug'     => false, // The slug of the default subnav item to select when clicked
     50                'single_nav'              => false, // The component id to create the single nav for
    5051        );
    5152
    5253        $r = wp_parse_args( $args, $defaults );
    53         extract( $r, EXTR_SKIP );
    5454
    5555        // If we don't have the required info we need, don't create this subnav item
    56         if ( empty( $name ) || empty( $slug ) )
     56        if ( empty( $r['name'] ) || empty( $r['slug'] ) ) {
    5757                return false;
     58        }
    5859
    5960        // If this is for site admins only and the user is not one, don't create the subnav item
    60         if ( !empty( $site_admin_only ) && !bp_current_user_can( 'bp_moderate' ) )
     61        if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) {
    6162                return false;
     63        }
    6264
    63         if ( empty( $item_css_id ) )
    64                 $item_css_id = $slug;
     65        // Defaults to slug
     66        $item_css_id = $r['slug'];
     67
     68        if ( ! empty( $r['item_css_id'] ) ) {
     69                $item_css_id = $r['item_css_id'];
     70        }
    6571
    66         $bp->bp_nav[$slug] = array(
    67                 'name'                    => $name,
    68                 'slug'                    => $slug,
    69                 'link'                    => trailingslashit( bp_loggedin_user_domain() . $slug ),
     72        $nav_item = array(
     73                'name'                    => $r['name'],
     74                'slug'                    => $r['slug'],
     75                'link'                    => '',
    7076                'css_id'                  => $item_css_id,
    71                 'show_for_displayed_user' => $show_for_displayed_user,
    72                 'position'                => $position,
    73                 'screen_function'         => &$screen_function,
    74                 'default_subnav_slug'     => $default_subnav_slug
     77                'show_for_displayed_user' => $r['show_for_displayed_user'],
     78                'position'                => $r['position'],
     79                'screen_function'         => &$r['screen_function'],
     80                'default_subnav_slug'     => $r['default_subnav_slug']
    7581        );
    7682
     83        $is_component_single_nav = ! empty( $r['single_nav'] ) && bp_is_active( $r['single_nav'] ) && isset( $bp->{$r['single_nav']}->single_nav ) && bp_is_current_component( $r['single_nav'] );
     84
     85        // The component is managing its single items nav
     86        if ( $is_component_single_nav ) {
     87                $component = $r['single_nav'];
     88
     89                /**
     90                 * Filter here to add your custom function to build the component root slug
     91                 *
     92                 * @since BuddyPress (2.3.0)
     93                 *
     94                 * $callable string the function to use
     95                 * $component  string the component id
     96                 */
     97                $callable = apply_filters( 'bp_core_new_nav_item_component_callable', 'bp_get_' . $component . '_root_slug', $component );
     98
     99                if ( ! is_callable( $callable ) ) {
     100                        return false;
     101                }
     102
     103                $nav_item['link'] = trailingslashit( bp_get_root_domain() . '/' . call_user_func( $callable ) . '/' . bp_current_item() . '/' . $r['slug'] );
     104                $bp->{$r['single_nav']}->single_nav[ $r['slug'] ] = $nav_item;
     105
     106        // Default nav is core nav
     107        } else {
     108                $nav_item['link'] = trailingslashit( bp_loggedin_user_domain() . $r['slug'] );
     109                $bp->bp_nav[ $r['slug'] ] = $nav_item;
     110        }
     111
    77112        /**
    78113         * If this nav item is hidden for the displayed user, and
    79114         * the logged in user is not the displayed user
    80115         * looking at their own profile, don't create the nav item.
    81116         */
    82         if ( empty( $show_for_displayed_user ) && !bp_user_has_access() )
     117        if ( empty( $r['show_for_displayed_user'] ) && ! bp_user_has_access() ) {
    83118                return false;
     119        }
    84120
    85121        /**
    86122         * If the nav item is visible, we are not viewing a user, and this is a root
    87123         * component, don't attach the default subnav function so we can display a
    88124         * directory or something else.
    89125         */
    90         if ( ( -1 != $position ) && bp_is_root_component( $slug ) && !bp_displayed_user_id() )
     126        if ( ( -1 != $r['position'] ) && bp_is_root_component( $r['slug'] ) && ! bp_displayed_user_id() && ! $is_component_single_nav ) {
    91127                return;
     128        }
     129
     130        // Manage the component's specific single nav
     131        if ( $is_component_single_nav && bp_is_current_action( $r['slug'] ) ) {
     132                if ( ! empty( $r['default_subnav_slug'] ) && bp_is_action_variable( $r['default_subnav_slug'], 0 ) && ! bp_action_variable( 1 ) ) {
     133                        unset( $bp->canonical_stack['action_variables'][0] );
     134                } elseif ( ! bp_action_variable( 0 ) ) {
    92135
    93         // Look for current component
    94         if ( bp_is_current_component( $slug ) || bp_is_current_item( $slug ) ) {
     136                        // Add our screen hook if screen function is callable
     137                        if ( is_callable( $r['screen_function'] ) ) {
     138                                add_action( 'bp_screens', $r['screen_function'], 3 );
     139                        }
     140
     141                        if ( ! empty( $r['default_subnav_slug'] ) ) {
     142                                /**
     143                                 * Filters the component's single nav default subnav item.
     144                                 *
     145                                 * @since BuddyPress (2.3.0)
     146                                 *
     147                                 * @param string $default_subnav_slug The slug of the default subnav item
     148                                 *                                    to select when clicked.
     149                                 * @param array  $r                   Parsed arguments for the nav item.
     150                                 */
     151                                $bp->current_action = apply_filters( 'bp_default_component_single_subnav', $r['default_subnav_slug'], $r );
     152                        }
     153                }
     154
     155        // Look for current component in core nav
     156        } elseif ( bp_is_current_component( $r['slug'] ) || bp_is_current_item( $r['slug'] ) ) {
    95157
    96158                // The requested URL has explicitly included the default subnav
    97159                // (eg: http://example.com/members/membername/activity/just-me/)
    98160                // The canonical version will not contain this subnav slug.
    99                 if ( !empty( $default_subnav_slug ) && bp_is_current_action( $default_subnav_slug ) && !bp_action_variable( 0 ) ) {
     161                if ( ! empty( $r['default_subnav_slug'] ) && bp_is_current_action( $r['default_subnav_slug'] ) && ! bp_action_variable( 0 ) ) {
    100162                        unset( $bp->canonical_stack['action'] );
    101163                } elseif ( ! bp_current_action() ) {
    102164
    103165                        // Add our screen hook if screen function is callable
    104                         if ( is_callable( $screen_function ) ) {
    105                                 add_action( 'bp_screens', $screen_function, 3 );
     166                        if ( is_callable( $r['screen_function'] ) ) {
     167                                add_action( 'bp_screens', $r['screen_function'], 3 );
    106168                        }
    107169
    108                         if ( !empty( $default_subnav_slug ) ) {
     170                        if ( ! empty( $r['default_subnav_slug'] ) ) {
    109171
    110172                                /**
    111173                                 * Filters the default component subnav item.
    function bp_core_new_nav_item( $args = '' ) { 
    116178                                 *                                    to select when clicked.
    117179                                 * @param array  $r                   Parsed arguments for the nav item.
    118180                                 */
    119                                 $bp->current_action = apply_filters( 'bp_default_component_subnav', $default_subnav_slug, $r );
     181                                $bp->current_action = apply_filters( 'bp_default_component_subnav', $r['default_subnav_slug'], $r );
    120182                        }
    121183                }
    122184        }
    function bp_core_new_nav_default( $args = '' ) { 
    212274 *
    213275 * @return bool|null Returns false on failure.
    214276 */
    215 function bp_core_sort_nav_items() {
     277function bp_core_sort_nav_items( $component = '' ) {
    216278        $bp = buddypress();
    217279
    218         if ( empty( $bp->bp_nav ) || !is_array( $bp->bp_nav ) )
     280        if ( empty( $component ) || ! bp_is_active( $component ) ) {
     281                $nav = $bp->bp_nav;
     282        } else {
     283                $nav = $bp->{$component}->single_nav;
     284        }
     285
     286        if ( empty( $nav ) || ! is_array( $nav ) ) {
    219287                return false;
     288        }
    220289
    221290        $temp = array();
    222291
    223         foreach ( (array) $bp->bp_nav as $slug => $nav_item ) {
     292        foreach ( (array) $nav as $slug => $nav_item ) {
    224293                if ( empty( $temp[$nav_item['position']]) ) {
    225294                        $temp[$nav_item['position']] = $nav_item;
    226295                } else {
    function bp_core_sort_nav_items() { 
    234303        }
    235304
    236305        ksort( $temp );
    237         $bp->bp_nav = &$temp;
     306        $nav = &$temp;
     307
     308        if ( empty( $component ) || ! bp_is_active( $component ) ) {
     309                $bp->bp_nav = $nav;
     310        } else {
     311                $bp->{$component}->single_nav = $nav;
     312        }
    238313}
    239314add_action( 'wp_head',    'bp_core_sort_nav_items' );
    240315add_action( 'admin_head', 'bp_core_sort_nav_items' );
    function bp_core_new_subnav_item( $args = '' ) { 
    286361                'screen_function'   => false, // The name of the function to run when clicked
    287362                'link'              => '',    // The link for the subnav item; optional, not usually required.
    288363                'show_in_admin_bar' => false, // Show the Manage link in the current group's "Edit" Admin Bar menu
     364                'single_subnav'     => false, // The component id to create the single subnav for
    289365        ) );
    290366
    291         extract( $r, EXTR_SKIP );
    292 
    293367        // If we don't have the required info we need, don't create this subnav item
    294         if ( empty( $name ) || empty( $slug ) || empty( $parent_slug ) || empty( $parent_url ) || empty( $screen_function ) )
     368        if ( empty( $r['name'] ) || empty( $r['slug'] ) || empty( $r['parent_slug'] ) || empty( $r['parent_url'] ) || empty( $r['screen_function'] ) ) {
    295369                return false;
     370        }
     371
     372        $parent_default_subnav  = '';
     373        $parent_screen_function = '';
     374        $is_component_subnav    = ! empty( $r['single_subnav'] ) && bp_is_active( $r['single_subnav'] ) && isset( $bp->{$r['single_subnav']}->single_subnav );
     375
     376        // The component is managing its single items subnav
     377        if ( $is_component_subnav && isset( $bp->{$r['single_subnav']}->single_nav ) ) {
     378                if ( ! empty( $bp->{$r['single_subnav']}->single_nav[ $r['parent_slug'] ]['default_subnav_slug'] ) ) {
     379                        $parent_default_subnav  = $bp->{$r['single_subnav']}->single_nav[ $r['parent_slug'] ]['default_subnav_slug'];
     380                }
     381
     382                if ( ! empty( $bp->{$r['single_subnav']}->single_nav[ $r['parent_slug'] ]['screen_function'] ) ) {
     383                        $parent_screen_function = $bp->{$r['single_subnav']}->single_nav[ $r['parent_slug'] ]['screen_function'];
     384                }
     385
     386        // Default nav is core nav
     387        } else {
     388                if ( ! empty( $bp->bp_nav[ $r['parent_slug'] ]['default_subnav_slug'] ) ) {
     389                        $parent_default_subnav  = $bp->bp_nav[ $r['parent_slug'] ]['default_subnav_slug'];
     390                }
     391
     392                if ( ! empty( $bp->bp_nav[ $r['parent_slug'] ]['screen_function'] ) ) {
     393                        $parent_screen_function = $bp->bp_nav[ $r['parent_slug'] ]['screen_function'];
     394                }
     395        }
    296396
    297397        // Link was not forced, so create one
    298         if ( empty( $link ) ) {
    299                 $link = trailingslashit( $parent_url . $slug );
     398        if ( empty( $r['link'] ) ) {
     399                $link = trailingslashit( $r['parent_url'] . $r['slug'] );
    300400
    301401                // If this sub item is the default for its parent, skip the slug
    302                 if ( ! empty( $bp->bp_nav[$parent_slug]['default_subnav_slug'] ) && $slug == $bp->bp_nav[$parent_slug]['default_subnav_slug'] ) {
    303                         $link = trailingslashit( $parent_url );
     402                if ( $r['slug'] == $parent_default_subnav ) {
     403                        $link = trailingslashit( $r['parent_url'] );
    304404                }
     405        } else {
     406                $link = $r['link'];
    305407        }
    306408
    307409        // If this is for site admins only and the user is not one, don't create the subnav item
    308         if ( !empty( $site_admin_only ) && !bp_current_user_can( 'bp_moderate' ) )
     410        if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) {
    309411                return false;
     412        }
     413
     414        // Defaults to slug
     415        $item_css_id = $r['slug'];
    310416
    311         if ( empty( $item_css_id ) )
    312                 $item_css_id = $slug;
     417        if ( ! empty( $r['item_css_id'] ) ) {
     418                $item_css_id = $r['item_css_id'];
     419        }
    313420
    314421        $subnav_item = array(
    315                 'name'              => $name,
     422                'name'              => $r['name'],
    316423                'link'              => $link,
    317                 'slug'              => $slug,
     424                'slug'              => $r['slug'],
    318425                'css_id'            => $item_css_id,
    319                 'position'          => $position,
    320                 'user_has_access'   => $user_has_access,
    321                 'no_access_url'     => $no_access_url,
    322                 'screen_function'   => &$screen_function,
     426                'position'          => $r['position'],
     427                'user_has_access'   => $r['user_has_access'],
     428                'no_access_url'     => $r['no_access_url'],
     429                'screen_function'   => &$r['screen_function'],
    323430                'show_in_admin_bar' => (bool) $r['show_in_admin_bar'],
    324431        );
    325432
    326         $bp->bp_options_nav[$parent_slug][$slug] = $subnav_item;
     433        // The component is managing its single items nav
     434        if ( $is_component_subnav ) {
     435                $bp->{$r['single_subnav']}->single_subnav[ $r['parent_slug'] ][ $r['slug'] ] = $subnav_item;
    327436
    328         /**
    329          * The last step is to hook the screen function for the added subnav item. But this only
    330          * needs to be done if this subnav item is the current view, and the user has access to the
    331          * subnav item. We figure out whether we're currently viewing this subnav by checking the
    332          * following two conditions:
    333          *   (1) Either:
    334          *           (a) the parent slug matches the current_component, or
    335          *           (b) the parent slug matches the current_item
    336          *   (2) And either:
    337          *           (a) the current_action matches $slug, or
    338          *       (b) there is no current_action (ie, this is the default subnav for the parent nav)
    339          *           and this subnav item is the default for the parent item (which we check by
    340          *           comparing this subnav item's screen function with the screen function of the
    341          *           parent nav item in $bp->bp_nav). This condition only arises when viewing a
    342          *           user, since groups should always have an action set.
    343          */
     437                if ( ! bp_is_current_component( $r['single_subnav'] ) && ! bp_is_current_action( $r['parent_slug'] ) ) {
     438                        return;
     439                }
    344440
    345         // If we *don't* meet condition (1), return
    346         if ( ! bp_is_current_component( $parent_slug ) && ! bp_is_current_item( $parent_slug ) )
    347                 return;
     441                if ( bp_action_variable( 0 ) && bp_is_action_variable( $r['slug'], 0 ) ) {
     442
     443                        $hooked = bp_core_maybe_hook_new_subnav_screen_function( $subnav_item );
     444
     445                        // If redirect args have been returned, perform the redirect now
     446                        if ( ! empty( $hooked['status'] ) && 'failure' === $hooked['status'] && isset( $hooked['redirect_args'] ) ) {
     447                                bp_core_no_access( $hooked['redirect_args'] );
     448                        }
     449                }
     450
     451        // Default nav is core nav
     452        } else {
     453                $bp->bp_options_nav[ $r['parent_slug'] ][ $r['slug'] ] = $subnav_item;
     454
     455                /**
     456                 * The last step is to hook the screen function for the added subnav item. But this only
     457                 * needs to be done if this subnav item is the current view, and the user has access to the
     458                 * subnav item. We figure out whether we're currently viewing this subnav by checking the
     459                 * following two conditions:
     460                 *   (1) Either:
     461                 *           (a) the parent slug matches the current_component, or
     462                 *           (b) the parent slug matches the current_item
     463                 *   (2) And either:
     464                 *           (a) the current_action matches $slug, or
     465                 *       (b) there is no current_action (ie, this is the default subnav for the parent nav)
     466                 *           and this subnav item is the default for the parent item (which we check by
     467                 *           comparing this subnav item's screen function with the screen function of the
     468                 *           parent nav item in $bp->bp_nav). This condition only arises when viewing a
     469                 *           user, since groups should always have an action set.
     470                 */
     471
     472                // If we *don't* meet condition (1), return
     473                if ( ! bp_is_current_component( $r['parent_slug'] ) && ! bp_is_current_item( $r['parent_slug'] ) ) {
     474                        return;
     475                }
    348476
    349         // If we *do* meet condition (2), then the added subnav item is currently being requested
    350         if ( ( bp_current_action() && bp_is_current_action( $slug ) ) || ( bp_is_user() && ! bp_current_action() && ( $screen_function == $bp->bp_nav[$parent_slug]['screen_function'] ) ) ) {
     477                // If we *do* meet condition (2), then the added subnav item is currently being requested
     478                if ( ( bp_current_action() && bp_is_current_action( $r['slug'] ) ) || ( bp_is_user() && ! bp_current_action() && ( $r['screen_function'] == $parent_screen_function ) ) ) {
    351479
    352                 $hooked = bp_core_maybe_hook_new_subnav_screen_function( $subnav_item );
     480                        $hooked = bp_core_maybe_hook_new_subnav_screen_function( $subnav_item );
    353481
    354                 // If redirect args have been returned, perform the redirect now
    355                 if ( ! empty( $hooked['status'] ) && 'failure' === $hooked['status'] && isset( $hooked['redirect_args'] ) ) {
    356                         bp_core_no_access( $hooked['redirect_args'] );
     482                        // If redirect args have been returned, perform the redirect now
     483                        if ( ! empty( $hooked['status'] ) && 'failure' === $hooked['status'] && isset( $hooked['redirect_args'] ) ) {
     484                                bp_core_no_access( $hooked['redirect_args'] );
     485                        }
    357486                }
    358487        }
    359488}
    function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ) { 
    454583 *
    455584 * @return bool|null Returns false on failure.
    456585 */
    457 function bp_core_sort_subnav_items() {
     586function bp_core_sort_subnav_items( $component = '' ) {
    458587        $bp = buddypress();
    459588
    460         if ( empty( $bp->bp_options_nav ) || !is_array( $bp->bp_options_nav ) )
     589        if ( empty( $component ) || ! bp_is_active( $component ) ) {
     590                $subnav = $bp->bp_options_nav;
     591        } else {
     592                $subnav = $bp->{$component}->single_subnav;
     593        }
     594
     595        if ( empty( $subnav ) || ! is_array( $subnav ) ) {
    461596                return false;
     597        }
    462598
    463         foreach ( (array) $bp->bp_options_nav as $parent_slug => $subnav_items ) {
     599        foreach ( (array) $subnav as $parent_slug => $subnav_items ) {
    464600                if ( !is_array( $subnav_items ) )
    465601                        continue;
    466602
    function bp_core_sort_subnav_items() { 
    477613                        }
    478614                }
    479615                ksort( $temp );
    480                 $bp->bp_options_nav[$parent_slug] = &$temp;
     616                $subnav[$parent_slug] = &$temp;
    481617                unset( $temp );
    482618        }
     619
     620        if ( empty( $component ) || ! bp_is_active( $component ) ) {
     621                $bp->bp_options_nav = $subnav;
     622        } else {
     623                $bp->{$component}->single_subnav = $subnav;
     624        }
    483625}
    484626add_action( 'wp_head',    'bp_core_sort_subnav_items' );
    485627add_action( 'admin_head', 'bp_core_sort_subnav_items' );
  • src/bp-core/bp-core-filters.php

    diff --git src/bp-core/bp-core-filters.php src/bp-core/bp-core-filters.php
    index cb1bcb9..f63d40b 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}->single_nav ) ) {
     735                        $component_nav_section = '';
     736
     737                        // Get the component nav section name
     738                        foreach ( $bp->{$bp->current_component}->single_nav 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-template.php

    diff --git src/bp-core/bp-core-template.php src/bp-core/bp-core-template.php
    index 641b7fe..b3f8571 100644
     
    1010defined( 'ABSPATH' ) || exit;
    1111
    1212/**
     13 * Output a component's single item main nav
     14 *
     15 * @since BuddyPress (2.3.0)
     16 *
     17 * @param  string $component the component id
     18 */
     19function bp_component_main_nav( $component = '' ) {
     20        $bp = buddypress();
     21
     22        if ( empty( $component ) ) {
     23                $component = bp_is_user() ? $bp->members->id : bp_current_component();
     24        }
     25
     26        if ( ! isset( $bp->{$component}->single_nav ) || ! is_array( $bp->{$component}->single_nav ) ) {
     27                return;
     28        }
     29
     30        foreach ( (array) $bp->{$component}->single_nav as $main_nav_item ) {
     31
     32                $selected = '';
     33
     34                if ( bp_is_current_action( $main_nav_item['slug'] ) ) {
     35                        $selected = ' class="current selected"';
     36                }
     37
     38                echo apply_filters_ref_array( 'bp_component_main_nav_' . $main_nav_item['css_id'], array( '<li id="' . esc_attr( $main_nav_item['slug'] ) . '-' . esc_attr( $main_nav_item['css_id'] ) . '-li" ' . $selected . '><a id="' . esc_attr( $component ) . '-' . esc_attr( $main_nav_item['slug'] ) . '" href="' . esc_url( $main_nav_item['link'] ) . '">' . $main_nav_item['name'] . '</a></li>', &$main_nav_item['slug'] ) );
     39        }
     40}
     41
     42/**
     43 * Output a component's single item options nav
     44 *
     45 * @since BuddyPress (2.3.0)
     46 *
     47 * @param array  $subnav the subnav containing the nav items to output
     48 * @param string $the_index the subnav index containing the nav items
     49 * @param string $selected_item the current item displayed
     50 * @param string $list_type extra css attribute
     51 */
     52function bp_component_options_nav( $subnav, $the_index = '', $selected_item = '', $list_type = '' ) {
     53        $bp = buddypress();
     54
     55        if ( empty( $subnav ) || ! is_array( $subnav ) ) {
     56                return false;
     57        }
     58
     59        // Defaults to bp_option_nav
     60        $filter_prefix = 'bp_get_options_nav';
     61
     62        if ( ! empty( $list_type ) && 'group' !== $list_type && 'personal' !== $list_type && bp_current_component() ) {
     63                $filter_prefix = 'bp_' . bp_current_component() . '_single_subnav';
     64        }
     65
     66        // Loop through each navigation item
     67        foreach ( (array) $subnav[$the_index] as $subnav_item ) {
     68                if ( empty( $subnav_item['user_has_access'] ) ) {
     69                        continue;
     70                }
     71
     72                // If the current action or an action variable matches the nav item id, then add a highlight CSS class.
     73                if ( $subnav_item['slug'] == $selected_item ) {
     74                        $selected = ' class="current selected"';
     75                } else {
     76                        $selected = '';
     77                }
     78
     79                /**
     80                 * Filters the "options nav", the secondary-level single item navigation menu.
     81                 *
     82                 * This is a dynamic filter that is dependent on the provided css_id value.
     83                 *
     84                 * @since BuddyPress (1.1.0)
     85                 *
     86                 * @param string $value         HTML list item for the submenu item.
     87                 * @param array  $subnav_item   Submenu array item being displayed.
     88                 * @param string $selected_item Current action.
     89                 */
     90                echo apply_filters( $filter_prefix . '_' . $subnav_item['css_id'], '<li id="' . esc_attr( $subnav_item['css_id'] . '-' . $list_type . '-li' ) . '" ' . $selected . '><a id="' . esc_attr( $subnav_item['css_id'] ) . '" href="' . esc_url( $subnav_item['link'] ) . '">' . $subnav_item['name'] . '</a></li>', $subnav_item, $selected_item );
     91        }
     92}
     93
     94/**
    1395 * Output the "options nav", the secondary-level single item navigation menu.
    1496 *
    1597 * Uses the $bp->bp_options_nav global to render out the sub navigation for the
    function bp_get_options_nav( $parent_slug = '' ) { 
    55137                }
    56138        }
    57139
    58         // Loop through each navigation item
    59         foreach ( (array) $bp->bp_options_nav[$the_index] as $subnav_item ) {
    60                 if ( empty( $subnav_item['user_has_access'] ) ) {
    61                         continue;
    62                 }
     140        // List type depends on our current component
     141        $list_type = bp_is_group() ? 'groups' : 'personal';
    63142
    64                 // If the current action or an action variable matches the nav item id, then add a highlight CSS class.
    65                 if ( $subnav_item['slug'] == $selected_item ) {
    66                         $selected = ' class="current selected"';
    67                 } else {
    68                         $selected = '';
    69                 }
    70 
    71                 // List type depends on our current component
    72                 $list_type = bp_is_group() ? 'groups' : 'personal';
    73 
    74                 /**
    75                  * Filters the "options nav", the secondary-level single item navigation menu.
    76                  *
    77                  * This is a dynamic filter that is dependent on the provided css_id value.
    78                  *
    79                  * @since BuddyPress (1.1.0)
    80                  *
    81                  * @param string $value         HTML list item for the submenu item.
    82                  * @param array  $subnav_item   Submenu array item being displayed.
    83                  * @param string $selected_item Current action.
    84                  */
    85                 echo apply_filters( 'bp_get_options_nav_' . $subnav_item['css_id'], '<li id="' . esc_attr( $subnav_item['css_id'] . '-' . $list_type . '-li' ) . '" ' . $selected . '><a id="' . esc_attr( $subnav_item['css_id'] ) . '" href="' . esc_url( $subnav_item['link'] ) . '">' . $subnav_item['name'] . '</a></li>', $subnav_item, $selected_item );
    86         }
     143        return bp_component_options_nav( $bp->bp_options_nav, $the_index, $selected_item, $list_type );
    87144}
    88145
    89146/**
    function bp_is_create_blog() { 
    25442601 * @return True if the current page is the blogs directory.
    25452602 */
    25462603function bp_is_blogs_directory() {
    2547         if ( is_multisite() && bp_is_blogs_component() && ! bp_current_action() ) {
     2604        if ( is_multisite() && bp_is_blogs_component() && ! bp_current_action() && ! bp_current_item() ) {
     2605                return true;
     2606        }
     2607
     2608        return false;
     2609}
     2610
     2611/**
     2612 * Does the current page belong to a single blog ?
     2613 *
     2614 * Will return true for any subpage of a single blog.
     2615 *
     2616 * @since  BuddyPress (2.3.0)
     2617 *
     2618 * @return bool True if the current page is part of a single blog.
     2619 */
     2620function bp_is_blog() {
     2621        $retval = bp_is_active( 'blogs' );
     2622
     2623        if ( ! empty( $retval ) ) {
     2624                $retval = bp_is_blogs_component() && bp_blogs_get_current_blog();
     2625        }
     2626
     2627        return (bool) $retval;
     2628}
     2629
     2630/**
     2631 * Is the current page a single blog's home page?
     2632 *
     2633 * URL will vary depending on which blog tab is set to be the "home". By
     2634 * default, it's the blog's recent activity.
     2635 *
     2636 * @since  BuddyPress (2.3.0)
     2637 *
     2638 * @return bool True if the current page is a single blog's home page.
     2639 */
     2640function bp_is_blog_home() {
     2641        if ( bp_is_single_item() && bp_is_blogs_component() && ( ! bp_current_action() || bp_is_current_action( 'home' ) ) ) {
    25482642                return true;
    25492643        }
    25502644
    25512645        return false;
    25522646}
    25532647
     2648/**
     2649 * Is the current page a blog's activity page?
     2650 *
     2651 * Eg http://example.com/sites/mysite/activity/.
     2652 *
     2653 * @since  BuddyPress (2.3.0)
     2654 *
     2655 * @return bool True if the current page is a blog's activity page.
     2656 */
     2657function bp_is_blog_activity() {
     2658        return (bool) ( bp_is_blogs_component() && bp_is_current_action( 'activity' ) );
     2659}
     2660
     2661/**
     2662 * Is the current page a blog's members page?
     2663 *
     2664 * Eg http://example.com/sites/mysite/members/.
     2665 *
     2666 * @since  BuddyPress (2.3.0)
     2667 *
     2668 * @return bool True if the current page is a blog's members page.
     2669 */
     2670function bp_is_blog_members() {
     2671        return (bool) ( bp_is_blogs_component() && bp_is_current_action( 'members' ) );
     2672}
     2673
     2674/**
     2675 * Is the current page a blog's manage page?
     2676 *
     2677 * Eg http://example.com/sites/mysite/manage/.
     2678 *
     2679 * @since  BuddyPress (2.3.0)
     2680 *
     2681 * @return bool True if the current page is a blog's manage page.
     2682 */
     2683function bp_is_blog_manage() {
     2684        return (bool) ( bp_is_blogs_component() && bp_is_current_action( 'manage' ) );
     2685}
     2686
    25542687/** Messages ******************************************************************/
    25552688
    25562689/**
  • 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 389e546..0fe5785 100644
    class BP_Attachment_Avatar extends BP_Attachment { 
    297297        }
    298298
    299299        /**
     300         * Get the blog id to set its avatar
     301         *
     302         * @since BuddyPress (2.3.0)
     303         *
     304         * @return integer the blog id
     305         */
     306        private function get_blog_id() {
     307                $blog_id = 0;
     308
     309                if ( bp_is_blog() ) {
     310                        $blog_id = bp_get_current_blog_id();
     311                }
     312
     313                return $blog_id;
     314        }
     315
     316        /**
    300317         * Build script datas for the Uploader UI
    301318         *
    302319         * @since BuddyPress (2.3.0)
    class BP_Attachment_Avatar extends BP_Attachment { 
    316333                // Get the possible item ids
    317334                $user_id  = $this->get_user_id();
    318335                $group_id = $this->get_group_id();
     336                $blog_id  = $this->get_blog_id();
    319337
    320338                if ( ! empty( $user_id ) ) {
    321339                        // Should we load the the Webcam Avatar javascript file
    class BP_Attachment_Avatar extends BP_Attachment { 
    358376                                3 => __( 'There was a problem deleting the group profile photo. Please try again.', 'buddypress' ),
    359377                                4 => __( 'The group profile photo was deleted successfully!', 'buddypress' ),
    360378                        );
     379                } elseif( ! empty( $blog_id ) ) {
     380                        $script_data['bp_params'] = array(
     381                                'object'     => 'blog',
     382                                'item_id'    => $blog_id,
     383                                'has_avatar' => bp_get_blog_has_avatar( $blog_id ),
     384                                'nonces'     => array(
     385                                        'set'    => wp_create_nonce( 'bp_avatar_cropstore' ),
     386                                        'remove' => wp_create_nonce( 'bp_delete_avatar_link' ),
     387                                ),
     388                        );
     389
     390                        // Set feedback messages
     391                        $script_data['feedback_messages'] = array(
     392                                1 => __( 'There was a problem cropping the site logo.', 'buddypress' ),
     393                                2 => __( 'The site logo was uploaded successfully.', 'buddypress' ),
     394                                3 => __( 'There was a problem deleting the site logo. Please try again.', 'buddypress' ),
     395                                4 => __( 'The site logo was deleted successfully!', 'buddypress' ),
     396                        );
    361397                } else {
    362398                        /**
    363399                         * Use this filter to include specific BuddyPress params for your object
    364                          * e.g. Blavatar
    365400                         *
    366401                         * @since BuddyPress (2.3.0)
    367402                         *
  • 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-members/bp-members-functions.php

    diff --git src/bp-members/bp-members-functions.php src/bp-members/bp-members-functions.php
    index 2f4acc9..ed0c7d0 100644
    function bp_core_activate_signup( $key ) { 
    19011901
    19021902                $user_id = $user['user_id'];
    19031903
     1904                /**
     1905                 * If it's a blog signup and site logos are enabled
     1906                 * save a transient so that the user once loggedin will
     1907                 * be redirected to the edit-logo manage page of his site
     1908                 */
     1909                if ( ! empty( $user['blog_id'] ) && bp_is_active( 'blogs' ) ) {
     1910                        // Taking no risk
     1911                        if ( bp_blogs_is_avatar_uploads_enabled() ) {
     1912                                $transient_key = sprintf( '_bp_activation_%d_redirect', $user_id );
     1913
     1914                                // Five minutes should be ok.
     1915                                set_transient( $transient_key, intval( $user['blog_id'] ), 300 );
     1916                        }
     1917                }
     1918
    19041919        } else {
    19051920                $signups = BP_Signup::get( array(
    19061921                        'activation_key' => $key,
  • 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/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..b2c06f6 100644
     
     1<?php
     2/**
     3 * BuddyPress Blog single item activity
     4 *
     5 * @since 2.3
     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_current_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..73cce09 100644
     
     1<?php
     2/**
     3 * BuddyPress Blog single item header
     4 *
     5 * @since 2.3
     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_current_blog_admins();
     19
     20        do_action( 'bp_after_blog_menu_admins' ); ?>
     21
     22</div><!-- #item-actions -->
     23
     24<div id="item-header-avatar">
     25        <a href="<?php bp_blog_view_details_link(); ?>" title="<?php bp_blog_name(); ?>">
     26
     27                <?php bp_blog_avatar(); ?>
     28
     29        </a>
     30</div><!-- #item-header-avatar -->
     31
     32<div id="item-header-content">
     33        <span class="highlight"><?php bp_current_blog_type(); ?></span>
     34        <span class="activity"><?php bp_blog_last_active(); ?></span>
     35
     36        <?php do_action( 'bp_before_blog_header_meta' ); ?>
     37
     38        <div id="item-meta">
     39
     40                <?php bp_blog_description(); ?>
     41
     42                <div id="item-buttons">
     43
     44                        <?php do_action( 'bp_blog_header_actions' ); ?>
     45
     46                </div><!-- #item-buttons -->
     47
     48                <?php do_action( 'bp_blog_header_meta' ); ?>
     49
     50        </div>
     51</div><!-- #item-header-content -->
     52
     53<?php
     54do_action( 'bp_after_blog_header' );
     55do_action( 'template_notices' );
     56?>
  • 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..2181c5a 100644
     
     1<?php
     2/**
     3 * BuddyPress Blog single item home page
     4 *
     5 * @since 2.3
     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 do_action( 'bp_before_blog_home_content' ); ?>
     19
     20        <div id="item-header" role="complementary">
     21
     22                <?php bp_get_template_part( 'blogs/single/blog-header' ); ?>
     23
     24        </div><!-- #item-header -->
     25
     26        <div id="item-nav">
     27                <div class="item-list-tabs no-ajax" id="object-nav" role="navigation">
     28                        <ul>
     29
     30                                <?php bp_component_main_nav( 'blogs' ); ?>
     31
     32                                <?php do_action( 'bp_blog_main_nav' ); ?>
     33
     34                        </ul>
     35                </div>
     36        </div><!-- #item-nav -->
     37
     38        <div id="item-body">
     39
     40                <?php do_action( 'bp_before_blog_body' );
     41
     42                /**
     43                 * Does this next bit look familiar? If not, go check out WordPress's
     44                 */
     45
     46                        // Looking at home location
     47                        if ( bp_is_blog_home() ) :
     48
     49                                if ( bp_current_blog_has_access() ) {
     50
     51                                        // Load the appropriate front template
     52                                        bp_blogs_load_blog_front_template();
     53
     54                                } else {
     55
     56                                        /**
     57                                         * Fires before the display of the blog status message.
     58                                         *
     59                                         * @since BuddyPress (2.3.0)
     60                                         */
     61                                        do_action( 'bp_before_blog_status_message' ); ?>
     62
     63                                        <div id="message" class="info">
     64                                                <p><?php bp_blog_status_message(); ?></p>
     65                                        </div>
     66
     67                                        <?php
     68
     69                                        /**
     70                                         * Fires after the display of the blog status message.
     71                                         *
     72                                         * @since BuddyPress (2.3.0)
     73                                         */
     74                                        do_action( 'bp_after_blog_status_message' );
     75
     76                                }
     77
     78                        // Not looking at home
     79                        else :
     80
     81                                // Blog manage
     82                                if     ( bp_is_blog_manage()   ) : bp_get_template_part( 'blogs/single/manage'   );
     83
     84                                // Blog Activity
     85                                elseif ( bp_is_blog_activity() ) : bp_get_template_part( 'blogs/single/activity' );
     86
     87                                // Blog Members
     88                                elseif ( bp_is_blog_members()  ) : bp_get_template_part( 'blogs/single/members'  );
     89
     90                                // Anything else (plugins mostly)
     91                                else                             : bp_get_template_part( 'blogs/single/plugins'  );
     92
     93                                endif;
     94
     95                        endif;
     96
     97                do_action( 'bp_after_blog_body' ); ?>
     98
     99        </div><!-- #item-body -->
     100
     101        <?php do_action( 'bp_after_blog_home_content' ); ?>
     102
     103        <?php endwhile; endif; ?>
     104
     105</div><!-- #buddypress -->
  • src/bp-templates/bp-legacy/buddypress/blogs/single/manage.php

    diff --git src/bp-templates/bp-legacy/buddypress/blogs/single/manage.php src/bp-templates/bp-legacy/buddypress/blogs/single/manage.php
    index e69de29..433b13a 100644
     
     1<?php
     2/**
     3 * BuddyPress Blog single item manage page
     4 *
     5 * @since 2.3
     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 if ( bp_is_item_admin() ) : ?>
     17
     18                        <?php bp_blogs_item_subnav();?>
     19
     20                <?php endif; ?>
     21        </ul>
     22</div>
     23
     24<?php
     25$action = bp_action_variable( 0 ) ? bp_action_variable( 0 ) : bp_current_action();
     26
     27switch ( $action ) :
     28        case 'manage'  :
     29                bp_get_template_part( 'blogs/single/settings/general' );
     30                break;
     31        case 'edit-logo'   :
     32                bp_get_template_part( 'blogs/single/settings/logo'   );
     33                break;
     34        default:
     35                bp_get_template_part( 'blogs/single/plugins'          );
     36                break;
     37endswitch;
  • src/bp-templates/bp-legacy/buddypress/blogs/single/members-loop.php

    diff --git src/bp-templates/bp-legacy/buddypress/blogs/single/members-loop.php src/bp-templates/bp-legacy/buddypress/blogs/single/members-loop.php
    index e69de29..4854c72 100644
     
     1<?php
     2/**
     3 * BuddyPress Blog single item members loop
     4 *
     5 * @since 2.3
     6 *
     7 * @package BuddyPress
     8 * @subpackage blogs
     9 */
     10
     11// Exit if accessed directly
     12defined( 'ABSPATH' ) or die; ?>
     13
     14<?php if ( bp_blog_has_members( bp_ajax_querystring( 'blog_members' ) ) ) : ?>
     15
     16        <?php
     17
     18        /**
     19         * Fires before the display of the blog members content.
     20         *
     21         * @since BuddyPress (2.3.0)
     22         */
     23        do_action( 'bp_before_blog_members_content' ); ?>
     24
     25        <div id="pag-top" class="pagination">
     26
     27                <div class="pag-count" id="member-count-top">
     28
     29                        <?php bp_members_pagination_count(); ?>
     30
     31                </div>
     32
     33                <div class="pagination-links" id="member-pag-top">
     34
     35                        <?php bp_members_pagination_links(); ?>
     36
     37                </div>
     38
     39        </div>
     40
     41        <?php
     42
     43        /**
     44         * Fires before the display of the blog members list.
     45         *
     46         * @since BuddyPress (2.3.0)
     47         */
     48        do_action( 'bp_before_blog_members_list' ); ?>
     49
     50        <ul id="member-list" class="item-list" role="main">
     51
     52                <?php while ( bp_blog_members() ) : bp_blog_the_member(); ?>
     53
     54                        <li>
     55                                <div class="item-avatar">
     56                                        <a href="<?php bp_blog_member_permalink(); ?>"><?php bp_blog_member_avatar(); ?></a>
     57                                </div>
     58
     59                                <div class="item">
     60                                        <div class="item-title">
     61                                                <a href="<?php bp_blog_member_permalink(); ?>"><?php bp_blog_member_name(); ?></a>
     62
     63                                                <?php if ( bp_blog_get_member_latest_update() ) : ?>
     64
     65                                                        <span class="update"> <?php bp_blog_member_latest_update(); ?></span>
     66
     67                                                <?php endif; ?>
     68
     69                                        </div>
     70
     71                                        <div class="item-meta"><span class="activity"><?php bp_blog_member_last_active(); ?></span></div>
     72
     73                                        <?php do_action( 'bp_blog_members_item' ); ?>
     74                                </div>
     75
     76                                <div class="action">
     77
     78                                        <?php do_action( 'bp_blog_members_actions' ); ?>
     79
     80                                </div>
     81
     82                                <div class="clear"></div>
     83                        </li>
     84
     85                <?php endwhile; ?>
     86
     87        </ul>
     88
     89        <?php
     90
     91        /**
     92         * Fires after the display of the blog members list.
     93         *
     94         * @since BuddyPress (2.3.0)
     95         */
     96        do_action( 'bp_after_blog_members_list' ); ?>
     97
     98        <div id="pag-bottom" class="pagination">
     99
     100                <div class="pag-count" id="member-count-bottom">
     101
     102                        <?php bp_members_pagination_count(); ?>
     103
     104                </div>
     105
     106                <div class="pagination-links" id="member-pag-bottom">
     107
     108                        <?php bp_members_pagination_links(); ?>
     109
     110                </div>
     111
     112        </div>
     113
     114        <?php
     115
     116        /**
     117         * Fires after the display of the blog members content.
     118         *
     119         * @since BuddyPress (2.3.0)
     120         */
     121        do_action( 'bp_after_blog_members_content' ); ?>
     122
     123<?php else: ?>
     124
     125        <div id="message" class="info">
     126                <p><?php _e( 'No members were found.', 'buddypress' ); ?></p>
     127        </div>
     128
     129<?php endif; ?>
  • src/bp-templates/bp-legacy/buddypress/blogs/single/members.php

    diff --git src/bp-templates/bp-legacy/buddypress/blogs/single/members.php src/bp-templates/bp-legacy/buddypress/blogs/single/members.php
    index e69de29..1d0819d 100644
     
     1<?php
     2/**
     3 * BuddyPress Blog single item members
     4 *
     5 * @since 2.3
     6 *
     7 * @package BuddyPress
     8 * @subpackage blogs
     9 */
     10
     11// Exit if accessed directly
     12defined( 'ABSPATH' ) or die; ?>
     13
     14<form action="" method="post" id="members-blog-form" class="dir-form">
     15
     16        <div class="item-list-tabs" id="subnav" role="navigation">
     17                <ul>
     18                        <?php bp_blogs_item_subnav();?>
     19
     20                        <?php do_action( 'bp_members_blog_member_sub_types' ); ?>
     21
     22                        <li id="members-order-select" class="last filter">
     23                                <label for="members-order-by"><?php _e( 'Order By:', 'buddypress' ); ?></label>
     24                                <select id="members-order-by">
     25                                        <option value="active"><?php _e( 'Last Active', 'buddypress' ); ?></option>
     26
     27                                        <?php if ( bp_is_active( 'xprofile' ) ) : ?>
     28                                                <option value="alphabetical"><?php _e( 'Alphabetical', 'buddypress' ); ?></option>
     29                                        <?php endif; ?>
     30
     31                                        <?php do_action( 'bp_members_blog_order_options' ); ?>
     32                                </select>
     33                        </li>
     34                </ul>
     35        </div>
     36
     37        <div id="blog-list" class="members item-list">
     38                <?php bp_get_template_part( 'blogs/single/members-loop' ); ?>
     39        </div><!-- #members-dir-list -->
     40
     41        <?php do_action( 'bp_blog_members_content' ); ?>
     42
     43        <?php wp_nonce_field( 'blog_members', '_wpnonce-member-filter' ); ?>
     44
     45        <?php do_action( 'bp_after_blog_members_content' ); ?>
     46
     47</form><!-- #members-directory-form -->
     48
     49<?php do_action( 'bp_after_blog_members' ); ?>
  • src/bp-templates/bp-legacy/buddypress/blogs/single/plugins.php

    diff --git src/bp-templates/bp-legacy/buddypress/blogs/single/plugins.php src/bp-templates/bp-legacy/buddypress/blogs/single/plugins.php
    index e69de29..df2fc1b 100644
     
     1<?php
     2/**
     3 * BuddyPress Blog single item plugins
     4 *
     5 * @since 2.3
     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_plugin_template' ); ?>
     15
     16<div class="item-list-tabs no-ajax" id="subnav">
     17        <ul>
     18                <?php bp_blogs_item_subnav();?>
     19
     20                <?php do_action( 'bp_blog_plugin_sub_nav' ); ?>
     21        </ul>
     22</div><!-- .item-list-tabs -->
     23
     24<h3><?php do_action( 'bp_template_title' ); ?></h3>
     25
     26<?php do_action( 'bp_template_content' ); ?>
     27
     28<?php do_action( 'bp_after_blog_plugin_template' ); ?>
  • src/bp-templates/bp-legacy/buddypress/blogs/single/settings/general.php

    diff --git src/bp-templates/bp-legacy/buddypress/blogs/single/settings/general.php src/bp-templates/bp-legacy/buddypress/blogs/single/settings/general.php
    index e69de29..7b0de96 100644
     
     1<?php
     2/**
     3 * BuddyPress Blog single item settings
     4 *
     5 * @since 2.3
     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_settings_template' ); ?>
     15
     16<form action="" method="post" class="standard-form" id="settings-form">
     17
     18        <h4><?php esc_html_e( 'General settings', 'buddypress' ); ?></h4>
     19
     20        <label for="blog_name"><?php esc_html_e( 'Site Name', 'buddypress' ); ?></label>
     21        <input type="text" name="bp_blog[blogname]" id="blog_name" value="<?php echo esc_attr( bp_get_blog_name() ); ?>" class="settings-input" />
     22        <p class="description"><?php esc_html_e( 'This setting is synchronized with the corresponding WordPress setting.', 'buddypress' ); ?></p>
     23
     24        <label for="blog_description"><?php esc_html_e( 'Site Description', 'buddypress' ); ?></label>
     25        <input type="text" name="bp_blog[blogdescription]" id="blog_description" value="<?php echo esc_html( bp_get_blog_description() ); ?>" class="settings-input" />
     26        <p class="description"><?php esc_html_e( 'This setting is synchronized with the corresponding WordPress setting.', 'buddypress' ); ?></p>
     27
     28        <label for="blog_public">
     29                <input type="checkbox" name="bp_blog[blog_public]" id="blog_public" value="1" <?php checked( true, bp_current_blog_is_public() ); ?> />
     30                <?php esc_html_e( 'Public site', 'buddypress' ); ?>
     31        </label>
     32        <p class="description"><?php esc_html_e( 'This setting is synchronized with the &quot;Discourage search engines from indexing this site&quot; WordPress setting.', 'buddypress' ); ?></p>
     33        <p class="description"><?php esc_html_e( 'If you deactivate this option, post types tracking and subscriptions will not be available for your site.', 'buddypress' ); ?></p>
     34
     35        <?php if ( bp_current_blog_is_public() ) : ?>
     36                <label for="blog_disallow_subscriptions">
     37                        <input type="checkbox" name="bp_blog[disallow_subscriptions]" id="blog_disallow_subscriptions" value="1" <?php checked( true, ! bp_current_blog_can_subscribe() ); ?> />
     38                        <?php esc_html_e( 'Disallow subscritions', 'buddypress' ); ?>
     39                </label>
     40                <p class="description"><?php esc_html_e( 'Subscriptions are only available for public sites', 'buddypress' ); ?></p>
     41        <?php endif ; ?>
     42
     43        <?php do_action( 'bp_blog_settings_after_general' ); ?>
     44
     45        <div class="submit">
     46                <input type="submit" name="bp_blog[submit]" value="<?php esc_attr_e( 'Save Changes', 'buddypress' ); ?>" id="submit" class="auto" />
     47        </div>
     48
     49        <?php do_action( 'bp_blog_settings_after_submit' ); ?>
     50
     51        <?php wp_nonce_field( 'blog_settings_general' ); ?>
     52
     53</form>
     54
     55<?php do_action( 'bp_after_blog_settings_template' ); ?>
  • src/bp-templates/bp-legacy/buddypress/blogs/single/settings/logo.php

    diff --git src/bp-templates/bp-legacy/buddypress/blogs/single/settings/logo.php src/bp-templates/bp-legacy/buddypress/blogs/single/settings/logo.php
    index e69de29..91257ae 100644
     
     1<?php
     2/**
     3 * BuddyPress Blog single item edit logo
     4 *
     5 * @since 2.3
     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_avatar_upload_content' ); ?>
     15
     16<p><?php esc_html_e( "Upload an image to use as a logo for this site. The image will be shown on the site&#39;s details page, and in search results.", 'buddypress' ); ?></p>
     17
     18<?php bp_avatar_get_templates(); ?>
     19
     20<?php do_action( 'bp_after_blog_avatar_upload_content' ); ?>
  • src/bp-templates/bp-legacy/css/buddypress.css

    diff --git src/bp-templates/bp-legacy/css/buddypress.css src/bp-templates/bp-legacy/css/buddypress.css
    index 9a64410..a0549f1 100644
    a.bp-title-button { 
    796796        text-decoration: none;
    797797}
    798798
     799#buddypress div.blog-button {
     800        display: inline-block;
     801        margin-left: 5px;
     802}
     803
    799804#buddypress form.standard-form .left-menu {
    800805        float: left;
    801806}
  • tests/phpunit/testcases/core/nav.php

    diff --git tests/phpunit/testcases/core/nav.php tests/phpunit/testcases/core/nav.php
    index 92a7ebd..f391809 100644
     
    55 * @group nav
    66 */
    77class BP_Tests_Core_Nav extends BP_UnitTestCase {
     8
     9        /**
     10         * @group bp_core_new_nav_item
     11         */
     12        public function test_bp_core_new_nav_item_user_nav() {
     13                $bp_nav = buddypress()->bp_nav;
     14
     15                $u = $this->factory->user->create();
     16                $old_current_user = get_current_user_id();
     17                $this->set_current_user( $u );
     18
     19                $this->go_to( bp_core_get_user_domain( $u ) );
     20
     21                bp_core_new_nav_item( array(
     22                        'name'                    => 'Foo',
     23                        'slug'                    => 'foo',
     24                        'position'                => 25,
     25                        'screen_function'         => 'foo_screen_function',
     26                        'default_subnav_slug'     => 'foo-sub'
     27                ) );
     28
     29                $expected = array(
     30                        'name'                    => 'Foo',
     31                        'slug'                    => 'foo',
     32                        'link'                    => trailingslashit( bp_core_get_user_domain( $u ) . 'foo' ),
     33                        'css_id'                  => 'foo',
     34                        'show_for_displayed_user' => true,
     35                        'position'                => 25,
     36                        'screen_function'         => 'foo_screen_function',
     37                        'default_subnav_slug'     => 'foo-sub'
     38                );
     39
     40                $this->assertSame( buddypress()->bp_nav['foo'], $expected );
     41
     42                // Clean up
     43                buddypress()->bp_nav = $bp_nav;
     44                $this->set_current_user( $old_current_user );
     45        }
     46
     47        /**
     48         * @group bp_core_new_nav_item
     49         */
     50        public function test_bp_core_new_nav_item_group_nav() {
     51                $bp_nav = buddypress()->bp_nav;
     52
     53                $u = $this->factory->user->create();
     54                $g = $this->factory->group->create();
     55                $old_current_user = get_current_user_id();
     56                $this->set_current_user( $u );
     57
     58                $group = groups_get_group( array(
     59                        'group_id' => $g,
     60                ) );
     61
     62                $this->go_to( bp_get_group_permalink( $group ) );
     63
     64                $this->assertTrue( buddypress()->bp_nav[ $group->slug ]['position'] === -1 );
     65
     66                // Clean up
     67                buddypress()->bp_nav = $bp_nav;
     68                $this->set_current_user( $old_current_user );
     69        }
     70
     71        /**
     72         * @group bp_core_new_nav_item
     73         */
     74        public function test_bp_core_new_nav_item_foo_nav() {
     75                $bp = buddypress();
     76                $reset_active_components = $bp->active_components;
     77                $reset_current_component = $bp->current_component;
     78                $reset_current_item      = $bp->current_item;
     79                $bp_nav = buddypress()->bp_nav;
     80
     81                if ( ! function_exists( 'bp_get_foo_root_slug') ) {
     82                        function bp_get_foo_root_slug() {
     83                                return 'foo';
     84                        }
     85                }
     86
     87                // Create and activate the foo component
     88                $bp->foo                = new BP_Component;
     89                $bp->foo->id            = 'foo';
     90                $bp->foo->slug          = 'foo';
     91                $bp->foo->name          = 'Foo';
     92                $bp->foo->single_nav    = array();
     93                $bp->active_components[ $bp->foo->id ] = 1;
     94
     95                $bp->current_component = 'foo';
     96                $bp->current_item = 'single-foo';
     97
     98                bp_core_new_nav_item( array(
     99                        'name'                    => 'Bar',
     100                        'slug'                    => 'bar',
     101                        'position'                => 10,
     102                        'screen_function'         => 'bar_screen_function',
     103                        'default_subnav_slug'     => 'bar-sub',
     104                        'single_nav'              => $bp->foo->id
     105                ) );
     106
     107                $expected = array(
     108                        'name'                    => 'Bar',
     109                        'slug'                    => 'bar',
     110                        'link'                    => trailingslashit( bp_get_root_domain() . '/foo/single-foo/bar' ),
     111                        'css_id'                  => 'bar',
     112                        'show_for_displayed_user' => true,
     113                        'position'                => 10,
     114                        'screen_function'         => 'bar_screen_function',
     115                        'default_subnav_slug'     => 'bar-sub'
     116                );
     117
     118                $this->assertTrue( empty( $bp->bp_nav['bar'] ) );
     119                $this->assertSame( $bp->foo->single_nav['bar'], $expected );
     120
     121                // Clean up
     122                $bp->foo->single_nav = array();
     123                $bp->active_components = $reset_active_components;
     124                $bp->current_component = $reset_current_component;
     125                $bp->current_item = $reset_current_item;
     126        }
     127
     128        /**
     129         * @group bp_core_sort_nav_items
     130         */
     131        public function test_bp_core_sort_nav_items() {
     132                $bp_nav = buddypress()->bp_nav;
     133
     134                $u = $this->factory->user->create();
     135                $old_current_user = get_current_user_id();
     136                $this->set_current_user( $u );
     137
     138                $this->go_to( bp_core_get_user_domain( $u ) );
     139
     140                bp_core_new_nav_item( array(
     141                        'name'                    => 'Foo',
     142                        'slug'                    => 'foo',
     143                        'position'                => 25,
     144                        'screen_function'         => 'foo_screen_function',
     145                        'default_subnav_slug'     => 'foo-sub'
     146                ) );
     147
     148                $expected = array(
     149                        'name'                    => 'Foo',
     150                        'slug'                    => 'foo',
     151                        'link'                    => trailingslashit( bp_core_get_user_domain( $u ) . 'foo' ),
     152                        'css_id'                  => 'foo',
     153                        'show_for_displayed_user' => true,
     154                        'position'                => 25,
     155                        'screen_function'         => 'foo_screen_function',
     156                        'default_subnav_slug'     => 'foo-sub'
     157                );
     158
     159                bp_core_sort_nav_items();
     160
     161                $this->assertSame( buddypress()->bp_nav[25], $expected );
     162
     163                // Clean up
     164                buddypress()->bp_nav = $bp_nav;
     165                $this->set_current_user( $old_current_user );
     166        }
     167
     168        /**
     169         * @group bp_core_new_subnav_item
     170         */
     171        public function test_bp_core_new_subnav_item_user_subnav() {
     172                $bp_options_nav = buddypress()->bp_options_nav;
     173
     174                $u = $this->factory->user->create();
     175                $old_current_user = get_current_user_id();
     176                $this->set_current_user( $u );
     177
     178                $user_domain = bp_core_get_user_domain( $u );
     179
     180                $this->go_to( $user_domain );
     181
     182                bp_core_new_subnav_item( array(
     183                        'name'            => 'Foo',
     184                        'slug'            => 'foo',
     185                        'parent_url'      => trailingslashit( $user_domain . 'foo' ),
     186                        'parent_slug'     => 'foo',
     187                        'screen_function' => 'foo_screen_function',
     188                        'position'        => 10
     189                ) );
     190
     191                $expected = array(
     192                        'name'              => 'Foo',
     193                        'link'              => trailingslashit( $user_domain . 'foo/foo' ),
     194                        'slug'              => 'foo',
     195                        'css_id'            => 'foo',
     196                        'position'          => 10,
     197                        'user_has_access'   => true,
     198                        'no_access_url'     => '',
     199                        'screen_function'   => 'foo_screen_function',
     200                        'show_in_admin_bar' => false,
     201                );
     202
     203                $this->assertSame( buddypress()->bp_options_nav['foo']['foo'], $expected );
     204
     205                // Clean up
     206                buddypress()->bp_options_nav = $bp_options_nav;
     207                $this->set_current_user( $old_current_user );
     208        }
     209
     210        /**
     211         * @group bp_core_new_nav_item
     212         */
     213        public function test_bp_core_new_subnav_item_foo_subnav() {
     214                $bp = buddypress();
     215                $reset_active_components = $bp->active_components;
     216
     217                // Create and activate the foo component
     218                $bp->foo                = new BP_Component;
     219                $bp->foo->id            = 'foo';
     220                $bp->foo->slug          = 'foo';
     221                $bp->foo->name          = 'Foo';
     222                $bp->foo->single_nav    = array();
     223                $bp->foo->single_subnav = array();
     224                $bp->active_components[ $bp->foo->id ] = 1;
     225
     226                bp_core_new_subnav_item( array(
     227                        'name'            => 'Bar',
     228                        'slug'            => 'bar',
     229                        'parent_url'      => trailingslashit( bp_get_root_domain() . '/foo/single-foo/bar' ),
     230                        'parent_slug'     => 'bar',
     231                        'screen_function' => 'bar_screen_function',
     232                        'position'        => 10,
     233                        'single_subnav'   => $bp->foo->id
     234                ) );
     235
     236                $expected = array(
     237                        'name'              => 'Bar',
     238                        'link'              => trailingslashit( bp_get_root_domain() . '/foo/single-foo/bar/bar' ),
     239                        'slug'              => 'bar',
     240                        'css_id'            => 'bar',
     241                        'position'          => 10,
     242                        'user_has_access'   => true,
     243                        'no_access_url'     => '',
     244                        'screen_function'   => 'bar_screen_function',
     245                        'show_in_admin_bar' => false,
     246                );
     247
     248                $this->assertTrue( empty( $bp->bp_options_nav['bar'] ) );
     249                $this->assertSame( $bp->foo->single_subnav['bar']['bar'], $expected );
     250
     251                // Clean up
     252                $bp->foo->single_subnav = array();
     253                $bp->active_components = $reset_active_components;
     254        }
     255
     256
    8257        /**
    9258         * @group bp_core_new_subnav_item
    10259         */
    class BP_Tests_Core_Nav extends BP_UnitTestCase { 
    400649
    401650                $this->assertSame( $link, buddypress()->bp_options_nav['foo']['bar']['link'] );
    402651        }
     652
     653        /**
     654         * @group bp_core_sort_subnav_items
     655         */
     656        public function test_bp_core_sort_subnav_items() {
     657                $bp_options_nav = buddypress()->bp_options_nav;
     658
     659                $u = $this->factory->user->create();
     660                $old_current_user = get_current_user_id();
     661                $this->set_current_user( $u );
     662
     663                $user_domain = bp_core_get_user_domain( $u );
     664
     665                $this->go_to( $user_domain );
     666
     667                bp_core_new_subnav_item( array(
     668                        'name'            => 'Foo',
     669                        'slug'            => 'foo',
     670                        'parent_url'      => trailingslashit( $user_domain . 'foo' ),
     671                        'parent_slug'     => 'foo',
     672                        'screen_function' => 'foo_screen_function',
     673                        'position'        => 10
     674                ) );
     675
     676                bp_core_sort_subnav_items();
     677
     678                $expected = array(
     679                        'name'              => 'Foo',
     680                        'link'              => trailingslashit( $user_domain . 'foo/foo' ),
     681                        'slug'              => 'foo',
     682                        'css_id'            => 'foo',
     683                        'position'          => 10,
     684                        'user_has_access'   => true,
     685                        'no_access_url'     => '',
     686                        'screen_function'   => 'foo_screen_function',
     687                        'show_in_admin_bar' => false,
     688                );
     689
     690                $this->assertSame( buddypress()->bp_options_nav['foo'][10], $expected );
     691
     692                // Clean up
     693                buddypress()->bp_options_nav = $bp_options_nav;
     694                $this->set_current_user( $old_current_user );
     695        }
    403696}