Skip to:
Content

BuddyPress.org

Ticket #3460: 3460.05.patch

File 3460.05.patch, 42.9 KB (added by imath, 6 years ago)
  • bp-activity/bp-activity-functions.php

    diff --git bp-activity/bp-activity-functions.php bp-activity/bp-activity-functions.php
    index c9d66d7..768fc8f 100644
    function bp_activity_get_permalink( $activity_id, $activity_obj = false ) { 
    15381538                $activity_obj = $activity_obj->current_comment;
    15391539        }
    15401540
    1541         if ( 'new_blog_post' == $activity_obj->type || 'new_blog_comment' == $activity_obj->type || 'new_forum_topic' == $activity_obj->type || 'new_forum_post' == $activity_obj->type ) {
     1541        $use_primary_link = array( 'new_forum_topic', 'new_forum_post' );
     1542
     1543        if ( bp_is_active( 'blogs' ) ) {
     1544                // Gets all post types activity actions available
     1545                $blogs_post_types        = get_object_vars( buddypress()->activity->actions->blogs );
     1546                // Adds them to the array to check.
     1547                $use_primary_link = array_merge( $use_primary_link, array_keys( $blogs_post_types ) );
     1548        }
     1549
     1550        if ( in_array( $activity_obj->type, $use_primary_link ) ) {
    15421551                $link = $activity_obj->primary_link;
    15431552        } else {
    15441553                if ( 'activity_comment' == $activity_obj->type ) {
  • bp-activity/bp-activity-template.php

    diff --git bp-activity/bp-activity-template.php bp-activity/bp-activity-template.php
    index b416e3a..dfa449c 100644
    function bp_activity_can_comment() { 
    26262626        $can_comment = true;
    26272627
    26282628        if ( false === $activities_template->disable_blogforum_replies || (int) $activities_template->disable_blogforum_replies ) {
    2629                 if ( 'new_blog_post' == bp_get_activity_action_name() || 'new_blog_comment' == bp_get_activity_action_name() || 'new_forum_topic' == bp_get_activity_action_name() || 'new_forum_post' == bp_get_activity_action_name() )
     2629                // initialize with forum activity types
     2630                $activity_comment_types = array( 'new_forum_topic', 'new_forum_post' );
     2631
     2632                if ( bp_is_active( 'blogs' ) ) {
     2633                        // Gets all post types activity actions available
     2634                        $blogs_post_types        = get_object_vars( buddypress()->activity->actions->blogs );
     2635                        // Adds them to the array to check.
     2636                        $activity_comment_types = array_merge( $activity_comment_types, array_keys( $blogs_post_types ) );
     2637                }
     2638
     2639                if ( in_array( bp_get_activity_action_name(), $activity_comment_types ) )
    26302640                        $can_comment = false;
    26312641        }
    26322642
  • bp-blogs/bp-blogs-activity.php

    diff --git bp-blogs/bp-blogs-activity.php bp-blogs/bp-blogs-activity.php
    index 70c41c6..9b4847a 100644
    if ( !defined( 'ABSPATH' ) ) exit; 
    2020 * @return bool|null Returns false if activity component is not active.
    2121 */
    2222function bp_blogs_register_activity_actions() {
    23         global $bp;
     23        global $bp, $_wp_post_type_features, $wp_post_types;
    2424
    2525        // Bail if activity is not active
    2626        if ( ! bp_is_active( 'activity' ) ) {
    function bp_blogs_register_activity_actions() { 
    3131                bp_activity_set_action( $bp->blogs->id, 'new_blog', __( 'New site created',        'buddypress' ) );
    3232        }
    3333
    34         bp_activity_set_action( $bp->blogs->id, 'new_blog_post',    __( 'New post published',      'buddypress' ) );
    35         bp_activity_set_action( $bp->blogs->id, 'new_blog_comment', __( 'New post comment posted', 'buddypress' ) );
     34        /**
     35         * if post type argument 'bp_tracking' (array) is set and these two labels are set, they will override default values.
     36         * labels are :
     37         *
     38         * - activity_post_type_action_label         // the post type main action label
     39         * - activity_post_type_comment_action_label // the post type comment action label
     40         *
     41         * Plugins developers can set these, by adding a bp_tracking argument when registering their post type
     42         * see how to set a post type argument: http://codex.wordpress.org/Function_Reference/register_post_type#Arguments
     43         */
     44
     45        foreach( $_wp_post_type_features as $post => $post_type ) {
     46       
     47                // if the admin did not activate the post type, continue..
     48                if ( ! bp_blogs_is_blog_post_type_trackable( $post ) )
     49                        continue;
     50
     51                /** Posts ************************************************/
     52
     53                // Default values
     54                $post_type_activity_action       = 'new_blog_'. $post;
     55                $post_type_activity_action_label = lcfirst( esc_html( $wp_post_types[ $post ]->labels->singular_name ) );
     56
     57                // overridden value provided by the post type when registering
     58                if ( ! empty( $wp_post_types[ $post ]->bp_tracking['activity_post_type_action'] ) ) {
     59                        $post_type_activity_action       = esc_html( $wp_post_types[ $post ]->bp_tracking['activity_post_type_action'] );
     60                }
     61
     62                if ( ! empty( $wp_post_types[ $post ]->bp_tracking['activity_post_type_action_label'] ) ) {
     63                        $post_type_activity_action_label = esc_html( $wp_post_types[ $post ]->bp_tracking['activity_post_type_action_label'] );
     64                }
     65
     66                // Registering the post type activity action
     67                bp_activity_set_action( $bp->blogs->id, $post_type_activity_action, sprintf( __( 'New %s published', 'buddypress' ), $post_type_activity_action_label ) );
     68               
     69
     70                /** Comments ************************************************/
     71
     72                // Checking if post type has comments support else no need to set the activity, as there should never be a comment.
     73                if ( ! post_type_supports( $post, 'comments' ) )
     74                        continue;
     75
     76                // Default values
     77                $comment_prefix = ( 'post' == $post ) ? '' : $post . '_';
     78                $post_type_comment_activity_action       = "new_blog_{$comment_prefix}comment";
     79                $post_type_comment_activity_action_label = lcfirst( esc_html( $wp_post_types[$post]->labels->singular_name ) ) . ' comment';
     80
     81                if ( ! empty( $wp_post_types[ $post ]->bp_tracking['activity_post_type_comment_action'] ) ) {
     82                        $post_type_comment_activity_action       = esc_html( $wp_post_types[ $post ]->bp_tracking['activity_post_type_comment_action'] );
     83                }
     84
     85                if ( ! empty( $wp_post_types[ $post ]->bp_tracking['activity_post_type_comment_action_label'] ) ) {
     86                        $post_type_comment_activity_action_label = esc_html( $wp_post_types[ $post ]->bp_tracking['activity_post_type_comment_action_label'] );
     87                }
     88               
     89                // Registering the post type comment activity action
     90                bp_activity_set_action( $bp->blogs->id, $post_type_comment_activity_action, sprintf( __( 'New %s posted', 'buddypress' ), $post_type_comment_activity_action_label ) );
     91        }
     92
     93
     94        // Adding the specific to subsite post types if any
     95        if ( is_multisite() ) {
     96               
     97                $subsites_post_type_actions = bp_get_option( 'bp-enabled-subsites-post-type-actions', array() );
     98
     99                if ( ! empty( $subsites_post_type_actions ) ) {
     100
     101                        foreach ( $subsites_post_type_actions as $subsites_post_type ) {
     102
     103                                if ( empty( $subsites_post_type['actions'] ) )
     104                                        continue;
     105
     106                                foreach( $subsites_post_type['actions'] as $subsites_action  ) {
     107                                        // Registering the specific to subsite activity actions
     108                                        bp_activity_set_action( $bp->blogs->id, $subsites_action['action'], sprintf( __( 'New %s posted', 'buddypress' ), $subsites_action['label'] ) );
     109                                }       
     110                        }
     111                }
     112        }
    36113
    37114        do_action( 'bp_blogs_register_activity_actions' );
    38115}
    39 add_action( 'bp_register_activity_actions', 'bp_blogs_register_activity_actions' );
     116add_action( 'bp_catch_post_types', 'bp_blogs_register_activity_actions' );
    40117
    41118/**
    42119 * Record blog-related activity to the activity stream.
  • bp-blogs/bp-blogs-admin.php

    diff --git bp-blogs/bp-blogs-admin.php bp-blogs/bp-blogs-admin.php
    index e69de29..a96fb44 100644
     
     1<?php
     2// Exit if accessed directly
     3if ( !defined( 'ABSPATH' ) ) exit;
     4
     5if ( !class_exists( 'BP_Blogs_Admin' ) ) :
     6/**
     7 * Load Blogs admin area.
     8 *
     9 * @package BuddyPress
     10 * @subpackage blogsAdministration
     11 *
     12 * @since BuddyPress (?)
     13 */
     14class BP_Blogs_Admin {
     15
     16        /** Vars *************************************************************/
     17
     18        /**
     19         * Current blog id.
     20         *
     21         * @var string $blog_id
     22         */
     23        public $blog_id = '';
     24
     25        /**
     26         * The list of post types active on the network.
     27         *
     28         * @var array $network_active
     29         */
     30        public $network_active;
     31
     32        /**
     33         * The list of post type to track for the current blog
     34         *
     35         * @var array $tracked_post_types
     36         */
     37        public $tracked_post_types;
     38
     39        /**
     40         * Is this blog trackable ?
     41         *
     42         * @var boolean
     43         */
     44        public $is_public = '';
     45
     46
     47        /**
     48         * Setup BP Blogs Admin.
     49         *
     50         * @access public
     51         * @since BuddyPress (?)
     52         *
     53         * @uses buddypress() to get BuddyPress main instance
     54         */
     55        public static function register_blogs_admin() {
     56                if( ! is_admin() )
     57                        return;
     58
     59                $bp = buddypress();
     60
     61                if( empty( $bp->blogs->admin ) ) {
     62                        $bp->blogs->admin = new self;
     63                }
     64
     65                return $bp->blogs->admin;
     66        }
     67
     68        /**
     69         * Constructor method.
     70         *
     71         * @access public
     72         * @since BuddyPress (?)
     73         */
     74        public function __construct() {
     75                $this->setup_globals();
     76                $this->setup_actions();
     77        }
     78
     79        /**
     80         * Set admin-related globals.
     81         *
     82         * @access private
     83         * @since BuddyPress (?)
     84         */
     85        private function setup_globals() {
     86
     87                $this->blog_id            = get_current_blog_id();
     88                $this->network_active     = bp_trackable_post_types();
     89                $this->tracked_post_types = bp_blogs_blog_trackable_post_type();
     90                $this->is_public          = get_option( 'blog_public' );
     91
     92        }
     93
     94        /**
     95         * Set admin-related actions and filters.
     96         *
     97         * @access private
     98         * @since BuddyPress (?)
     99         */
     100        private function setup_actions() {
     101                // Bail if blog is not trackable
     102                if ( empty( $this->is_public ) )
     103                        return;
     104
     105                // Add an option page to blog settings
     106                add_action( 'admin_menu', array( $this, 'admin_menus' ) );
     107
     108                // Register the blog tracking settings
     109                add_action( 'bp_register_admin_settings', array( $this, 'blog_settings' ) );
     110        }
     111
     112        /**
     113         * Create the options sub menu.
     114         *
     115         * @access public
     116         * @since BuddyPress (?)
     117         *
     118         * @uses add_options_page() To add the Site tracking submenu.
     119         */
     120        public function admin_menus() {
     121
     122                $hook = add_options_page(
     123                        __( 'Site Tracking', 'buddypress' ),
     124                        __( 'Site Tracking', 'buddypress' ),
     125                        'manage_options',
     126                        'bp-tracking',
     127                        array( &$this, 'tracking_settings' )
     128                );
     129
     130                add_action( "admin_head-$hook", array( $this, 'activity_actions' ) );
     131
     132        }
     133
     134        /**
     135         * Create the settings page.
     136         *
     137         * @access public
     138         * @since BuddyPress (?)
     139         */
     140        public function tracking_settings() {
     141                ?>
     142                <div class="wrap">
     143                        <?php screen_icon( 'buddypress' ); ?>
     144
     145                        <h2><?php esc_html_e( 'Settings', 'buddypress' ); ?></h2>
     146
     147                        <form action="options.php" method="post">
     148
     149                                <?php settings_fields( 'buddypress_blog' ); ?>
     150
     151                                <?php do_settings_sections( 'buddypress_blog' ); ?>
     152
     153                                <p class="submit">
     154                                        <input type="submit" name="submit" class="button-primary" value="<?php esc_attr_e( 'Save Settings', 'buddypress' ); ?>" />
     155                                </p>
     156                        </form>
     157                </div>
     158                <?php
     159        }
     160
     161        /**
     162         * Create the settings section & fields.
     163         *
     164         * @access public
     165         * @since BuddyPress (?)
     166         */
     167        public function blog_settings() {
     168                // Add the main section
     169                add_settings_section(
     170                        'bp_blog',
     171                        '',
     172                        array( &$this, 'main_section_callback' ),
     173                        'buddypress_blog'
     174                );
     175
     176                // Add the site tracking section
     177                add_settings_section(
     178                        'bp_tracking',
     179                        __( 'Site Tracking Settings', 'buddypress' ),
     180                        array( &$this, 'tracking_section_callback' ),
     181                        'buddypress_blog'
     182                );
     183
     184                // Add the tracking setting
     185                add_settings_field(
     186                        'bp-enabled-post-types',
     187                        __( 'List of post types to track', 'buddypress' ),
     188                        array( &$this, 'post_types_setting_callback' ),
     189                        'buddypress_blog',
     190                        'bp_tracking'
     191                );
     192
     193                register_setting(
     194                        'buddypress_blog',
     195                        'bp-enabled-post-types',
     196                        array( &$this, 'post_types_sanitize_callback' )
     197                );
     198        }
     199
     200        /**
     201         * Output the main section callback
     202         *
     203         * @access public
     204         * @since  BuddyPress (?)
     205         */
     206        public function main_section_callback() {}
     207
     208        /**
     209         * Output the tracking section callback
     210         *
     211         * @access public
     212         * @since  BuddyPress (?)
     213         */
     214        public function tracking_section_callback() {
     215                ?>
     216                <p class="description">
     217                        <?php esc_html_e( 'List of the post types active for tracking on the network:', 'buddypress' ) ;?>
     218
     219                        <ol>
     220                        <?php foreach ( $this->network_active as $post_type => $active ) :
     221                                if ( empty( $active ) )
     222                                        continue;
     223                                ?>
     224
     225                                <li><?php echo esc_html( ucfirst( $post_type ) );?></li>
     226
     227                        <?php endforeach; ?>
     228                        </ol>
     229
     230                </p>
     231                <p class="description"><?php printf( __( 'You can disable the tracking of your site by <a href="%s">discouraging</a> search engines from indexing your site', 'buddypress' ), admin_url( 'options-reading.php#blog_public' ) ); ?></p>
     232                <p class="description"><?php esc_html_e( 'Manage your site post types by enabling, disabling the checkboxes', 'buddypress' ) ;?></p>
     233                <?php
     234        }
     235
     236        /**
     237         * Output the tracking section callback
     238         *
     239         * @access public
     240         * @since  BuddyPress (?)
     241         *
     242         * @uses bp_admin_setting_callback_post_types_tracked() to get the output
     243         */
     244        public function post_types_setting_callback() {
     245                return bp_admin_setting_callback_post_types_tracked( $this->tracked_post_types );
     246        }
     247
     248        /**
     249         * Sanitize the tracking setting
     250         *
     251         * @access public
     252         * @since  BuddyPress (?)
     253         *
     254         * @uses bp_admin_sanitize_callback_post_types_tracked() to sanitize the option
     255         */
     256        public function post_types_sanitize_callback( $option = array() ) {
     257                return bp_admin_sanitize_callback_post_types_tracked( $option );
     258        }
     259
     260        /**
     261         * Makes sure the different activity actions will be available on root blog
     262         *
     263         * @access public
     264         * @since  BuddyPress (?)
     265         */
     266        public function activity_actions() {
     267                // Bail if no settings were updated
     268                if ( empty( $_GET['settings-updated'] ) || 'true' != $_GET['settings-updated'] )
     269                        return;
     270
     271                /**
     272                 * In order to populate the selectbox filters in activity directory and members activity page
     273                 * we need to save the post type activity type and label into a network option
     274                 */
     275                $network_compare = array_diff_key( $this->tracked_post_types, $this->network_active );
     276
     277                // the network option
     278                $subsite_cached_post_type_actions = bp_get_option( 'bp-enabled-subsites-post-type-actions', array() );
     279
     280                // network post types that are specific to subsite
     281                $subsite_compare = array_diff_key( $subsite_cached_post_type_actions, $this->tracked_post_types );
     282               
     283                /**
     284                 * One or more post types active on this blog are not on network
     285                 * Let's save its action & label
     286                 */
     287                if ( ! empty( $network_compare ) ) {
     288
     289                        foreach ( array_keys( $network_compare ) as $post ) {
     290                               
     291                                if ( empty( $subsite_cached_post_type_actions[ $post ] ) ) {
     292
     293                                        $post_type = get_post_type_object( $post );
     294
     295                                        $action = ! empty( $post_type->bp_tracking['activity_post_type_action'] ) ? esc_html( $post_type->bp_tracking['activity_post_type_action'] ) : 'new_blog_'. $post;
     296                                        $label  = ! empty( $post_type->bp_tracking['activity_post_type_action_label'] ) ? esc_html( $post_type->bp_tracking['activity_post_type_action_label'] ) : lcfirst( esc_html( $post_type->labels->singular_name ) );
     297
     298                                        $subsite_cached_post_type_actions[ $post ]['actions'][] = array(
     299                                                'action' => $action,
     300                                                'label'  => $label
     301                                        );
     302
     303                                        // Adding the blog to the list
     304                                        $subsite_cached_post_type_actions[ $post ]['blogs'][] = $this->blog_id;
     305
     306                                        if ( post_type_supports( $post, 'comments' ) ) {
     307
     308                                                $action_comment = ! empty( $post_type->bp_tracking['activity_post_type_comment_action'] ) ? esc_html( $post_type->bp_tracking['activity_post_type_comment_action'] ) : "new_blog_{$post}_comment" ;
     309                                                $label_comment  = ! empty( $post_type->bp_tracking['activity_post_type_comment_action_label'] ) ? esc_html( $post_type->bp_tracking['activity_post_type_comment_action_label'] ) : lcfirst( esc_html( $post_type->labels->singular_name ) . ' comment' );
     310
     311                                                $subsite_cached_post_type_actions[ $post ]['actions'][] = array(
     312                                                        'action' => $action_comment,
     313                                                        'label'  => $label_comment
     314                                                );
     315                                        }
     316
     317                                } else {
     318                                        // Simply add the blog to the list if it's not already in
     319                                        if ( in_array( $this->blog_id, $subsite_cached_post_type_actions[ $post ]['blogs'] ) )
     320                                                continue;
     321                                       
     322                                        $subsite_cached_post_type_actions[ $post ]['blogs'][] = $this->blog_id;
     323                                }
     324                        }
     325
     326                        bp_update_option( 'bp-enabled-subsites-post-type-actions', $subsite_cached_post_type_actions );
     327                }
     328
     329                /**
     330                 * The post type is no more tracked
     331                 */
     332                if ( ! empty( $subsite_compare ) ) {
     333
     334                        foreach( $subsite_compare as $post => $post_type ) {
     335                                // this should not happen..
     336                                if ( empty( $subsite_compare[ $post ]['blogs'] ) )
     337                                        continue;
     338
     339                                // removing the blog from the list
     340                                if ( in_array( $this->blog_id, $subsite_compare[ $post ]['blogs'] ) ) {
     341                                        $blog_index = array_flip( $subsite_compare[ $post ]['blogs'] );
     342                                        unset( $subsite_compare[ $post ]['blogs'][ $blog_index[ $this->blog_id ] ] );
     343                                }
     344
     345                                // Remove post type that are no more active on any blogs
     346                                if ( empty( $subsite_compare[ $post ]['blogs'] ) ) {
     347                                        unset( $subsite_compare[ $post ] );
     348                                }
     349                                       
     350                        }
     351
     352                        // nothing left, just delete the option
     353                        if ( empty( $subsite_compare ) ) {
     354                                bp_delete_option( 'bp-enabled-subsites-post-type-actions' );
     355                        // some blogs are still using specific post types, just update the option
     356                        } else {
     357                                bp_update_option( 'bp-enabled-subsites-post-type-actions', $subsite_compare );
     358                        }
     359                }
     360
     361        }
     362
     363}
     364endif; // class_exists check
     365
     366// Load the BP Blogs admin
     367add_action( 'bp_init', array( 'BP_Blogs_Admin','register_blogs_admin' ) );
  • bp-blogs/bp-blogs-functions.php

    diff --git bp-blogs/bp-blogs-functions.php bp-blogs/bp-blogs-functions.php
    index f887dd9..56f219c 100644
    function bp_blogs_is_blog_trackable( $blog_id, $user_id = 0 ) { 
    158158        return $trackable_globally;
    159159}
    160160
     161
     162function bp_blogs_blog_trackable_post_type( $default = array(), $blog_id = 0 ) {
     163        if ( empty( $blog_id ) )
     164                $blog_id = get_current_blog_id();
     165
     166        if ( empty( $default) )
     167                $default = array( 'post' => 1 );
     168
     169        $default = array_merge( bp_trackable_post_types(), $default );
     170
     171        return (array) apply_filters( 'bp_blogs_blog_trackable_post_types', (array) get_blog_option( $blog_id, 'bp-enabled-post-types', $default ), $blog_id );
     172}
     173
     174/**
     175 * Check whether a given blog post type should be tracked by the Blogs component.
     176 *
     177 * If $blog_id is provided, the developer can restrict a given blog post type from
     178 * being trackable.
     179 *
     180 * @since BuddyPress (?)
     181 *
     182 * @uses bp_trackable_post_types()
     183 * @uses apply_filters()
     184 *
     185 * @param string $post_type the post type being checked.
     186 * @param int $blog_id the blog the post type is registered to.
     187 * @return bool True if the post type is trackable, otherwise false.
     188 */
     189function bp_blogs_is_blog_post_type_trackable( $post_type = '', $blog_id = 0 ) {
     190        /**
     191         * If blog id is not root_blog_id, get the current blog settings instead of network one
     192         */
     193        if ( $blog_id != bp_get_root_blog_id() ) {
     194                $trackable = (array) apply_filters( 'bp_blogs_is_blog_post_type_trackable', bp_blogs_blog_trackable_post_type( array(), $blog_id ), $blog_id );
     195        } else {
     196                $trackable = (array) apply_filters( 'bp_blogs_is_blog_post_type_trackable', bp_trackable_post_types(),                            $blog_id );
     197        }
     198
     199        // BackCompat
     200        $legacy_post_type_filter = apply_filters( 'bp_blogs_record_post_post_types', array() );
     201        $legacy_comment_filter   = apply_filters( 'bp_blogs_record_comment_post_types', array() );
     202        $legacy_post_type_filter = array_merge( $legacy_post_type_filter, $legacy_comment_filter );
     203
     204        if ( ! empty( $legacy_post_type_filter ) ) {
     205                $legacy_post_type_filter = array_fill_keys( $legacy_post_type_filter, 1 );
     206
     207                // Merge the two arrays making sure the setting saved for the post type will be the final value
     208                $trackable = array_merge( $legacy_post_type_filter, $trackable );
     209        }
     210
     211        return ! empty( $trackable[ $post_type ] );
     212}
     213
    161214/**
    162215 * Make BuddyPress aware of a new site so that it can track its activity.
    163216 *
    function bp_blogs_catch_published_post( $new_status, $old_status, $post ) { 
    280333add_action( 'transition_post_status', 'bp_blogs_catch_published_post', 10, 3 );
    281334
    282335/**
     336 * Callback function to build the permalink to the post type
     337 *
     338 * @since  BuddyPress (?)
     339 *
     340 * @param  integer $post_id the post type id
     341 * @param  integer $blog_id the blog id
     342 * @param  WP_Post  $post    Post object.
     343 * @uses   add_query_arg()   To add custom args to the url
     344 * @uses   get_home_url()
     345 * @return string           the post type permalink
     346 */
     347function bp_blogs_activity_post_type_permalink_callback( $post_id = 0, $blog_id = 0, $post = null ) {
     348        $post_permalink = add_query_arg(
     349                'p',
     350                $post_id,
     351                trailingslashit( get_home_url( $blog_id ) )
     352        );
     353
     354        return $post_permalink;
     355}
     356
     357/**
     358 * Callback function to build the action for the post type
     359 *
     360 * @param  array  $args the available arguments
     361 * @uses   bp_core_get_userlink() to build the post author profile link
     362 * @uses   get_blog_option() WordPress function to fetch blog meta.
     363 * @return string the activity action
     364 */
     365function bp_blogs_activity_post_type_action_callback( $args = array() ) {
     366
     367        $r = bp_parse_args( $args, array(
     368                'post_author'             => bp_loggedin_user_id(),
     369                'post_title'              => '',
     370                'singular_post_type_name' => '',
     371                'blog_id'                 => 0,
     372                'post_permalink'          => '',
     373        ), 'blogs_activity_post_type_action_callback' );
     374
     375        extract( $r, EXTR_SKIP );
     376
     377        if ( ! empty( $blog_id ) ) {
     378                $activity_action  = sprintf( __( '%1$s wrote a new %2$s, %3$s, on the site %4$s', 'buddypress' ), bp_core_get_userlink( (int) $post_author ), $singular_post_type_name, '<a href="' . $post_permalink . '">' . $post_title . '</a>', '<a href="' . get_blog_option( $blog_id, 'home' ) . '">' . get_blog_option( $blog_id, 'blogname' ) . '</a>' );
     379        } else {
     380                $activity_action  = sprintf( __( '%1$s wrote a new %2$s, %3$s', 'buddypress' ), bp_core_get_userlink( (int) $post_author ), $singular_post_type_name, '<a href="' . $post_permalink . '">' . $post_title . '</a>' );
     381        }
     382
     383        return $activity_action;
     384}
     385
     386/**
    283387 * Record a new blog post in the BuddyPress activity stream.
    284388 *
    285389 * @param int $post_id ID of the post being recorded.
    function bp_blogs_record_post( $post_id, $post, $user_id = 0 ) { 
    313417        if ( (int) $blog_id == $tags_blog_id && apply_filters( 'bp_blogs_block_sitewide_tags_activity', true ) )
    314418                return false;
    315419
    316         // Don't record this if it's not a post
    317         if ( !in_array( $post->post_type, apply_filters( 'bp_blogs_record_post_post_types', array( 'post' ) ) ) )
     420        // Don't record this if the post type is not trackable
     421        if ( ! bp_blogs_is_blog_post_type_trackable( $post->post_type, $blog_id ) )
    318422                return false;
    319423
    320424        $is_blog_public = apply_filters( 'bp_is_blog_public', (int)get_blog_option( $blog_id, 'blog_public' ) );
    function bp_blogs_record_post( $post_id, $post, $user_id = 0 ) { 
    323427                if ( $is_blog_public || !is_multisite() ) {
    324428
    325429                        // Record this in activity streams
    326                         $post_permalink = add_query_arg(
    327                                 'p',
    328                                 $post_id,
    329                                 trailingslashit( get_home_url( $blog_id ) )
     430                        $post_type_object = get_post_type_object( $post->post_type );
     431
     432                        // Initializing the action arguments
     433                        $action_args = array(
     434                                'post_author'              => absint( $post->post_author ),
     435                                'post_title'               => esc_html( $post->post_title ),
     436                                'singular_post_type_name'  => lcfirst( esc_html( $post_type_object->labels->singular_name ) ),
     437                                'blog_id'                  => is_multisite() ? $blog_id : 0,
    330438                        );
    331439
    332                         if ( is_multisite() )
    333                                 $activity_action  = sprintf( __( '%1$s wrote a new post, %2$s, on the site %3$s', 'buddypress' ), bp_core_get_userlink( (int) $post->post_author ), '<a href="' . $post_permalink . '">' . $post->post_title . '</a>', '<a href="' . get_blog_option( $blog_id, 'home' ) . '">' . get_blog_option( $blog_id, 'blogname' ) . '</a>' );
    334                         else
    335                                 $activity_action  = sprintf( __( '%1$s wrote a new post, %2$s', 'buddypress' ), bp_core_get_userlink( (int) $post->post_author ), '<a href="' . $post_permalink . '">' . $post->post_title . '</a>' );
     440                        if ( ! empty( $post_type_object->bp_tracking ) ) {
     441                                /**
     442                                 * Extracting bp_tracking post type argument will give us the following vars (if set):
     443                                 * - activity_post_type_action                   // the post type main action
     444                                 * - activity_post_type_action_label             // the post type main action label (used in template filter box)
     445                                 * - activity_post_type_permalink_callback       // the post type provided function to build the permalink
     446                                 * - activity_post_type_action_callback          // the post type provided function to build the activity action
     447                                 *
     448                                 * Plugins developers can set these, by adding a bp_tracking argument when registering their post type
     449                                 * see how to set a post type argument: http://codex.wordpress.org/Function_Reference/register_post_type#Arguments
     450                                 */
     451                                extract( $post_type_object->bp_tracking, EXTR_SKIP );
     452
     453                                // Builds the permalink to the post_type using the callback function provided by the post type
     454                                if ( ! empty( $activity_post_type_permalink_callback ) && is_callable( $activity_post_type_permalink_callback ) )
     455                                        $action_args['post_permalink'] = call_user_func_array( $activity_post_type_permalink_callback, array( $post_id, $blog_id, $post ) );
     456
     457                                // Builds the activity action for the post type
     458                                if ( ! empty( $activity_post_type_action_callback ) && is_callable( $activity_post_type_action_callback ) )
     459                                        $activity_action               = call_user_func_array( $activity_post_type_action_callback, array( $action_args ) );
     460
     461                        }
     462
     463                        if ( empty( $action_args['post_permalink'] ) )
     464                                $action_args['post_permalink'] = bp_blogs_activity_post_type_permalink_callback( $post_id, $blog_id, $post );
     465
     466                        if ( empty( $activity_action ) )
     467                                $activity_action               = bp_blogs_activity_post_type_action_callback( $action_args );
     468
     469                        // if no action "identifier" ( == type field of activity table ) was provided by the post type
     470                        if ( empty( $activity_post_type_action ) ) {
     471                                $activity_post_type_action = 'new_blog_'. $post->post_type;
     472                        }
    336473
    337474                        // Make sure there's not an existing entry for this post (prevent bumping)
    338475                        if ( bp_is_active( 'activity' ) ) {
    339476                                $existing = bp_activity_get( array(
    340477                                        'filter' => array(
    341                                                 'action'       => 'new_blog_post',
     478                                                'action'       => $activity_post_type_action,
    342479                                                'primary_id'   => $blog_id,
    343480                                                'secondary_id' => $post_id,
    344481                                        )
    345482                                ) );
    346483
    347                                 if ( !empty( $existing['activities'] ) ) {
     484                                if ( ! empty( $existing['activities'] ) ) {
    348485                                        return;
    349486                                }
    350487                        }
    351488
    352489                        $activity_content = $post->post_content;
     490                        $post_permalink   = $action_args['post_permalink'];
    353491
    354492                        bp_blogs_record_activity( array(
    355493                                'user_id'           => (int) $post->post_author,
    356                                 'action'            => apply_filters( 'bp_blogs_activity_new_post_action',       $activity_action,  $post, $post_permalink ),
    357                                 'content'           => apply_filters( 'bp_blogs_activity_new_post_content',      $activity_content, $post, $post_permalink ),
    358                                 'primary_link'      => apply_filters( 'bp_blogs_activity_new_post_primary_link', $post_permalink,   $post_id               ),
    359                                 'type'              => 'new_blog_post',
     494                                'action'            => apply_filters( "bp_blogs_activity_new_{$post->post_type}_action",       $activity_action,  $post, $post_permalink ),
     495                                'content'           => apply_filters( "bp_blogs_activity_new_{$post->post_type}_content",      $activity_content, $post, $post_permalink ),
     496                                'primary_link'      => apply_filters( "bp_blogs_activity_new_{$post->post_type}_primary_link", $post_permalink,   $post_id               ),
     497                                'type'              => $activity_post_type_action,
    360498                                'item_id'           => $blog_id,
    361499                                'secondary_item_id' => $post_id,
    362500                                'recorded_time'     => $post->post_date_gmt,
    function bp_blogs_record_post( $post_id, $post, $user_id = 0 ) { 
    373511}
    374512
    375513/**
     514 * Callback function to build the action for the comment on the post type
     515 *
     516 * @param  array  $args the available arguments
     517 * @uses   bp_core_get_userlink() to build the post author profile link
     518 * @uses   get_blog_option() WordPress function to fetch blog meta.
     519 * @return string the activity action
     520 */
     521function bp_blogs_activity_post_type_comment_action_callback( $args = array() ) {
     522       
     523        $r = bp_parse_args( $args, array(
     524                'user_id'                 => bp_loggedin_user_id(),
     525                'post_title'              => '',
     526                'singular_post_type_name' => '',
     527                'blog_id'                 => 0,
     528                'post_permalink'          => '',
     529        ), 'blogs_activity_post_type_comment_action_callback' );
     530
     531        extract( $r, EXTR_SKIP );
     532
     533        if ( ! empty( $blog_id ) )
     534                $activity_action = sprintf( __( '%1$s commented on the %2$s, %3$s, on the site %4$s', 'buddypress' ), bp_core_get_userlink( $user_id ), $singular_post_type_name, '<a href="' . $post_permalink . '">' . apply_filters( 'the_title', $post_title ) . '</a>', '<a href="' . get_blog_option( $blog_id, 'home' ) . '">' . get_blog_option( $blog_id, 'blogname' ) . '</a>' );
     535        else
     536                $activity_action = sprintf( __( '%1$s commented on the %2$s, %3$s', 'buddypress' ), bp_core_get_userlink( $user_id ), $singular_post_type_name, '<a href="' . $post_permalink . '">' . apply_filters( 'the_title', $post_title ) . '</a>' );
     537
     538        return $activity_action;
     539}
     540
     541/**
    376542 * Record a new blog comment in the BuddyPress activity stream.
    377543 *
    378544 * Only posts the item if blog is public and post is not password-protected.
    function bp_blogs_record_comment( $comment_id, $is_approved = true ) { 
    424590        if ( !empty( $recorded_comment->post->post_password ) )
    425591                return false;
    426592
    427         // Don't record activity if the comment's associated post isn't a WordPress Post
    428         if ( !in_array( $recorded_comment->post->post_type, apply_filters( 'bp_blogs_record_comment_post_types', array( 'post' ) ) ) )
     593        // Don't record this if the post type has not been set by administrator to be tracked
     594        if ( ! bp_blogs_is_blog_post_type_trackable( $recorded_comment->post->post_type, $blog_id ) )
    429595                return false;
    430596
    431597        $is_blog_public = apply_filters( 'bp_is_blog_public', (int)get_blog_option( $blog_id, 'blog_public' ) );
    function bp_blogs_record_comment( $comment_id, $is_approved = true ) { 
    433599        // If blog is public allow activity to be posted
    434600        if ( $is_blog_public ) {
    435601
    436                 // Get activity related links
    437                 $post_permalink = get_permalink( $recorded_comment->comment_post_ID );
     602                // Record this in activity streams
     603                $post_type_object = get_post_type_object( $recorded_comment->post->post_type );
     604
     605                // Initializing the action arguments
     606                $action_args = array(
     607                        'user_id'                  => $user_id,
     608                        'post_title'               => $recorded_comment->post->post_title,
     609                        'singular_post_type_name'  => lcfirst( esc_html( $post_type_object->labels->singular_name ) ),
     610                        'blog_id'                  => is_multisite() ? $blog_id : 0,
     611                );
     612               
     613                if( ! empty( $post_type_object->bp_tracking ) ) {
     614                        /**
     615                         * Extracting bp_tracking post type argument will give us the following vars (if set):
     616                         * - activity_post_type_permalink_callback       // the post type provided function to build the permalink
     617                         * - activity_post_type_comment_action           // the post type comment action
     618                         * - activity_post_type_comment_action_label     // the post type comment action label (used in template filter box)
     619                         * - activity_post_type_comment_action_callback  // the post type provided function to build the comment activity action
     620                         *
     621                         * Plugins developers can set these, by adding a bp_tracking argument when registering their post type
     622                         * see how to set a post type argument: http://codex.wordpress.org/Function_Reference/register_post_type#Arguments
     623                         */
     624                        extract( $post_type_object->bp_tracking, EXTR_SKIP );
     625
     626                        // Builds the permalink to the post_type comment
     627                        if ( ! empty( $activity_post_type_permalink_callback ) && is_callable( $activity_post_type_permalink_callback ) )
     628                                $action_args['post_permalink'] = call_user_func_array( $activity_post_type_permalink_callback, array( $recorded_comment->comment_post_ID, $blog_id, $recorded_comment->post ) );
     629
     630                        if( ! empty( $activity_post_type_comment_action_callback ) && is_callable( $activity_post_type_comment_action_callback ) )
     631                                $activity_action               = call_user_func_array( $activity_post_type_comment_action_callback, array( $action_args ) );
     632
     633                }
     634
     635                if ( empty( $action_args['post_permalink'] ) )
     636                        $action_args['post_permalink'] = get_permalink( $recorded_comment->comment_post_ID );
     637
     638                if ( empty( $activity_action ) )
     639                        $activity_action = bp_blogs_activity_post_type_comment_action_callback( $action_args );
     640
     641               
     642                // Get the activity type
     643                $comment_prefix = ( 'post' == $recorded_comment->post->post_type ) ? '' : $recorded_comment->post->post_type . '_';
     644
     645                // if no action "identifier" ( == type field of activity table ) was provided by the post type
     646                if ( empty( $activity_post_type_comment_action ) ) {
     647                        $activity_post_type_comment_action = "new_blog_{$comment_prefix}comment";
     648                }
     649
     650                // Get comment link
    438651                $comment_link   = get_comment_link( $recorded_comment->comment_ID );
    439652
    440                 // Prepare to record in activity streams
    441                 if ( is_multisite() )
    442                         $activity_action = sprintf( __( '%1$s commented on the post, %2$s, on the site %3$s', 'buddypress' ), bp_core_get_userlink( $user_id ), '<a href="' . $post_permalink . '">' . apply_filters( 'the_title', $recorded_comment->post->post_title ) . '</a>', '<a href="' . get_blog_option( $blog_id, 'home' ) . '">' . get_blog_option( $blog_id, 'blogname' ) . '</a>' );
    443                 else
    444                         $activity_action = sprintf( __( '%1$s commented on the post, %2$s', 'buddypress' ), bp_core_get_userlink( $user_id ), '<a href="' . $post_permalink . '">' . apply_filters( 'the_title', $recorded_comment->post->post_title ) . '</a>' );
     653                // Get the comment content
     654                $activity_content = $recorded_comment->comment_content;
    445655
    446                 $activity_content       = $recorded_comment->comment_content;
     656                // to have custom filters by type of post type commented.
     657                $comment_post_type = ( 'post' == $recorded_comment->post->post_type ) ? 'comment' : $recorded_comment->post->post_type . '_comment';
    447658
    448659                // Record in activity streams
    449660                bp_blogs_record_activity( array(
    450661                        'user_id'           => $user_id,
    451                         'action'            => apply_filters_ref_array( 'bp_blogs_activity_new_comment_action',       array( $activity_action,  &$recorded_comment, $comment_link ) ),
    452                         'content'           => apply_filters_ref_array( 'bp_blogs_activity_new_comment_content',      array( $activity_content, &$recorded_comment, $comment_link ) ),
    453                         'primary_link'      => apply_filters_ref_array( 'bp_blogs_activity_new_comment_primary_link', array( $comment_link,     &$recorded_comment                ) ),
    454                         'type'              => 'new_blog_comment',
     662                        'action'            => apply_filters_ref_array( "bp_blogs_activity_new_{$comment_post_type}_action",       array( $activity_action,  &$recorded_comment, $comment_link ) ),
     663                        'content'           => apply_filters_ref_array( "bp_blogs_activity_new_{$comment_post_type}_content",      array( $activity_content, &$recorded_comment, $comment_link ) ),
     664                        'primary_link'      => apply_filters_ref_array( "bp_blogs_activity_new_{$comment_post_type}_primary_link", array( $comment_link,     &$recorded_comment                ) ),
     665                        'type'              => $activity_post_type_comment_action,
    455666                        'item_id'           => $blog_id,
    456667                        'secondary_item_id' => $comment_id,
    457668                        'recorded_time'     => $recorded_comment->comment_date_gmt
  • bp-blogs/bp-blogs-loader.php

    diff --git bp-blogs/bp-blogs-loader.php bp-blogs/bp-blogs-loader.php
    index 39e0450..62ce92b 100644
    class BP_Blogs_Component extends BP_Component { 
    9696                        'buddybar'
    9797                );
    9898
    99                 if ( is_multisite() )
     99                if ( is_multisite() ) {
    100100                        $includes[] = 'widgets';
    101101
     102                        if ( bp_get_root_blog_id() != get_current_blog_id() && is_admin() && bp_is_active( 'activity' ) )
     103                                $includes[] = 'admin';
     104                }
     105                       
     106
    102107                // Include the files
    103108                parent::includes( $includes );
    104109        }
  • bp-blogs/bp-blogs-template.php

    diff --git bp-blogs/bp-blogs-template.php bp-blogs/bp-blogs-template.php
    index b69c1c6..388d31e 100644
    function bp_blogs_get_profile_stats( $args = '' ) { 
    12881288        // Filter and return
    12891289        return apply_filters( 'bp_blogs_get_profile_stats', $r['output'], $r );
    12901290}
     1291
     1292/**
     1293 * Adds the available post types actions to activity filters
     1294 *
     1295 * As in bp-legacy or bp-default templates the regular post type
     1296 * is already added we'll need to remove it from these options.
     1297 * Leaving it this way for backcompat theme purpose. But all
     1298 * post types should be handled there in the future..
     1299 *
     1300 * @return string html output
     1301 */
     1302function bp_blogs_post_types_activity_options() {
     1303
     1304        $blogs_legacy_actions     = array( 'new_blog_post', 'new_blog_comment' );
     1305        $blogs_post_types_actions = buddypress()->activity->actions->blogs;
     1306
     1307        foreach ( $blogs_post_types_actions as $action ) {
     1308                if ( in_array( $action['key'], $blogs_legacy_actions ) )
     1309                        continue;
     1310                ?>
     1311                <option value="<?php echo esc_attr( $action['key'] ) ;?>"><?php echo esc_html( $action['value'] ) ;?></option>
     1312                <?php
     1313        }
     1314}
     1315add_action( 'bp_activity_filter_options',        'bp_blogs_post_types_activity_options' );
     1316add_action( 'bp_member_activity_filter_options', 'bp_blogs_post_types_activity_options' );
  • bp-core/admin/bp-core-settings.php

    diff --git bp-core/admin/bp-core-settings.php bp-core/admin/bp-core-settings.php
    index e112df7..9e25db3 100644
    function bp_admin_setting_callback_group_creation() { 
    211211<?php
    212212}
    213213
     214/** Blogs Section *************************************************************/
     215
     216/**
     217 * Displays a message about the trackable post types in case BuddyPress is network activated
     218 *
     219 * @since BuddyPress (?)
     220 * @uses  bp_core_do_network_admin() to check if BuddyPress is network activated
     221 */
     222function bp_admin_setting_callback_blogs_section() {
     223        if ( bp_core_do_network_admin() ) {
     224        ?>
     225                <p class="description"><?php _e( 'Only the networked enabled & the primary blog post types can be tracked in Activity stream.', 'buddypress' );?></p>
     226        <?php
     227        }
     228}
     229
     230/**
     231 * Allow the Admin to define the post types to track in activity stream
     232 *
     233 * @since BuddyPress (?)
     234 *
     235 * @uses  get_post_types() to list the show_in_nav_menus enabled post types
     236 * @uses  checked() To display the checked attribute
     237 * @uses  post_type_supports() to check for bp_tracking support
     238 */
     239function bp_admin_setting_callback_post_types_tracked( $setting = '') {
     240        /**
     241         * Using show_in_nav_menus argument avoids the inclusion of the attachment post type
     242         * if show_in_nav_menus is not defined it defaults to the value of public arguments
     243         */
     244        $post_types = get_post_types( array( 'show_in_nav_menus' => true ), 'objects' );
     245
     246        // Building an array to compare with the array saved in bp-enabled-post-types option
     247        $compare    = array_fill_keys( array_keys( $post_types ), 0 );
     248
     249        if ( empty( $setting ) )
     250                $setting = bp_trackable_post_types();
     251
     252        // Merge the two arrays making sure the setting saved for the post type will be the final value
     253        $db_post_types = array_merge( $compare, $setting );
     254
     255        if ( empty( $db_post_types ) )
     256                return;
     257
     258        foreach ( $post_types as $post_type => $arguments ) {
     259                $readonly = ( 'post' == $post_type ) ? 'disabled' : '';
     260                ?>
     261
     262                <input id="bp-enabled-post-types-<?php echo $post_type;?>" name="bp-enabled-post-types[<?php echo $post_type;?>]" type="checkbox" value="1" <?php checked( $db_post_types[ $post_type ] ); ?> <?php echo $readonly;?>/>
     263                <label for="bp-enabled-post-types-<?php echo $post_type;?>"><?php echo $arguments->labels->name ?></label>
     264
     265                <?php
     266        }
     267
     268}
     269
     270/**
     271 * Sanitization for bp-enabled-post-types
     272 *
     273 * @since BuddyPress (?)
     274 */
     275function bp_admin_sanitize_callback_post_types_tracked( $value = array() ) {
     276        // Post is legacy : always tracked.
     277        $tracked = array( 'post' => 1 );
     278
     279        if( is_array( $value ) )
     280                $tracked = array_merge( $tracked, $value );
     281
     282        return array_map( 'absint', $tracked );
     283}
     284
    214285/** Forums Section ************************************************************/
    215286
    216287/**
  • bp-core/bp-core-actions.php

    diff --git bp-core/bp-core-actions.php bp-core/bp-core-actions.php
    index df61f5a..de1c65e 100644
    if ( !defined( 'ABSPATH' ) ) exit; 
    3333  */
    3434add_action( 'plugins_loaded',          'bp_loaded',                 10    );
    3535add_action( 'init',                    'bp_init',                   10    );
     36add_action( 'init',                    'bp_catch_post_types',       100   ); // late to catch post types
    3637add_action( 'parse_query',             'bp_parse_query',            2     ); // Early for overrides
    3738add_action( 'wp',                      'bp_ready',                  10    );
    3839add_action( 'set_current_user',        'bp_setup_current_user',     10    );
  • bp-core/bp-core-admin.php

    diff --git bp-core/bp-core-admin.php bp-core/bp-core-admin.php
    index 4020355..0e9ee2e 100644
    class BP_Admin { 
    348348                    add_settings_field( 'bp-disable-avatar-uploads', __( 'Avatar Uploads',   'buddypress' ), 'bp_admin_setting_callback_avatar_uploads',   'buddypress', $avatar_setting );
    349349                    register_setting  ( 'buddypress',         'bp-disable-avatar-uploads',   'intval'                                                                                    );
    350350                }
     351
     352                /** Blogs Section **************************************************/
     353
     354                if ( bp_is_active( 'blogs' ) ) {
     355
     356                        // Add the main section
     357                        add_settings_section( 'bp_blogs', __( 'Site Tracking Settings', 'buddypress' ), 'bp_admin_setting_callback_blogs_section', 'buddypress' );
     358
     359                        // Post types tracking settings
     360                        add_settings_field( 'bp-enabled-post-types', __( 'List of post types to track', 'buddypress' ), 'bp_admin_setting_callback_post_types_tracked', 'buddypress', 'bp_blogs' );
     361                        register_setting  ( 'buddypress',           'bp-enabled-post-types',                            'bp_admin_sanitize_callback_post_types_tracked'                          );
     362                }
    351363        }
    352364
    353365        /**
  • bp-core/bp-core-dependency.php

    diff --git bp-core/bp-core-dependency.php bp-core/bp-core-dependency.php
    index eaf839c..32262c3 100644
    function bp_get_request() { 
    388388        // Use this static action if you don't mind checking the 'action' yourself.
    389389        do_action( 'bp_get_request',   $_GET['action'] );
    390390}
     391
     392/**
     393 * The main action used for catching registered post types
     394 *
     395 * @since BuddyPress (?)
     396 * @uses do_action()
     397 */
     398function bp_catch_post_types() {
     399        do_action( 'bp_catch_post_types' );
     400}
  • bp-core/bp-core-options.php

    diff --git bp-core/bp-core-options.php bp-core/bp-core-options.php
    index 07edc8c..4e9ce57 100644
    function bp_disable_blogforum_comments( $default = false ) { 
    506506}
    507507
    508508/**
     509 * What are the registered post types trackable in activity streams?
     510 *
     511 * @since BuddyPress (?)
     512 *
     513 * @uses bp_get_option() To get the blog/forum comments option.
     514 *
     515 * @param array $default Optional. Fallback value if not found in the database.
     516 *        Default: array().
     517 * @return bool True if activity comments are disabled for blog and forum
     518 *         items, otherwise false.
     519 */
     520function bp_trackable_post_types( $default = array( 'post' => 1 ) ) {
     521        return (array) apply_filters( 'bp_trackable_post_types', (array) bp_get_option( 'bp-enabled-post-types', $default ) );
     522}
     523
     524/**
    509525 * Is group creation turned off?
    510526 *
    511527 * @since BuddyPress (1.6.0)