Skip to:
Content

BuddyPress.org

source: trunk/src/bp-core/bp-core-template.php

Last change on this file was 13170, checked in by dcavins, 5 months ago

Membership Requests: Change labels on register page.

We are using the standard "register" form to collect
membership requests, so we need to change the labels
in many cases to avoid confusion. Also ensure that users
can access the registration page when membership
requests are enabled.

See #8582.

File size: 106.9 KB
Line 
1<?php
2/**
3 * Core component template tag functions.
4 *
5 * @package BuddyPress
6 * @subpackage TemplateFunctions
7 * @since 1.5.0
8 */
9
10// Exit if accessed directly.
11defined( 'ABSPATH' ) || exit;
12
13/**
14 * Output the "options nav", the secondary-level single item navigation menu.
15 *
16 * Uses the component's nav global to render out the sub navigation for the
17 * current component. Each component adds to its sub navigation array within
18 * its own setup_nav() function.
19 *
20 * This sub navigation array is the secondary level navigation, so for profile
21 * it contains:
22 *      [Public, Edit Profile, Change Avatar]
23 *
24 * The function will also analyze the current action for the current component
25 * to determine whether or not to highlight a particular sub nav item.
26 *
27 * @since 1.0.0
28 *
29 *       viewed user.
30 *
31 * @param string $parent_slug Options nav slug.
32 * @return string
33 */
34function bp_get_options_nav( $parent_slug = '' ) {
35        $bp = buddypress();
36
37        // If we are looking at a member profile, then the we can use the current
38        // component as an index. Otherwise we need to use the component's root_slug.
39        $component_index = !empty( $bp->displayed_user ) ? bp_current_component() : bp_get_root_slug( bp_current_component() );
40        $selected_item   = bp_current_action();
41
42        // Default to the Members nav.
43        if ( ! bp_is_single_item() ) {
44                // Set the parent slug, if not provided.
45                if ( empty( $parent_slug ) ) {
46                        $parent_slug = $component_index;
47                }
48
49                $secondary_nav_items = $bp->members->nav->get_secondary( array( 'parent_slug' => $parent_slug ) );
50
51                if ( ! $secondary_nav_items ) {
52                        return false;
53                }
54
55        // For a single item, try to use the component's nav.
56        } else {
57                $current_item = bp_current_item();
58                $single_item_component = bp_current_component();
59
60                // Adjust the selected nav item for the current single item if needed.
61                if ( ! empty( $parent_slug ) ) {
62                        $current_item  = $parent_slug;
63                        $selected_item = bp_action_variable( 0 );
64                }
65
66                // If the nav is not defined by the parent component, look in the Members nav.
67                if ( ! isset( $bp->{$single_item_component}->nav ) ) {
68                        $secondary_nav_items = $bp->members->nav->get_secondary( array( 'parent_slug' => $current_item ) );
69                } else {
70                        $secondary_nav_items = $bp->{$single_item_component}->nav->get_secondary( array( 'parent_slug' => $current_item ) );
71                }
72
73                if ( ! $secondary_nav_items ) {
74                        return false;
75                }
76        }
77
78        // Loop through each navigation item.
79        foreach ( $secondary_nav_items as $subnav_item ) {
80                if ( empty( $subnav_item->user_has_access ) ) {
81                        continue;
82                }
83
84                // If the current action or an action variable matches the nav item id, then add a highlight CSS class.
85                if ( $subnav_item->slug === $selected_item ) {
86                        $selected = ' class="current selected"';
87                } else {
88                        $selected = '';
89                }
90
91                // List type depends on our current component.
92                $list_type = bp_is_group() ? 'groups' : 'personal';
93
94                /**
95                 * Filters the "options nav", the secondary-level single item navigation menu.
96                 *
97                 * This is a dynamic filter that is dependent on the provided css_id value.
98                 *
99                 * @since 1.1.0
100                 *
101                 * @param string $value         HTML list item for the submenu item.
102                 * @param array  $subnav_item   Submenu array item being displayed.
103                 * @param string $selected_item Current action.
104                 */
105                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 );
106        }
107}
108
109/**
110 * Get the 'bp_options_title' property from the BP global.
111 *
112 * Not currently used in BuddyPress.
113 *
114 * @todo Deprecate.
115 */
116function bp_get_options_title() {
117        $bp = buddypress();
118
119        if ( empty( $bp->bp_options_title ) ) {
120                $bp->bp_options_title = __( 'Options', 'buddypress' );
121        }
122
123        echo apply_filters( 'bp_get_options_title', esc_attr( $bp->bp_options_title ) );
124}
125
126/**
127 * Get the directory title for a component.
128 *
129 * Used for the <title> element and the page header on the component directory
130 * page.
131 *
132 * @since 2.0.0
133 *
134 * @param string $component Component to get directory title for.
135 * @return string
136 */
137function bp_get_directory_title( $component = '' ) {
138        $title = '';
139
140        // Use the string provided by the component.
141        if ( isset( buddypress()->{$component}->directory_title ) && buddypress()->{$component}->directory_title ) {
142                $title = buddypress()->{$component}->directory_title;
143
144        // If none is found, concatenate.
145        } elseif ( isset( buddypress()->{$component}->name ) ) {
146                /* translators: %s: Name of the BuddyPress component */
147                $title = sprintf( __( '%s Directory', 'buddypress' ), buddypress()->{$component}->name );
148        }
149
150        /**
151         * Filters the directory title for a component.
152         *
153         * @since 2.0.0
154         *
155         * @param string $title     Text to be used in <title> tag.
156         * @param string $component Current component being displayed.
157         */
158        return apply_filters( 'bp_get_directory_title', $title, $component );
159}
160
161/** Avatars *******************************************************************/
162
163/**
164 * Check to see if there is an options avatar.
165 *
166 * An options avatar is an avatar for something like a group, or a friend.
167 * Basically an avatar that appears in the sub nav options bar.
168 *
169 * Not currently used in BuddyPress.
170 *
171 * @return bool $value Returns true if an options avatar has been set, otherwise false.
172 */
173function bp_has_options_avatar() {
174        return (bool) buddypress()->bp_options_avatar;
175}
176
177/**
178 * Output the options avatar.
179 *
180 * Not currently used in BuddyPress.
181 *
182 * @todo Deprecate.
183 */
184function bp_get_options_avatar() {
185        echo apply_filters( 'bp_get_options_avatar', buddypress()->bp_options_avatar );
186}
187
188/**
189 * Output a comment author's avatar.
190 *
191 * Not currently used in BuddyPress.
192 */
193function bp_comment_author_avatar() {
194        global $comment;
195
196        echo apply_filters( 'bp_comment_author_avatar', bp_core_fetch_avatar( array(
197                'item_id' => $comment->user_id,
198                'type'    => 'thumb',
199                'alt'     => sprintf(
200                        /* translators: %s: member name */
201                        __( 'Profile photo of %s', 'buddypress' ),
202                        bp_core_get_user_displayname( $comment->user_id )
203                ),
204        ) ) );
205}
206
207/**
208 * Output a post author's avatar.
209 *
210 * Not currently used in BuddyPress.
211 */
212function bp_post_author_avatar() {
213        global $post;
214
215        echo apply_filters( 'bp_post_author_avatar', bp_core_fetch_avatar( array(
216                'item_id' => $post->post_author,
217                'type'    => 'thumb',
218                'alt'     => sprintf(
219                        /* translators: %s: member name */
220                        __( 'Profile photo of %s', 'buddypress' ),
221                        bp_core_get_user_displayname( $post->post_author )
222                ),
223        ) ) );
224}
225
226/**
227 * Output the current avatar upload step.
228 *
229 * @since 1.1.0
230 */
231function bp_avatar_admin_step() {
232        echo bp_get_avatar_admin_step();
233}
234        /**
235         * Return the current avatar upload step.
236         *
237         * @since 1.1.0
238         *
239         * @return string The current avatar upload step. Returns 'upload-image'
240         *         if none is found.
241         */
242        function bp_get_avatar_admin_step() {
243                $bp   = buddypress();
244                $step = isset( $bp->avatar_admin->step )
245                        ? $step = $bp->avatar_admin->step
246                        : 'upload-image';
247
248                /**
249                 * Filters the current avatar upload step.
250                 *
251                 * @since 1.1.0
252                 *
253                 * @param string $step The current avatar upload step.
254                 */
255                return apply_filters( 'bp_get_avatar_admin_step', $step );
256        }
257
258/**
259 * Output the URL of the avatar to crop.
260 *
261 * @since 1.1.0
262 */
263function bp_avatar_to_crop() {
264        echo bp_get_avatar_to_crop();
265}
266        /**
267         * Return the URL of the avatar to crop.
268         *
269         * @since 1.1.0
270         *
271         * @return string URL of the avatar awaiting cropping.
272         */
273        function bp_get_avatar_to_crop() {
274                $bp  = buddypress();
275                $url = isset( $bp->avatar_admin->image->url )
276                        ? $bp->avatar_admin->image->url
277                        : '';
278
279                /**
280                 * Filters the URL of the avatar to crop.
281                 *
282                 * @since 1.1.0
283                 *
284                 * @param string $url URL for the avatar.
285                 */
286                return apply_filters( 'bp_get_avatar_to_crop', $url );
287        }
288
289/**
290 * Output the relative file path to the avatar to crop.
291 *
292 * @since 1.1.0
293 */
294function bp_avatar_to_crop_src() {
295        echo bp_get_avatar_to_crop_src();
296}
297        /**
298         * Return the relative file path to the avatar to crop.
299         *
300         * @since 1.1.0
301         *
302         * @return string Relative file path to the avatar.
303         */
304        function bp_get_avatar_to_crop_src() {
305                $bp  = buddypress();
306                $src = isset( $bp->avatar_admin->image->dir )
307                        ? str_replace( WP_CONTENT_DIR, '', $bp->avatar_admin->image->dir )
308                        : '';
309
310                /**
311                 * Filters the relative file path to the avatar to crop.
312                 *
313                 * @since 1.1.0
314                 *
315                 * @param string $src Relative file path for the avatar.
316                 */
317                return apply_filters( 'bp_get_avatar_to_crop_src', $src );
318        }
319
320/**
321 * Output the avatar cropper <img> markup.
322 *
323 * No longer used in BuddyPress.
324 *
325 * @todo Deprecate.
326 */
327function bp_avatar_cropper() {
328?>
329        <img id="avatar-to-crop" class="avatar" src="<?php echo esc_url( buddypress()->avatar_admin->image ); ?>" />
330<?php
331}
332
333/**
334 * Output the name of the BP site. Used in RSS headers.
335 *
336 * @since 1.0.0
337 */
338function bp_site_name() {
339        echo bp_get_site_name();
340}
341        /**
342         * Returns the name of the BP site. Used in RSS headers.
343         *
344         * @since 1.6.0
345         *
346         * @return string
347         */
348        function bp_get_site_name() {
349
350                /**
351                 * Filters the name of the BP site. Used in RSS headers.
352                 *
353                 * @since 1.0.0
354                 *
355                 * @param string $value Current BP site name.
356                 */
357                return apply_filters( 'bp_site_name', get_bloginfo( 'name', 'display' ) );
358        }
359
360/**
361 * Format a date based on a UNIX timestamp.
362 *
363 * This function can be used to turn a UNIX timestamp into a properly formatted
364 * (and possibly localized) string, useful for outputting the date & time an
365 * action took place.
366 *
367 * Not to be confused with `bp_core_time_since()`, this function is best used
368 * for displaying a more exact date and time vs. a human-readable time.
369 *
370 * Note: This function may be improved or removed at a later date, as it is
371 * hardly used and adds an additional layer of complexity to calculating dates
372 * and times together with timezone offsets and i18n.
373 *
374 * @since 1.1.0
375 *
376 * @param int|string $time         The UNIX timestamp to be formatted.
377 * @param bool       $exclude_time Optional. True to return only the month + day, false
378 *                                 to return month, day, and time. Default: false.
379 * @param bool       $gmt          Optional. True to display in local time, false to
380 *                                  leave in GMT. Default: true.
381 * @return mixed A string representation of $time, in the format
382 *               "March 18, 2014 at 2:00 pm" (or whatever your
383 *               'date_format' and 'time_format' settings are
384 *               on your root blog). False on failure.
385 */
386function bp_format_time( $time = '', $exclude_time = false, $gmt = true ) {
387
388        // Bail if time is empty or not numeric
389        // @todo We should output something smarter here.
390        if ( empty( $time ) || ! is_numeric( $time ) ) {
391                return false;
392        }
393
394        // Get GMT offset from root blog.
395        if ( true === $gmt ) {
396
397                // Use Timezone string if set.
398                $timezone_string = bp_get_option( 'timezone_string' );
399                if ( ! empty( $timezone_string ) ) {
400                        $timezone_object = timezone_open( $timezone_string );
401                        $datetime_object = date_create( "@{$time}" );
402                        $timezone_offset = timezone_offset_get( $timezone_object, $datetime_object ) / HOUR_IN_SECONDS;
403
404                // Fall back on less reliable gmt_offset.
405                } else {
406                        $timezone_offset = bp_get_option( 'gmt_offset' );
407                }
408
409                // Calculate time based on the offset.
410                $calculated_time = $time + ( $timezone_offset * HOUR_IN_SECONDS );
411
412        // No localizing, so just use the time that was submitted.
413        } else {
414                $calculated_time = $time;
415        }
416
417        // Formatted date: "March 18, 2014".
418        $formatted_date = date_i18n( bp_get_option( 'date_format' ), $calculated_time, $gmt );
419
420        // Should we show the time also?
421        if ( true !== $exclude_time ) {
422
423                // Formatted time: "2:00 pm".
424                $formatted_time = date_i18n( bp_get_option( 'time_format' ), $calculated_time, $gmt );
425
426                // Return string formatted with date and time.
427                $formatted_date = sprintf( esc_html__( '%1$s at %2$s', 'buddypress' ), $formatted_date, $formatted_time );
428        }
429
430        /**
431         * Filters the date based on a UNIX timestamp.
432         *
433         * @since 1.0.0
434         *
435         * @param string $formatted_date Formatted date from the timestamp.
436         */
437        return apply_filters( 'bp_format_time', $formatted_date );
438}
439
440/**
441 * Select between two dynamic strings, according to context.
442 *
443 * This function can be used in cases where a phrase used in a template will
444 * differ for a user looking at his own profile and a user looking at another
445 * user's profile (eg, "My Friends" and "Joe's Friends"). Pass both versions
446 * of the phrase, and bp_word_or_name() will detect which is appropriate, and
447 * do the necessary argument swapping for dynamic phrases.
448 *
449 * @since 1.0.0
450 *
451 * @param string $youtext    The "you" version of the phrase (eg "Your Friends").
452 * @param string $nametext   The other-user version of the phrase. Should be in
453 *                           a format appropriate for sprintf() - use %s in place of the displayed
454 *                           user's name (eg "%'s Friends").
455 * @param bool   $capitalize Optional. Force into title case. Default: true.
456 * @param bool   $echo       Optional. True to echo the results, false to return them.
457 *                           Default: true.
458 * @return string|null $nametext If ! $echo, returns the appropriate string.
459 */
460function bp_word_or_name( $youtext, $nametext, $capitalize = true, $echo = true ) {
461
462        if ( ! empty( $capitalize ) ) {
463                $youtext = bp_core_ucfirst( $youtext );
464        }
465
466        if ( bp_displayed_user_id() == bp_loggedin_user_id() ) {
467                if ( true == $echo ) {
468
469                        /**
470                         * Filters the text used based on context of own profile or someone else's profile.
471                         *
472                         * @since 1.0.0
473                         *
474                         * @param string $youtext Context-determined string to display.
475                         */
476                        echo apply_filters( 'bp_word_or_name', $youtext );
477                } else {
478
479                        /** This filter is documented in bp-core/bp-core-template.php */
480                        return apply_filters( 'bp_word_or_name', $youtext );
481                }
482        } else {
483                $fullname = bp_get_displayed_user_fullname();
484                $fullname = (array) explode( ' ', $fullname );
485                $nametext = sprintf( $nametext, $fullname[0] );
486                if ( true == $echo ) {
487
488                        /** This filter is documented in bp-core/bp-core-template.php */
489                        echo apply_filters( 'bp_word_or_name', $nametext );
490                } else {
491
492                        /** This filter is documented in bp-core/bp-core-template.php */
493                        return apply_filters( 'bp_word_or_name', $nametext );
494                }
495        }
496}
497
498/**
499 * Do the 'bp_styles' action, and call wp_print_styles().
500 *
501 * No longer used in BuddyPress.
502 *
503 * @todo Deprecate.
504 */
505function bp_styles() {
506        do_action( 'bp_styles' );
507        wp_print_styles();
508}
509
510/** Search Form ***************************************************************/
511
512/**
513 * Return the "action" attribute for search forms.
514 *
515 * @since 1.0.0
516 *
517 * @return string URL action attribute for search forms, eg example.com/search/.
518 */
519function bp_search_form_action() {
520
521        /**
522         * Filters the "action" attribute for search forms.
523         *
524         * @since 1.0.0
525         *
526         * @param string $value Search form action url.
527         */
528        return apply_filters( 'bp_search_form_action', trailingslashit( bp_get_root_domain() . '/' . bp_get_search_slug() ) );
529}
530
531/**
532 * Generate the basic search form as used in BP-Default's header.
533 *
534 * @since 1.0.0
535 *
536 * @return string HTML <select> element.
537 */
538function bp_search_form_type_select() {
539
540        $options = array();
541
542        if ( bp_is_active( 'xprofile' ) ) {
543                $options['members'] = _x( 'Members', 'search form', 'buddypress' );
544        }
545
546        if ( bp_is_active( 'groups' ) ) {
547                $options['groups']  = _x( 'Groups', 'search form', 'buddypress' );
548        }
549
550        if ( bp_is_active( 'blogs' ) && is_multisite() ) {
551                $options['blogs']   = _x( 'Blogs', 'search form', 'buddypress' );
552        }
553
554        $options['posts'] = _x( 'Posts', 'search form', 'buddypress' );
555
556        // Eventually this won't be needed and a page will be built to integrate all search results.
557        $selection_box  = '<label for="search-which" class="accessibly-hidden">' . _x( 'Search these:', 'search form', 'buddypress' ) . '</label>';
558        $selection_box .= '<select name="search-which" id="search-which" style="width: auto">';
559
560        /**
561         * Filters all of the component options available for search scope.
562         *
563         * @since 1.5.0
564         *
565         * @param array $options Array of options to add to select field.
566         */
567        $options = apply_filters( 'bp_search_form_type_select_options', $options );
568        foreach( (array) $options as $option_value => $option_title ) {
569                $selection_box .= sprintf( '<option value="%s">%s</option>', $option_value, $option_title );
570        }
571
572        $selection_box .= '</select>';
573
574        /**
575         * Filters the complete <select> input used for search scope.
576         *
577         * @since 1.0.0
578         *
579         * @param string $selection_box <select> input for selecting search scope.
580         */
581        return apply_filters( 'bp_search_form_type_select', $selection_box );
582}
583
584/**
585 * Output the 'name' attribute for search form input element.
586 *
587 * @since 2.7.0
588 *
589 * @param string $component See bp_get_search_input_name().
590 */
591function bp_search_input_name( $component = '' ) {
592        echo esc_attr( bp_get_search_input_name( $component ) );
593}
594
595/**
596 * Get the 'name' attribute for the search form input element.
597 *
598 * @since 2.7.0
599 *
600 * @param string $component Component name. Defaults to current component.
601 * @return string Text for the 'name' attribute.
602 */
603function bp_get_search_input_name( $component = '' ) {
604        if ( ! $component ) {
605                $component = bp_current_component();
606        }
607
608        $bp = buddypress();
609
610        $name = '';
611        if ( isset( $bp->{$component}->id ) ) {
612                $name = $bp->{$component}->id . '_search';
613        }
614
615        return $name;
616}
617
618/**
619 * Output the placeholder text for the search box for a given component.
620 *
621 * @since 2.7.0
622 *
623 * @param string $component See bp_get_search_placeholder().
624 */
625function bp_search_placeholder( $component = '' ) {
626        echo esc_attr( bp_get_search_placeholder( $component ) );
627}
628
629/**
630 * Get the placeholder text for the search box for a given component.
631 *
632 * @since 2.7.0
633 *
634 * @param string $component Component name. Defaults to current component.
635 * @return string Placeholder text for the search field.
636 */
637function bp_get_search_placeholder( $component = '' ) {
638        $query_arg = bp_core_get_component_search_query_arg( $component );
639
640        if ( $query_arg && ! empty( $_REQUEST[ $query_arg ] ) ) {
641                $placeholder = wp_unslash( $_REQUEST[ $query_arg ] );
642        } else {
643                $placeholder = bp_get_search_default_text( $component );
644        }
645
646        return $placeholder;
647}
648
649/**
650 * Output the default text for the search box for a given component.
651 *
652 * @since 1.5.0
653 *
654 * @see bp_get_search_default_text()
655 *
656 * @param string $component See {@link bp_get_search_default_text()}.
657 */
658function bp_search_default_text( $component = '' ) {
659        echo bp_get_search_default_text( $component );
660}
661        /**
662         * Return the default text for the search box for a given component.
663         *
664         * @since 1.5.0
665         *
666         * @param string $component Component name. Default: current component.
667         * @return string Placeholder text for search field.
668         */
669        function bp_get_search_default_text( $component = '' ) {
670
671                $bp = buddypress();
672
673                if ( empty( $component ) ) {
674                        $component = bp_current_component();
675                }
676
677                $default_text = __( 'Search anything...', 'buddypress' );
678
679                // Most of the time, $component will be the actual component ID.
680                if ( !empty( $component ) ) {
681                        if ( !empty( $bp->{$component}->search_string ) ) {
682                                $default_text = $bp->{$component}->search_string;
683                        } else {
684                                // When the request comes through AJAX, we need to get the component
685                                // name out of $bp->pages.
686                                if ( !empty( $bp->pages->{$component}->slug ) ) {
687                                        $key = $bp->pages->{$component}->slug;
688                                        if ( !empty( $bp->{$key}->search_string ) ) {
689                                                $default_text = $bp->{$key}->search_string;
690                                        }
691                                }
692                        }
693                }
694
695                /**
696                 * Filters the default text for the search box for a given component.
697                 *
698                 * @since 1.5.0
699                 *
700                 * @param string $default_text Default text for search box.
701                 * @param string $component    Current component displayed.
702                 */
703                return apply_filters( 'bp_get_search_default_text', $default_text, $component );
704        }
705
706/**
707 * Fire the 'bp_custom_profile_boxes' action.
708 *
709 * No longer used in BuddyPress.
710 *
711 * @todo Deprecate.
712 */
713function bp_custom_profile_boxes() {
714        do_action( 'bp_custom_profile_boxes' );
715}
716
717/**
718 * Fire the 'bp_custom_profile_sidebar_boxes' action.
719 *
720 * No longer used in BuddyPress.
721 *
722 * @todo Deprecate.
723 */
724function bp_custom_profile_sidebar_boxes() {
725        do_action( 'bp_custom_profile_sidebar_boxes' );
726}
727
728/**
729 * Output the attributes for a form field.
730 *
731 * @since 2.2.0
732 *
733 * @param string $name       The field name to output attributes for.
734 * @param array  $attributes Array of existing attributes to add.
735 */
736function bp_form_field_attributes( $name = '', $attributes = array() ) {
737        echo bp_get_form_field_attributes( $name, $attributes );
738}
739        /**
740         * Get the attributes for a form field.
741         *
742         * Primarily to add better support for touchscreen devices, but plugin devs
743         * can use the 'bp_get_form_field_extra_attributes' filter for further
744         * manipulation.
745         *
746         * @since 2.2.0
747         *
748         * @param string $name       The field name to get attributes for.
749         * @param array  $attributes Array of existing attributes to add.
750         * @return string
751         */
752        function bp_get_form_field_attributes( $name = '', $attributes = array() ) {
753                $retval = '';
754
755                if ( empty( $attributes ) ) {
756                        $attributes = array();
757                }
758
759                $name = strtolower( $name );
760
761                switch ( $name ) {
762                        case 'username' :
763                        case 'blogname' :
764                                $attributes['autocomplete']   = 'off';
765                                $attributes['autocapitalize'] = 'none';
766                                break;
767
768                        case 'email' :
769                                if ( wp_is_mobile() ) {
770                                        $attributes['autocapitalize'] = 'none';
771                                }
772                                break;
773
774                        case 'password' :
775                                $attributes['spellcheck']   = 'false';
776                                $attributes['autocomplete'] = 'off';
777
778                                if ( wp_is_mobile() ) {
779                                        $attributes['autocorrect']    = 'false';
780                                        $attributes['autocapitalize'] = 'none';
781                                }
782                                break;
783                }
784
785                /**
786                 * Filter the attributes for a field before rendering output.
787                 *
788                 * @since 2.2.0
789                 *
790                 * @param array  $attributes The field attributes.
791                 * @param string $name       The field name.
792                 */
793                $attributes = (array) apply_filters( 'bp_get_form_field_attributes', $attributes, $name );
794
795                foreach( $attributes as $attr => $value ) {
796                        // Numeric keyed array.
797                        if (is_numeric( $attr ) ) {
798                                $retval .= sprintf( ' %s', esc_attr( $value ) );
799
800                        // Associative keyed array.
801                        } else {
802                                $retval .= sprintf( ' %s="%s"', sanitize_key( $attr ), esc_attr( $value ) );
803                        }
804                }
805
806                return $retval;
807        }
808
809/**
810 * Create and output a button.
811 *
812 * @since 1.2.6
813 *
814 * @see bp_get_button()
815 *
816 * @param array|string $args See {@link BP_Button}.
817 */
818function bp_button( $args = '' ) {
819        echo bp_get_button( $args );
820}
821        /**
822         * Create and return a button.
823         *
824         * @since 1.2.6
825         *
826         * @see BP_Button for a description of arguments and return value.
827         *
828         * @param array|string $args See {@link BP_Button}.
829         * @return string HTML markup for the button.
830         */
831        function bp_get_button( $args = '' ) {
832                $button = new BP_Button( $args );
833
834                /**
835                 * Filters the requested button output.
836                 *
837                 * @since 1.2.6
838                 *
839                 * @param string    $contents  Button context to be used.
840                 * @param array     $args      Array of args for the button.
841                 * @param BP_Button $button    BP_Button object.
842                 */
843                return apply_filters( 'bp_get_button', $button->contents, $args, $button );
844        }
845
846/**
847 * Truncate text.
848 *
849 * Cuts a string to the length of $length and replaces the last characters
850 * with the ending if the text is longer than length.
851 *
852 * This function is borrowed from CakePHP v2.0, under the MIT license. See
853 * http://book.cakephp.org/view/1469/Text#truncate-1625
854 *
855 * @since 1.0.0
856 * @since 2.6.0 Added 'strip_tags' and 'remove_links' as $options args.
857 *
858 * @param string $text   String to truncate.
859 * @param int    $length Optional. Length of returned string, including ellipsis.
860 *                       Default: 225.
861 * @param array  $options {
862 *     An array of HTML attributes and options. Each item is optional.
863 *     @type string $ending            The string used after truncation.
864 *                                     Default: ' [&hellip;]'.
865 *     @type bool   $exact             If true, $text will be trimmed to exactly $length.
866 *                                     If false, $text will not be cut mid-word. Default: false.
867 *     @type bool   $html              If true, don't include HTML tags when calculating
868 *                                     excerpt length. Default: true.
869 *     @type bool   $filter_shortcodes If true, shortcodes will be stripped.
870 *                                     Default: true.
871 *     @type bool   $strip_tags        If true, HTML tags will be stripped. Default: false.
872 *                                     Only applicable if $html is set to false.
873 *     @type bool   $remove_links      If true, URLs will be stripped. Default: false.
874 *                                     Only applicable if $html is set to false.
875 * }
876 * @return string Trimmed string.
877 */
878function bp_create_excerpt( $text, $length = 225, $options = array() ) {
879
880        // Backward compatibility. The third argument used to be a boolean $filter_shortcodes.
881        $filter_shortcodes_default = is_bool( $options ) ? $options : true;
882
883        $r = bp_parse_args(
884                $options,
885                array(
886                        'ending'            => __( ' [&hellip;]', 'buddypress' ),
887                        'exact'             => false,
888                        'html'              => true,
889                        'filter_shortcodes' => $filter_shortcodes_default,
890                        'strip_tags'        => false,
891                        'remove_links'      => false,
892                ),
893                'create_excerpt'
894        );
895
896        // Save the original text, to be passed along to the filter.
897        $original_text = $text;
898
899        /**
900         * Filters the excerpt length to trim text to.
901         *
902         * @since 1.5.0
903         *
904         * @param int $length Length of returned string, including ellipsis.
905         */
906        $length = apply_filters( 'bp_excerpt_length',      $length      );
907
908        /**
909         * Filters the excerpt appended text value.
910         *
911         * @since 1.5.0
912         *
913         * @param string $value Text to append to the end of the excerpt.
914         */
915        $ending = apply_filters( 'bp_excerpt_append_text', $r['ending'] );
916
917        // Remove shortcodes if necessary.
918        if ( ! empty( $r['filter_shortcodes'] ) ) {
919                $text = strip_shortcodes( $text );
920        }
921
922        // When $html is true, the excerpt should be created without including HTML tags in the
923        // excerpt length.
924        if ( ! empty( $r['html'] ) ) {
925
926                // The text is short enough. No need to truncate.
927                if ( mb_strlen( preg_replace( '/<.*?>/', '', $text ) ) <= $length ) {
928                        return $text;
929                }
930
931                $totalLength = mb_strlen( strip_tags( $ending ) );
932                $openTags    = array();
933                $truncate    = '';
934
935                // Find all the tags and HTML comments and put them in a stack for later use.
936                preg_match_all( '/(<\/?([\w+!]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER );
937
938                foreach ( $tags as $tag ) {
939                        // Process tags that need to be closed.
940                        if ( !preg_match( '/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s',  $tag[2] ) ) {
941                                if ( preg_match( '/<[\w]+[^>]*>/s', $tag[0] ) ) {
942                                        array_unshift( $openTags, $tag[2] );
943                                } elseif ( preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag ) ) {
944                                        $pos = array_search( $closeTag[1], $openTags );
945                                        if ( $pos !== false ) {
946                                                array_splice( $openTags, $pos, 1 );
947                                        }
948                                }
949                        }
950
951                        $truncate     .= $tag[1];
952                        $contentLength = mb_strlen( preg_replace( '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3] ) );
953
954                        if ( $contentLength + $totalLength > $length ) {
955                                $left = $length - $totalLength;
956                                $entitiesLength = 0;
957                                if ( preg_match_all( '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE ) ) {
958                                        foreach ( $entities[0] as $entity ) {
959                                                if ( $entity[1] + 1 - $entitiesLength <= $left ) {
960                                                        $left--;
961                                                        $entitiesLength += mb_strlen( $entity[0] );
962                                                } else {
963                                                        break;
964                                                }
965                                        }
966                                }
967
968                                $truncate .= mb_substr( $tag[3], 0 , $left + $entitiesLength );
969                                break;
970                        } else {
971                                $truncate .= $tag[3];
972                                $totalLength += $contentLength;
973                        }
974                        if ( $totalLength >= $length ) {
975                                break;
976                        }
977                }
978        } else {
979                // Strip HTML tags if necessary.
980                if ( ! empty( $r['strip_tags'] ) ) {
981                        $text = strip_tags( $text );
982                }
983
984                // Remove links if necessary.
985                if ( ! empty( $r['remove_links'] ) ) {
986                        $text = preg_replace( '#^\s*(https?://[^\s"]+)\s*$#im', '', $text );
987                }
988
989                if ( mb_strlen( $text ) <= $length ) {
990                        /**
991                         * Filters the final generated excerpt.
992                         *
993                         * @since 1.1.0
994                         *
995                         * @param string $text          Generated excerpt.
996                         * @param string $original_text Original text provided.
997                         * @param int    $length        Length of returned string, including ellipsis.
998                         * @param array  $options       Array of HTML attributes and options.
999                         */
1000                        return apply_filters( 'bp_create_excerpt', $text, $original_text, $length, $options );
1001                } else {
1002                        $truncate = mb_substr( $text, 0, $length - mb_strlen( $ending ) );
1003                }
1004        }
1005
1006        // If $exact is false, we can't break on words.
1007        if ( empty( $r['exact'] ) ) {
1008                // Find the position of the last space character not part of a tag.
1009                preg_match_all( '/<[a-z\!\/][^>]*>/', $truncate, $_truncate_tags, PREG_OFFSET_CAPTURE );
1010
1011                // Rekey tags by the string index of their last character.
1012                $truncate_tags = array();
1013                if ( ! empty( $_truncate_tags[0] ) ) {
1014                        foreach ( $_truncate_tags[0] as $_tt ) {
1015                                $_tt['start'] = $_tt[1];
1016                                $_tt['end']   = $_tt[1] + strlen( $_tt[0] );
1017                                $truncate_tags[ $_tt['end'] ] = $_tt;
1018                        }
1019                }
1020
1021                $truncate_length = mb_strlen( $truncate );
1022                $spacepos = $truncate_length + 1;
1023                for ( $pos = $truncate_length - 1; $pos >= 0; $pos-- ) {
1024                        // Word boundaries are spaces and the close of HTML tags, when the tag is preceded by a space.
1025                        $is_word_boundary = ' ' === $truncate[ $pos ];
1026                        if ( ! $is_word_boundary && isset( $truncate_tags[ $pos - 1 ] ) ) {
1027                                $preceding_tag    = $truncate_tags[ $pos - 1 ];
1028                                if ( ' ' === $truncate[ $preceding_tag['start'] - 1 ] ) {
1029                                        $is_word_boundary = true;
1030                                        break;
1031                                }
1032                        }
1033
1034                        if ( ! $is_word_boundary ) {
1035                                continue;
1036                        }
1037
1038                        // If there are no tags in the string, the first space found is the right one.
1039                        if ( empty( $truncate_tags ) ) {
1040                                $spacepos = $pos;
1041                                break;
1042                        }
1043
1044                        // Look at each tag to see if the space is inside of it.
1045                        $intag = false;
1046                        foreach ( $truncate_tags as $tt ) {
1047                                if ( $pos > $tt['start'] && $pos < $tt['end'] ) {
1048                                        $intag = true;
1049                                        break;
1050                                }
1051                        }
1052
1053                        if ( ! $intag ) {
1054                                $spacepos = $pos;
1055                                break;
1056                        }
1057                }
1058
1059                if ( $r['html'] ) {
1060                        $bits = mb_substr( $truncate, $spacepos );
1061                        preg_match_all( '/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER );
1062                        if ( !empty( $droppedTags ) ) {
1063                                foreach ( $droppedTags as $closingTag ) {
1064                                        if ( !in_array( $closingTag[1], $openTags ) ) {
1065                                                array_unshift( $openTags, $closingTag[1] );
1066                                        }
1067                                }
1068                        }
1069                }
1070
1071                $truncate = rtrim( mb_substr( $truncate, 0, $spacepos ) );
1072        }
1073        $truncate .= $ending;
1074
1075        if ( !empty( $r['html'] ) ) {
1076                foreach ( $openTags as $tag ) {
1077                        $truncate .= '</' . $tag . '>';
1078                }
1079        }
1080
1081        /** This filter is documented in /bp-core/bp-core-template.php */
1082        return apply_filters( 'bp_create_excerpt', $truncate, $original_text, $length, $options );
1083}
1084add_filter( 'bp_create_excerpt', 'stripslashes_deep'  );
1085add_filter( 'bp_create_excerpt', 'force_balance_tags' );
1086
1087/**
1088 * Output the total member count for the site.
1089 *
1090 * @since 1.2.0
1091 */
1092function bp_total_member_count() {
1093        echo bp_get_total_member_count();
1094}
1095        /**
1096         * Return the total member count in your BP instance.
1097         *
1098         * Since BuddyPress 1.6, this function has used bp_core_get_active_member_count(),
1099         * which counts non-spam, non-deleted users who have last_activity.
1100         * This value will correctly match the total member count number used
1101         * for pagination on member directories.
1102         *
1103         * Before BuddyPress 1.6, this function used bp_core_get_total_member_count(),
1104         * which did not take into account last_activity, and thus often
1105         * resulted in higher counts than shown by member directory pagination.
1106         *
1107         * @since 1.2.0
1108         *
1109         * @return int Member count.
1110         */
1111        function bp_get_total_member_count() {
1112
1113                /**
1114                 * Filters the total member count in your BP instance.
1115                 *
1116                 * @since 1.2.0
1117                 *
1118                 * @param int $value Member count.
1119                 */
1120                return apply_filters( 'bp_get_total_member_count', bp_core_get_active_member_count() );
1121        }
1122        add_filter( 'bp_get_total_member_count', 'bp_core_number_format' );
1123
1124/**
1125 * Output whether blog signup is allowed.
1126 *
1127 * @todo Deprecate. It doesn't make any sense to echo a boolean.
1128 */
1129function bp_blog_signup_allowed() {
1130        echo bp_get_blog_signup_allowed();
1131}
1132        /**
1133         * Is blog signup allowed?
1134         *
1135         * Returns true if is_multisite() and blog creation is enabled at
1136         * Network Admin > Settings.
1137         *
1138         * @since 1.2.0
1139         *
1140         * @return bool True if blog signup is allowed, otherwise false.
1141         */
1142        function bp_get_blog_signup_allowed() {
1143
1144                if ( ! is_multisite() ) {
1145                        return false;
1146                }
1147
1148                $status = bp_core_get_root_option( 'registration' );
1149                if ( ( 'none' !== $status ) && ( 'user' !== $status ) ) {
1150                        return true;
1151                }
1152
1153                return false;
1154        }
1155
1156/**
1157 * Check whether an activation has just been completed.
1158 *
1159 * @since 1.1.0
1160 *
1161 * @return bool True if the activation_complete global flag has been set,
1162 *              otherwise false.
1163 */
1164function bp_account_was_activated() {
1165        $bp = buddypress();
1166
1167        $activation_complete = ! empty( $bp->activation_complete ) || ( bp_is_current_component( 'activate' ) && ! empty( $_GET['activated'] ) );
1168
1169        return $activation_complete;
1170}
1171
1172/**
1173 * Check whether registrations require activation on this installation.
1174 *
1175 * On a normal BuddyPress installation, all registrations require email
1176 * activation. This filter exists so that customizations that omit activation
1177 * can remove certain notification text from the registration screen.
1178 *
1179 * @since 1.2.0
1180 *
1181 * @return bool True by default.
1182 */
1183function bp_registration_needs_activation() {
1184
1185        /**
1186         * Filters whether registrations require activation on this installation.
1187         *
1188         * @since 1.2.0
1189         *
1190         * @param bool $value Whether registrations require activation. Default true.
1191         */
1192        return apply_filters( 'bp_registration_needs_activation', true );
1193}
1194
1195/**
1196 * Retrieve a client friendly version of the root blog name.
1197 *
1198 * The blogname option is escaped with esc_html on the way into the database in
1199 * sanitize_option, we want to reverse this for the plain text arena of emails.
1200 *
1201 * @since 1.7.0
1202 * @since 2.5.0 No longer used by BuddyPress, but not deprecated in case any existing plugins use it.
1203 *
1204 * @see https://buddypress.trac.wordpress.org/ticket/4401
1205 *
1206 * @param array $args {
1207 *     Array of optional parameters.
1208 *     @type string $before  String to appear before the site name in the
1209 *                           email subject. Default: '['.
1210 *     @type string $after   String to appear after the site name in the
1211 *                           email subject. Default: ']'.
1212 *     @type string $default The default site name, to be used when none is
1213 *                           found in the database. Default: 'Community'.
1214 *     @type string $text    Text to append to the site name (ie, the main text of
1215 *                           the email subject).
1216 * }
1217 * @return string Sanitized email subject.
1218 */
1219function bp_get_email_subject( $args = array() ) {
1220
1221        $r = bp_parse_args(
1222                $args,
1223                array(
1224                        'before'  => '[',
1225                        'after'   => ']',
1226                        'default' => __( 'Community', 'buddypress' ),
1227                        'text'    => '',
1228                ),
1229                'get_email_subject'
1230        );
1231
1232        $subject = $r['before'] . wp_specialchars_decode( bp_get_option( 'blogname', $r['default'] ), ENT_QUOTES ) . $r['after'] . ' ' . $r['text'];
1233
1234        /**
1235         * Filters a client friendly version of the root blog name.
1236         *
1237         * @since 1.7.0
1238         *
1239         * @param string $subject Client friendly version of the root blog name.
1240         * @param array  $r       Array of arguments for the email subject.
1241         */
1242        return apply_filters( 'bp_get_email_subject', $subject, $r );
1243}
1244
1245/**
1246 * Allow templates to pass parameters directly into the template loops via AJAX.
1247 *
1248 * For the most part this will be filtered in a theme's functions.php for
1249 * example in the default theme it is filtered via bp_dtheme_ajax_querystring().
1250 *
1251 * By using this template tag in the templates it will stop them from showing
1252 * errors if someone copies the templates from the default theme into another
1253 * WordPress theme without coping the functions from functions.php.
1254 *
1255 * @since 1.2.0
1256 *
1257 * @param string|bool $object Current template component.
1258 * @return string The AJAX querystring.
1259 */
1260function bp_ajax_querystring( $object = false ) {
1261        $bp = buddypress();
1262
1263        if ( ! isset( $bp->ajax_querystring ) ) {
1264                $bp->ajax_querystring = '';
1265        }
1266
1267        /**
1268         * Filters the template parameters to be used in the query string.
1269         *
1270         * Allows templates to pass parameters into the template loops via AJAX.
1271         *
1272         * @since 1.2.0
1273         *
1274         * @param string $ajax_querystring Current query string.
1275         * @param string $object           Current template component.
1276         */
1277        return apply_filters( 'bp_ajax_querystring', $bp->ajax_querystring, $object );
1278}
1279
1280/** Template Classes and _is functions ****************************************/
1281
1282/**
1283 * Return the name of the current component.
1284 *
1285 * @since 1.0.0
1286 *
1287 * @return string Component name.
1288 */
1289function bp_current_component() {
1290        $bp                = buddypress();
1291        $current_component = !empty( $bp->current_component )
1292                ? $bp->current_component
1293                : false;
1294
1295        /**
1296         * Filters the name of the current component.
1297         *
1298         * @since 1.0.0
1299         *
1300         * @param string|bool $current_component Current component if available or false.
1301         */
1302        return apply_filters( 'bp_current_component', $current_component );
1303}
1304
1305/**
1306 * Return the name of the current action.
1307 *
1308 * @since 1.0.0
1309 *
1310 * @return string Action name.
1311 */
1312function bp_current_action() {
1313        $bp             = buddypress();
1314        $current_action = !empty( $bp->current_action )
1315                ? $bp->current_action
1316                : '';
1317
1318        /**
1319         * Filters the name of the current action.
1320         *
1321         * @since 1.0.0
1322         *
1323         * @param string $current_action Current action.
1324         */
1325        return apply_filters( 'bp_current_action', $current_action );
1326}
1327
1328/**
1329 * Return the name of the current item.
1330 *
1331 * @since 1.1.0
1332 *
1333 * @return string|bool
1334 */
1335function bp_current_item() {
1336        $bp           = buddypress();
1337        $current_item = !empty( $bp->current_item )
1338                ? $bp->current_item
1339                : false;
1340
1341        /**
1342         * Filters the name of the current item.
1343         *
1344         * @since 1.1.0
1345         *
1346         * @param string|bool $current_item Current item if available or false.
1347         */
1348        return apply_filters( 'bp_current_item', $current_item );
1349}
1350
1351/**
1352 * Return the value of $bp->action_variables.
1353 *
1354 * @since 1.0.0
1355 *
1356 * @return array|bool $action_variables The action variables array, or false
1357 *                                      if the array is empty.
1358 */
1359function bp_action_variables() {
1360        $bp               = buddypress();
1361        $action_variables = !empty( $bp->action_variables )
1362                ? $bp->action_variables
1363                : false;
1364
1365        /**
1366         * Filters the value of $bp->action_variables.
1367         *
1368         * @since 1.0.0
1369         *
1370         * @param array|bool $action_variables Available action variables.
1371         */
1372        return apply_filters( 'bp_action_variables', $action_variables );
1373}
1374
1375/**
1376 * Return the value of a given action variable.
1377 *
1378 * @since 1.5.0
1379 *
1380 * @param int $position The key of the action_variables array that you want.
1381 * @return string|bool $action_variable The value of that position in the
1382 *                                      array, or false if not found.
1383 */
1384function bp_action_variable( $position = 0 ) {
1385        $action_variables = bp_action_variables();
1386        $action_variable  = isset( $action_variables[ $position ] )
1387                ? $action_variables[ $position ]
1388                : false;
1389
1390        /**
1391         * Filters the value of a given action variable.
1392         *
1393         * @since 1.5.0
1394         *
1395         * @param string|bool $action_variable Requested action variable based on position.
1396         * @param int         $position        The key of the action variable requested.
1397         */
1398        return apply_filters( 'bp_action_variable', $action_variable, $position );
1399}
1400
1401/**
1402 * Output the "root domain", the URL of the BP root blog.
1403 *
1404 * @since 1.1.0
1405 */
1406function bp_root_domain() {
1407        echo bp_get_root_domain();
1408}
1409        /**
1410         * Return the "root domain", the URL of the BP root blog.
1411         *
1412         * @since 1.1.0
1413         *
1414         * @return string URL of the BP root blog.
1415         */
1416        function bp_get_root_domain() {
1417                $bp = buddypress();
1418
1419                if ( ! empty( $bp->root_domain ) ) {
1420                        $domain = $bp->root_domain;
1421                } else {
1422                        $domain          = bp_core_get_root_domain();
1423                        $bp->root_domain = $domain;
1424                }
1425
1426                /**
1427                 * Filters the "root domain", the URL of the BP root blog.
1428                 *
1429                 * @since 1.2.4
1430                 *
1431                 * @param string $domain URL of the BP root blog.
1432                 */
1433                return apply_filters( 'bp_get_root_domain', $domain );
1434        }
1435
1436/**
1437 * Output the root slug for a given component.
1438 *
1439 * @since 1.5.0
1440 *
1441 * @param string $component The component name.
1442 */
1443function bp_root_slug( $component = '' ) {
1444        echo bp_get_root_slug( $component );
1445}
1446        /**
1447         * Get the root slug for given component.
1448         *
1449         * The "root slug" is the string used when concatenating component
1450         * directory URLs. For example, on an installation where the Groups
1451         * component's directory is located at http://example.com/groups/, the
1452         * root slug for the Groups component is 'groups'. This string
1453         * generally corresponds to page_name of the component's directory
1454         * page.
1455         *
1456         * In order to maintain backward compatibility, the following procedure
1457         * is used:
1458         * 1) Use the short slug to get the canonical component name from the
1459         *    active component array.
1460         * 2) Use the component name to get the root slug out of the
1461         *    appropriate part of the $bp global.
1462         * 3) If nothing turns up, it probably means that $component is itself
1463         *    a root slug.
1464         *
1465         * Example: If your groups directory is at /community/companies, this
1466         * function first uses the short slug 'companies' (ie the current
1467         * component) to look up the canonical name 'groups' in
1468         * $bp->active_components. Then it uses 'groups' to get the root slug,
1469         * from $bp->groups->root_slug.
1470         *
1471         * @since 1.5.0
1472         *
1473         * @param string $component Optional. Defaults to the current component.
1474         * @return string $root_slug The root slug.
1475         */
1476        function bp_get_root_slug( $component = '' ) {
1477                $bp        = buddypress();
1478                $root_slug = '';
1479
1480                // Use current global component if none passed.
1481                if ( empty( $component ) ) {
1482                        $component = bp_current_component();
1483                }
1484
1485                // Component is active.
1486                if ( ! empty( $bp->active_components[ $component ] ) ) {
1487
1488                        // Backward compatibility: in legacy plugins, the canonical component id
1489                        // was stored as an array value in $bp->active_components.
1490                        $component_name = ( '1' == $bp->active_components[ $component ] )
1491                                ? $component
1492                                : $bp->active_components[$component];
1493
1494                        // Component has specific root slug.
1495                        if ( ! empty( $bp->{$component_name}->root_slug ) ) {
1496                                $root_slug = $bp->{$component_name}->root_slug;
1497                        }
1498                }
1499
1500                // No specific root slug, so fall back to component slug.
1501                if ( empty( $root_slug ) ) {
1502                        $root_slug = $component;
1503                }
1504
1505                /**
1506                 * Filters the root slug for given component.
1507                 *
1508                 * @since 1.5.0
1509                 *
1510                 * @param string $root_slug Root slug for given component.
1511                 * @param string $component Current component.
1512                 */
1513                return apply_filters( 'bp_get_root_slug', $root_slug, $component );
1514        }
1515
1516/**
1517 * Return the component name based on a root slug.
1518 *
1519 * @since 1.5.0
1520 *
1521 * @param string $root_slug Needle to our active component haystack.
1522 * @return mixed False if none found, component name if found.
1523 */
1524function bp_get_name_from_root_slug( $root_slug = '' ) {
1525        $bp = buddypress();
1526
1527        // If no slug is passed, look at current_component.
1528        if ( empty( $root_slug ) ) {
1529                $root_slug = bp_current_component();
1530        }
1531
1532        // No current component or root slug, so flee.
1533        if ( empty( $root_slug ) ) {
1534                return false;
1535        }
1536
1537        // Loop through active components and look for a match.
1538        foreach ( array_keys( $bp->active_components ) as $component ) {
1539                if ( ( ! empty( $bp->{$component}->slug ) && ( $bp->{$component}->slug == $root_slug ) ) || ( ! empty( $bp->{$component}->root_slug ) && ( $bp->{$component}->root_slug === $root_slug ) ) ) {
1540                        return $bp->{$component}->name;
1541                }
1542        }
1543
1544        return false;
1545}
1546
1547/**
1548 * Returns whether or not a user has access.
1549 *
1550 * @since 1.2.4
1551 *
1552 * @return bool
1553 */
1554function bp_user_has_access() {
1555        $has_access = bp_current_user_can( 'bp_moderate' ) || bp_is_my_profile();
1556
1557        /**
1558         * Filters whether or not a user has access.
1559         *
1560         * @since 1.2.4
1561         *
1562         * @param bool $has_access Whether or not user has access.
1563         */
1564        return (bool) apply_filters( 'bp_user_has_access', $has_access );
1565}
1566
1567/**
1568 * Output the search slug.
1569 *
1570 * @since 1.5.0
1571 *
1572 */
1573function bp_search_slug() {
1574        echo bp_get_search_slug();
1575}
1576        /**
1577         * Return the search slug.
1578         *
1579         * @since 1.5.0
1580         *
1581         * @return string The search slug. Default: 'search'.
1582         */
1583        function bp_get_search_slug() {
1584
1585                /**
1586                 * Filters the search slug.
1587                 *
1588                 * @since 1.5.0
1589                 *
1590                 * @const string BP_SEARCH_SLUG The search slug. Default "search".
1591                 */
1592                return apply_filters( 'bp_get_search_slug', BP_SEARCH_SLUG );
1593        }
1594
1595/**
1596 * Get the ID of the currently displayed user.
1597 *
1598 * @since 1.0.0
1599 *
1600 * @return int $id ID of the currently displayed user.
1601 */
1602function bp_displayed_user_id() {
1603        $bp = buddypress();
1604        $id = !empty( $bp->displayed_user->id )
1605                ? $bp->displayed_user->id
1606                : 0;
1607
1608        /**
1609         * Filters the ID of the currently displayed user.
1610         *
1611         * @since 1.0.0
1612         *
1613         * @param int $id ID of the currently displayed user.
1614         */
1615        return (int) apply_filters( 'bp_displayed_user_id', $id );
1616}
1617
1618/**
1619 * Get the ID of the currently logged-in user.
1620 *
1621 * @since 1.0.0
1622 *
1623 * @return int ID of the logged-in user.
1624 */
1625function bp_loggedin_user_id() {
1626        $bp = buddypress();
1627        $id = !empty( $bp->loggedin_user->id )
1628                ? $bp->loggedin_user->id
1629                : 0;
1630
1631        /**
1632         * Filters the ID of the currently logged-in user.
1633         *
1634         * @since 1.0.0
1635         *
1636         * @param int $id ID of the currently logged-in user.
1637         */
1638        return (int) apply_filters( 'bp_loggedin_user_id', $id );
1639}
1640
1641/** The is_() functions to determine the current page *****************************/
1642
1643/**
1644 * Check to see whether the current page belongs to the specified component.
1645 *
1646 * This function is designed to be generous, accepting several different kinds
1647 * of value for the $component parameter. It checks $component_name against:
1648 * - the component's root_slug, which matches the page slug in $bp->pages.
1649 * - the component's regular slug.
1650 * - the component's id, or 'canonical' name.
1651 *
1652 * @since 1.5.0
1653 *
1654 * @param string $component Name of the component being checked.
1655 * @return bool Returns true if the component matches, or else false.
1656 */
1657function bp_is_current_component( $component = '' ) {
1658
1659        // Default is no match. We'll check a few places for matches.
1660        $is_current_component = false;
1661
1662        // Always return false if a null value is passed to the function.
1663        if ( empty( $component ) ) {
1664                return false;
1665        }
1666
1667        // Backward compatibility: 'xprofile' should be read as 'profile'.
1668        if ( 'xprofile' === $component ) {
1669                $component = 'profile';
1670        }
1671
1672        $bp = buddypress();
1673
1674        // Only check if BuddyPress found a current_component.
1675        if ( ! empty( $bp->current_component ) ) {
1676
1677                // First, check to see whether $component_name and the current
1678                // component are a simple match.
1679                if ( $bp->current_component == $component ) {
1680                        $is_current_component = true;
1681
1682                // Since the current component is based on the visible URL slug let's
1683                // check the component being passed and see if its root_slug matches.
1684                } elseif ( isset( $bp->{$component}->root_slug ) && $bp->{$component}->root_slug == $bp->current_component ) {
1685                        $is_current_component = true;
1686
1687                // Because slugs can differ from root_slugs, we should check them too.
1688                } elseif ( isset( $bp->{$component}->slug ) && $bp->{$component}->slug == $bp->current_component ) {
1689                        $is_current_component = true;
1690
1691                // Next, check to see whether $component is a canonical,
1692                // non-translatable component name. If so, we can return its
1693                // corresponding slug from $bp->active_components.
1694                } elseif ( $key = array_search( $component, $bp->active_components ) ) {
1695                        if ( strstr( $bp->current_component, $key ) ) {
1696                                $is_current_component = true;
1697                        }
1698
1699                // If we haven't found a match yet, check against the root_slugs
1700                // created by $bp->pages, as well as the regular slugs.
1701                } else {
1702                        foreach ( $bp->active_components as $id ) {
1703                                // If the $component parameter does not match the current_component,
1704                                // then move along, these are not the droids you are looking for.
1705                                if ( empty( $bp->{$id}->root_slug ) || $bp->{$id}->root_slug != $bp->current_component ) {
1706                                        continue;
1707                                }
1708
1709                                if ( $id == $component ) {
1710                                        $is_current_component = true;
1711                                        break;
1712                                }
1713                        }
1714                }
1715        }
1716
1717        /**
1718         * Filters whether the current page belongs to the specified component.
1719         *
1720         * @since 1.5.0
1721         *
1722         * @param bool   $is_current_component Whether or not the current page belongs to specified component.
1723         * @param string $component            Name of the component being checked.
1724         */
1725        return apply_filters( 'bp_is_current_component', $is_current_component, $component );
1726}
1727
1728/**
1729 * Check to see whether the current page matches a given action.
1730 *
1731 * Along with bp_is_current_component() and bp_is_action_variable(), this
1732 * function is mostly used to help determine when to use a given screen
1733 * function.
1734 *
1735 * In BP parlance, the current_action is the URL chunk that comes directly
1736 * after the current item slug. E.g., in
1737 *   http://example.com/groups/my-group/members
1738 * the current_action is 'members'.
1739 *
1740 * @since 1.5.0
1741 *
1742 * @param string $action The action being tested against.
1743 * @return bool True if the current action matches $action.
1744 */
1745function bp_is_current_action( $action = '' ) {
1746        return (bool) ( $action === bp_current_action() );
1747}
1748
1749/**
1750 * Check to see whether the current page matches a given action_variable.
1751 *
1752 * Along with bp_is_current_component() and bp_is_current_action(), this
1753 * function is mostly used to help determine when to use a given screen
1754 * function.
1755 *
1756 * In BP parlance, action_variables are an array made up of the URL chunks
1757 * appearing after the current_action in a URL. For example,
1758 *   http://example.com/groups/my-group/admin/group-settings
1759 * $action_variables[0] is 'group-settings'.
1760 *
1761 * @since 1.5.0
1762 *
1763 * @param string   $action_variable The action_variable being tested against.
1764 * @param int|bool $position        Optional. The array key you're testing against. If you
1765 *                                  don't provide a $position, the function will return true if the
1766 *                                  $action_variable is found *anywhere* in the action variables array.
1767 * @return bool True if $action_variable matches at the $position provided.
1768 */
1769function bp_is_action_variable( $action_variable = '', $position = false ) {
1770        $is_action_variable = false;
1771
1772        if ( false !== $position ) {
1773                // When a $position is specified, check that slot in the action_variables array.
1774                if ( $action_variable ) {
1775                        $is_action_variable = $action_variable == bp_action_variable( $position );
1776                } else {
1777                        // If no $action_variable is provided, we are essentially checking to see
1778                        // whether the slot is empty.
1779                        $is_action_variable = !bp_action_variable( $position );
1780                }
1781        } else {
1782                // When no $position is specified, check the entire array.
1783                $is_action_variable = in_array( $action_variable, (array)bp_action_variables() );
1784        }
1785
1786        /**
1787         * Filters whether the current page matches a given action_variable.
1788         *
1789         * @since 1.5.0
1790         *
1791         * @param bool   $is_action_variable Whether the current page matches a given action_variable.
1792         * @param string $action_variable    The action_variable being tested against.
1793         * @param int    $position           The array key tested against.
1794         */
1795        return apply_filters( 'bp_is_action_variable', $is_action_variable, $action_variable, $position );
1796}
1797
1798/**
1799 * Check against the current_item.
1800 *
1801 * @since 1.5.0
1802 *
1803 * @param string $item The item being checked.
1804 * @return bool True if $item is the current item.
1805 */
1806function bp_is_current_item( $item = '' ) {
1807        $retval = ( $item === bp_current_item() );
1808
1809        /**
1810         * Filters whether or not an item is the current item.
1811         *
1812         * @since 2.1.0
1813         *
1814         * @param bool   $retval Whether or not an item is the current item.
1815         * @param string $item   The item being checked.
1816         */
1817        return (bool) apply_filters( 'bp_is_current_item', $retval, $item );
1818}
1819
1820/**
1821 * Are we looking at a single item? (group, user, etc).
1822 *
1823 * @since 1.1.0
1824 *
1825 * @return bool True if looking at a single item, otherwise false.
1826 */
1827function bp_is_single_item() {
1828        $bp     = buddypress();
1829        $retval = false;
1830
1831        if ( isset( $bp->is_single_item ) ) {
1832                $retval = $bp->is_single_item;
1833        }
1834
1835        /**
1836         * Filters whether or not an item is the a single item. (group, user, etc)
1837         *
1838         * @since 2.1.0
1839         *
1840         * @param bool $retval Whether or not an item is a single item.
1841         */
1842        return (bool) apply_filters( 'bp_is_single_item', $retval );
1843}
1844
1845/**
1846 * Is the logged-in user an admin for the current item?
1847 *
1848 * @since 1.5.0
1849 *
1850 * @return bool True if the current user is an admin for the current item,
1851 *              otherwise false.
1852 */
1853function bp_is_item_admin() {
1854        $bp     = buddypress();
1855        $retval = false;
1856
1857        if ( isset( $bp->is_item_admin ) ) {
1858                $retval = $bp->is_item_admin;
1859        }
1860
1861        /**
1862         * Filters whether or not the logged-in user is an admin for the current item.
1863         *
1864         * @since 2.1.0
1865         *
1866         * @param bool $retval Whether or not the logged-in user is an admin.
1867         */
1868        return (bool) apply_filters( 'bp_is_item_admin', $retval );
1869}
1870
1871/**
1872 * Is the logged-in user a mod for the current item?
1873 *
1874 * @since 1.5.0
1875 *
1876 * @return bool True if the current user is a mod for the current item,
1877 *              otherwise false.
1878 */
1879function bp_is_item_mod() {
1880        $bp     = buddypress();
1881        $retval = false;
1882
1883        if ( isset( $bp->is_item_mod ) ) {
1884                $retval = $bp->is_item_mod;
1885        }
1886
1887        /**
1888         * Filters whether or not the logged-in user is a mod for the current item.
1889         *
1890         * @since 2.1.0
1891         *
1892         * @param bool $retval Whether or not the logged-in user is a mod.
1893         */
1894        return (bool) apply_filters( 'bp_is_item_mod', $retval );
1895}
1896
1897/**
1898 * Is this a component directory page?
1899 *
1900 * @since 1.0.0
1901 *
1902 * @return bool True if the current page is a component directory, otherwise false.
1903 */
1904function bp_is_directory() {
1905        $bp     = buddypress();
1906        $retval = false;
1907
1908        if ( isset( $bp->is_directory ) ) {
1909                $retval = $bp->is_directory;
1910        }
1911
1912        /**
1913         * Filters whether or not user is on a component directory page.
1914         *
1915         * @since 2.1.0
1916         *
1917         * @param bool $retval Whether or not user is on a component directory page.
1918         */
1919        return (bool) apply_filters( 'bp_is_directory', $retval );
1920}
1921
1922/**
1923 * Check to see if a component's URL should be in the root, not under a member page.
1924 *
1925 * - Yes ('groups' is root)    : http://example.com/groups/the-group
1926 * - No  ('groups' is not-root): http://example.com/members/andy/groups/the-group
1927 *
1928 * This function is on the chopping block. It's currently only used by a few
1929 * already deprecated functions.
1930 *
1931 * @since 1.5.0
1932 *
1933 * @param string $component_name Component name to check.
1934 *
1935 * @return bool True if root component, else false.
1936 */
1937function bp_is_root_component( $component_name = '' ) {
1938        $bp     = buddypress();
1939        $retval = false;
1940
1941        // Default to the current component if none is passed.
1942        if ( empty( $component_name ) ) {
1943                $component_name = bp_current_component();
1944        }
1945
1946        // Loop through active components and check for key/slug matches.
1947        if ( ! empty( $bp->active_components ) ) {
1948                foreach ( (array) $bp->active_components as $key => $slug ) {
1949                        if ( ( $key === $component_name ) || ( $slug === $component_name ) ) {
1950                                $retval = true;
1951                                break;
1952                        }
1953                }
1954        }
1955
1956        /**
1957         * Filters whether or not a component's URL should be in the root, not under a member page.
1958         *
1959         * @since 2.1.0
1960         *
1961         * @param bool $retval Whether or not URL should be in the root.
1962         */
1963        return (bool) apply_filters( 'bp_is_root_component', $retval );
1964}
1965
1966/**
1967 * Check if the specified BuddyPress component directory is set to be the front page.
1968 *
1969 * Corresponds to the setting in wp-admin's Settings > Reading screen.
1970 *
1971 * @since 1.5.0
1972 *
1973 * @global int $current_blog WordPress global for the current blog.
1974 *
1975 * @param string $component Optional. Name of the component to check for.
1976 *                          Default: current component.
1977 * @return bool True if the specified component is set to be the site's front
1978 *              page, otherwise false.
1979 */
1980function bp_is_component_front_page( $component = '' ) {
1981        global $current_blog;
1982
1983        $bp = buddypress();
1984
1985        // Default to the current component if none is passed.
1986        if ( empty( $component ) ) {
1987                $component = bp_current_component();
1988        }
1989
1990        // Get the path for the current blog/site.
1991        $path = is_main_site()
1992                ? bp_core_get_site_path()
1993                : $current_blog->path;
1994
1995        // Get the front page variables.
1996        $show_on_front = get_option( 'show_on_front' );
1997        $page_on_front = get_option( 'page_on_front' );
1998
1999        if ( ( 'page' !== $show_on_front ) || empty( $component ) || empty( $bp->pages->{$component} ) || ( $_SERVER['REQUEST_URI'] !== $path ) ) {
2000                return false;
2001        }
2002
2003        /**
2004         * Filters whether or not the specified BuddyPress component directory is set to be the front page.
2005         *
2006         * @since 1.5.0
2007         *
2008         * @param bool   $value     Whether or not the specified component directory is set as front page.
2009         * @param string $component Current component being checked.
2010         */
2011        return (bool) apply_filters( 'bp_is_component_front_page', ( $bp->pages->{$component}->id == $page_on_front ), $component );
2012}
2013
2014/**
2015 * Is this a blog page, ie a non-BP page?
2016 *
2017 * You can tell if a page is displaying BP content by whether the
2018 * current_component has been defined.
2019 *
2020 * @since 1.0.0
2021 *
2022 * @return bool True if it's a non-BP page, false otherwise.
2023 */
2024function bp_is_blog_page() {
2025
2026        $is_blog_page = false;
2027
2028        // Generally, we can just check to see that there's no current component.
2029        // The one exception is single user home tabs, where $bp->current_component
2030        // is unset. Thus the addition of the bp_is_user() check.
2031        if ( ! bp_current_component() && ! bp_is_user() ) {
2032                $is_blog_page = true;
2033        }
2034
2035        /**
2036         * Filters whether or not current page is a blog page or not.
2037         *
2038         * @since 1.5.0
2039         *
2040         * @param bool $is_blog_page Whether or not current page is a blog page.
2041         */
2042        return (bool) apply_filters( 'bp_is_blog_page', $is_blog_page );
2043}
2044
2045/**
2046 * Is this a BuddyPress component?
2047 *
2048 * You can tell if a page is displaying BP content by whether the
2049 * current_component has been defined.
2050 *
2051 * Generally, we can just check to see that there's no current component.
2052 * The one exception is single user home tabs, where $bp->current_component
2053 * is unset. Thus the addition of the bp_is_user() check.
2054 *
2055 * @since 1.7.0
2056 *
2057 * @return bool True if it's a BuddyPress page, false otherwise.
2058 */
2059function is_buddypress() {
2060        $retval = (bool) ( bp_current_component() || bp_is_user() );
2061
2062        /**
2063         * Filters whether or not this is a BuddyPress component.
2064         *
2065         * @since 1.7.0
2066         *
2067         * @param bool $retval Whether or not this is a BuddyPress component.
2068         */
2069        return apply_filters( 'is_buddypress', $retval );
2070}
2071
2072/** Components ****************************************************************/
2073
2074/**
2075 * Check whether a given component (or feature of a component) is active.
2076 *
2077 * @since 1.2.0 See r2539.
2078 * @since 2.3.0 Added $feature as a parameter.
2079 *
2080 * @param string $component The component name.
2081 * @param string $feature   The feature name.
2082 * @return bool
2083 */
2084function bp_is_active( $component = '', $feature = '' ) {
2085        $retval = false;
2086
2087        // Default to the current component if none is passed.
2088        if ( empty( $component ) ) {
2089                $component = bp_current_component();
2090        }
2091
2092        // Is component in either the active or required components arrays.
2093        if ( isset( buddypress()->active_components[ $component ] ) || in_array( $component, buddypress()->required_components, true ) ) {
2094                $retval = true;
2095
2096                // Is feature active?
2097                if ( ! empty( $feature ) ) {
2098                        // The xProfile component is specific.
2099                        if ( 'xprofile' === $component ) {
2100                                $component = 'profile';
2101
2102                                // The Cover Image feature has been moved to the Members component in 6.0.0.
2103                                if ( 'cover_image' === $feature && 'profile' === $component ) {
2104                                        _doing_it_wrong( 'bp_is_active( \'profile\', \'cover_image\' )', esc_html__( 'The cover image is a Members component feature, please use bp_is_active( \'members\', \'cover_image\' ) instead.', 'buddypress' ), '6.0.0' );
2105                                        $members_component = buddypress()->members;
2106
2107                                        if ( ! isset( $members_component->features ) || false === in_array( $feature, $members_component->features, true ) ) {
2108                                                $retval = false;
2109                                        }
2110
2111                                        /** This filter is documented in wp-includes/deprecated.php */
2112                                        return apply_filters_deprecated( 'bp_is_profile_cover_image_active', array( $retval ), '6.0.0', 'bp_is_members_cover_image_active' );
2113                                }
2114                        }
2115
2116                        $component_features = isset( buddypress()->{$component}->features ) ? buddypress()->{$component}->features : array();
2117
2118                        if ( empty( $component_features ) || false === in_array( $feature, $component_features, true ) ) {
2119                                $retval = false;
2120                        }
2121
2122                        /**
2123                         * Filters whether or not a given feature for a component is active.
2124                         *
2125                         * This is a variable filter that is based on the component and feature
2126                         * that you are checking of active status of.
2127                         *
2128                         * @since 2.3.0
2129                         *
2130                         * @param bool $retval
2131                         */
2132                        $retval = apply_filters( "bp_is_{$component}_{$feature}_active", $retval );
2133                }
2134        }
2135
2136        /**
2137         * Filters whether or not a given component has been activated by the admin.
2138         *
2139         * @since 2.1.0
2140         *
2141         * @param bool   $retval    Whether or not a given component has been activated by the admin.
2142         * @param string $component Current component being checked.
2143         */
2144        return apply_filters( 'bp_is_active', $retval, $component );
2145}
2146
2147/**
2148 * Check whether the current page is part of the Members component.
2149 *
2150 * @since 1.5.0
2151 *
2152 * @return bool True if the current page is part of the Members component.
2153 */
2154function bp_is_members_component() {
2155        return (bool) bp_is_current_component( 'members' );
2156}
2157
2158/**
2159 * Check whether the current page is part of the Profile component.
2160 *
2161 * @since 1.1.0
2162 *
2163 * @return bool True if the current page is part of the Profile component.
2164 */
2165function bp_is_profile_component() {
2166        return (bool) bp_is_current_component( 'xprofile' );
2167}
2168
2169/**
2170 * Check whether the current page is part of the Activity component.
2171 *
2172 * @since 1.1.0
2173 *
2174 * @return bool True if the current page is part of the Activity component.
2175 */
2176function bp_is_activity_component() {
2177        return (bool) bp_is_current_component( 'activity' );
2178}
2179
2180/**
2181 * Check whether the current page is part of the Blogs component.
2182 *
2183 * @since 1.1.0
2184 *
2185 * @return bool True if the current page is part of the Blogs component.
2186 */
2187function bp_is_blogs_component() {
2188        return (bool) ( is_multisite() && bp_is_current_component( 'blogs' ) );
2189}
2190
2191/**
2192 * Check whether the current page is part of the Messages component.
2193 *
2194 * @since 1.1.0
2195 *
2196 * @return bool True if the current page is part of the Messages component.
2197 */
2198function bp_is_messages_component() {
2199        return (bool) bp_is_current_component( 'messages' );
2200}
2201
2202/**
2203 * Check whether the current page is part of the Friends component.
2204 *
2205 * @since 1.1.0
2206 *
2207 * @return bool True if the current page is part of the Friends component.
2208 */
2209function bp_is_friends_component() {
2210        return (bool) bp_is_current_component( 'friends' );
2211}
2212
2213/**
2214 * Check whether the current page is part of the Groups component.
2215 *
2216 * @since 1.1.0
2217 *
2218 * @return bool True if the current page is part of the Groups component.
2219 */
2220function bp_is_groups_component() {
2221        return (bool) bp_is_current_component( 'groups' );
2222}
2223
2224/**
2225 * Check whether the current page is part of the Forums component.
2226 *
2227 * @since 1.5.0
2228 * @since 3.0.0 Required for bbPress 2 integration.
2229 *
2230 * @return bool True if the current page is part of the Forums component.
2231 */
2232function bp_is_forums_component() {
2233        return (bool) bp_is_current_component( 'forums' );
2234}
2235
2236/**
2237 * Check whether the current page is part of the Notifications component.
2238 *
2239 * @since 1.9.0
2240 *
2241 * @return bool True if the current page is part of the Notifications component.
2242 */
2243function bp_is_notifications_component() {
2244        return (bool) bp_is_current_component( 'notifications' );
2245}
2246
2247/**
2248 * Check whether the current page is part of the Settings component.
2249 *
2250 * @since 1.1.0
2251 *
2252 * @return bool True if the current page is part of the Settings component.
2253 */
2254function bp_is_settings_component() {
2255        return (bool) bp_is_current_component( 'settings' );
2256}
2257
2258/**
2259 * Check whether the current page is an Invitations screen.
2260 *
2261 * @since 8.0.0
2262 *
2263 * @return bool True if the current page is an Invitations screen.
2264 */
2265function bp_is_members_invitations_screen() {
2266        return (bool) bp_is_current_component( bp_get_members_invitations_slug() );
2267}
2268
2269/**
2270 * Is the current component an active core component?
2271 *
2272 * Use this function when you need to check if the current component is an
2273 * active core component of BuddyPress. If the current component is inactive, it
2274 * will return false. If the current component is not part of BuddyPress core,
2275 * it will return false. If the current component is active, and is part of
2276 * BuddyPress core, it will return true.
2277 *
2278 * @since 1.7.0
2279 *
2280 * @return bool True if the current component is active and is one of BP's
2281 *              packaged components.
2282 */
2283function bp_is_current_component_core() {
2284        $retval = false;
2285
2286        foreach ( bp_core_get_packaged_component_ids() as $active_component ) {
2287                if ( bp_is_current_component( $active_component ) ) {
2288                        $retval = true;
2289                        break;
2290                }
2291        }
2292
2293        return $retval;
2294}
2295
2296/** Activity ******************************************************************/
2297
2298/**
2299 * Is the current page the activity directory?
2300 *
2301 * @since 2.0.0
2302 *
2303 * @return bool True if the current page is the activity directory.
2304 */
2305function bp_is_activity_directory() {
2306        if ( ! bp_displayed_user_id() && bp_is_activity_component() && ! bp_current_action() ) {
2307                return true;
2308        }
2309
2310        return false;
2311}
2312
2313/**
2314 * Is the current page a single activity item permalink?
2315 *
2316 * @since 1.5.0
2317 *
2318 * @return bool True if the current page is a single activity item permalink.
2319 */
2320function bp_is_single_activity() {
2321        return (bool) ( bp_is_activity_component() && is_numeric( bp_current_action() ) );
2322}
2323
2324/** User **********************************************************************/
2325
2326/**
2327 * Is the current page the members directory?
2328 *
2329 * @since 2.0.0
2330 *
2331 * @return bool True if the current page is the members directory.
2332 */
2333function bp_is_members_directory() {
2334        if ( ! bp_is_user() && bp_is_members_component() ) {
2335                return true;
2336        }
2337
2338        return false;
2339}
2340
2341/**
2342 * Is the current page part of the profile of the logged-in user?
2343 *
2344 * Will return true for any subpage of the logged-in user's profile, eg
2345 * http://example.com/members/joe/friends/.
2346 *
2347 * @since 1.2.0
2348 *
2349 * @return bool True if the current page is part of the profile of the logged-in user.
2350 */
2351function bp_is_my_profile() {
2352        if ( is_user_logged_in() && bp_loggedin_user_id() == bp_displayed_user_id() ) {
2353                $my_profile = true;
2354        } else {
2355                $my_profile = false;
2356        }
2357
2358        /**
2359         * Filters whether or not current page is part of the profile for the logged-in user.
2360         *
2361         * @since 1.2.4
2362         *
2363         * @param bool $my_profile Whether or not current page is part of the profile for the logged-in user.
2364         */
2365        return apply_filters( 'bp_is_my_profile', $my_profile );
2366}
2367
2368/**
2369 * Is the current page a user page?
2370 *
2371 * Will return true anytime there is a displayed user.
2372 *
2373 * @since 1.5.0
2374 *
2375 * @return bool True if the current page is a user page.
2376 */
2377function bp_is_user() {
2378        return (bool) bp_displayed_user_id();
2379}
2380
2381/**
2382 * Is the current page a user custom front page?
2383 *
2384 * Will return true anytime there is a custom front page for the displayed user.
2385 *
2386 * @since 2.6.0
2387 *
2388 * @return bool True if the current page is a user custom front page.
2389 */
2390function bp_is_user_front() {
2391        return (bool) ( bp_is_user() && bp_is_current_component( 'front' ) );
2392}
2393
2394/**
2395 * Is the current page a user's activity stream page?
2396 *
2397 * Eg http://example.com/members/joe/activity/ (or any subpages thereof).
2398 *
2399 * @since 1.1.0
2400 *
2401 * @return bool True if the current page is a user's activity stream page.
2402 */
2403function bp_is_user_activity() {
2404        return (bool) ( bp_is_user() && bp_is_activity_component() );
2405}
2406
2407/**
2408 * Is the current page a user's Friends activity stream?
2409 *
2410 * Eg http://example.com/members/joe/friends/
2411 *
2412 * @since 1.1.0
2413 *
2414 * @return bool True if the current page is a user's Friends activity stream.
2415 */
2416function bp_is_user_friends_activity() {
2417
2418        if ( ! bp_is_active( 'friends' ) ) {
2419                return false;
2420        }
2421
2422        $slug = bp_get_friends_slug();
2423
2424        if ( empty( $slug ) ) {
2425                $slug = 'friends';
2426        }
2427
2428        if ( bp_is_user_activity() && bp_is_current_action( $slug ) ) {
2429                return true;
2430        }
2431
2432        return false;
2433}
2434
2435/**
2436 * Is the current page a user's Groups activity stream?
2437 *
2438 * Eg http://example.com/members/joe/groups/
2439 *
2440 * @since 1.5.0
2441 *
2442 * @return bool True if the current page is a user's Groups activity stream.
2443 */
2444function bp_is_user_groups_activity() {
2445
2446        if ( ! bp_is_active( 'groups' ) ) {
2447                return false;
2448        }
2449
2450        $slug = ( bp_get_groups_slug() )
2451                ? bp_get_groups_slug()
2452                : 'groups';
2453
2454        if ( bp_is_user_activity() && bp_is_current_action( $slug ) ) {
2455                return true;
2456        }
2457
2458        return false;
2459}
2460
2461/**
2462 * Is the current page part of a user's extended profile?
2463 *
2464 * Eg http://example.com/members/joe/profile/ (or a subpage thereof).
2465 *
2466 * @since 1.1.0
2467 *
2468 * @return bool True if the current page is part of a user's extended profile.
2469 */
2470function bp_is_user_profile() {
2471        return (bool) ( bp_is_profile_component() || bp_is_current_component( 'profile' ) );
2472}
2473
2474/**
2475 * Is the current page part of a user's profile editing section?
2476 *
2477 * Eg http://example.com/members/joe/profile/edit/ (or a subpage thereof).
2478 *
2479 * @since 1.5.0
2480 *
2481 * @return bool True if the current page is a user's profile edit page.
2482 */
2483function bp_is_user_profile_edit() {
2484        return (bool) ( bp_is_profile_component() && bp_is_current_action( 'edit' ) );
2485}
2486
2487/**
2488 * Is the current page part of a user's profile avatar editing section?
2489 *
2490 * Eg http://example.com/members/joe/profile/change-avatar/ (or a subpage thereof).
2491 *
2492 * @since 1.5.0
2493 *
2494 * @return bool True if the current page is the user's avatar edit page.
2495 */
2496function bp_is_user_change_avatar() {
2497        return (bool) ( bp_is_profile_component() && bp_is_current_action( 'change-avatar' ) );
2498}
2499
2500/**
2501 * Is the current page the a user's change cover image profile page?
2502 *
2503 * Eg http://example.com/members/joe/profile/change-cover-image/ (or a subpage thereof).
2504 *
2505 * @since 2.4.0
2506 *
2507 * @return bool True if the current page is a user's profile edit cover image page.
2508 */
2509function bp_is_user_change_cover_image() {
2510        return (bool) ( bp_is_profile_component() && bp_is_current_action( 'change-cover-image' ) );
2511}
2512
2513/**
2514 * Is the current page part of a user's Groups page?
2515 *
2516 * Eg http://example.com/members/joe/groups/ (or a subpage thereof).
2517 *
2518 * @since 1.1.0
2519 *
2520 * @return bool True if the current page is a user's Groups page.
2521 */
2522function bp_is_user_groups() {
2523        return (bool) ( bp_is_user() && bp_is_groups_component() );
2524}
2525
2526/**
2527 * Is the current page part of a user's Blogs page?
2528 *
2529 * Eg http://example.com/members/joe/blogs/ (or a subpage thereof).
2530 *
2531 * @since 1.1.0
2532 *
2533 * @return bool True if the current page is a user's Blogs page.
2534 */
2535function bp_is_user_blogs() {
2536        return (bool) ( bp_is_user() && bp_is_blogs_component() );
2537}
2538
2539/**
2540 * Is the current page a user's Recent Blog Posts page?
2541 *
2542 * Eg http://example.com/members/joe/blogs/recent-posts/.
2543 *
2544 * @since 1.1.0
2545 *
2546 * @return bool True if the current page is a user's Recent Blog Posts page.
2547 */
2548function bp_is_user_recent_posts() {
2549        return (bool) ( bp_is_user_blogs() && bp_is_current_action( 'recent-posts' ) );
2550}
2551
2552/**
2553 * Is the current page a user's Recent Blog Comments page?
2554 *
2555 * Eg http://example.com/members/joe/blogs/recent-comments/.
2556 *
2557 * @since 1.1.0
2558 *
2559 * @return bool True if the current page is a user's Recent Blog Comments page.
2560 */
2561function bp_is_user_recent_commments() {
2562        return (bool) ( bp_is_user_blogs() && bp_is_current_action( 'recent-comments' ) );
2563}
2564
2565/**
2566 * Is the current page a user's Friends page?
2567 *
2568 * Eg http://example.com/members/joe/blogs/friends/ (or a subpage thereof).
2569 *
2570 * @since 1.1.0
2571 *
2572 * @return bool True if the current page is a user's Friends page.
2573 */
2574function bp_is_user_friends() {
2575        return (bool) ( bp_is_user() && bp_is_friends_component() );
2576}
2577
2578/**
2579 * Is the current page a user's Friend Requests page?
2580 *
2581 * Eg http://example.com/members/joe/friends/requests/.
2582 *
2583 * @since 1.5.0
2584 *
2585 * @return bool True if the current page is a user's Friends Requests page.
2586 */
2587function bp_is_user_friend_requests() {
2588        return (bool) ( bp_is_user_friends() && bp_is_current_action( 'requests' ) );
2589}
2590
2591/**
2592 * Is this a user's notifications page?
2593 *
2594 * Eg http://example.com/members/joe/notifications/ (or a subpage thereof).
2595 *
2596 * @since 1.9.0
2597 *
2598 * @return bool True if the current page is a user's Notifications page.
2599 */
2600function bp_is_user_notifications() {
2601        return (bool) ( bp_is_user() && bp_is_notifications_component() );
2602}
2603
2604/**
2605 * Is this a user's settings page?
2606 *
2607 * Eg http://example.com/members/joe/settings/ (or a subpage thereof).
2608 *
2609 * @since 1.5.0
2610 *
2611 * @return bool True if the current page is a user's Settings page.
2612 */
2613function bp_is_user_settings() {
2614        return (bool) ( bp_is_user() && bp_is_settings_component() );
2615}
2616
2617/**
2618 * Is this a user's General Settings page?
2619 *
2620 * Eg http://example.com/members/joe/settings/general/.
2621 *
2622 * @since 1.5.0
2623 *
2624 * @return bool True if the current page is a user's General Settings page.
2625 */
2626function bp_is_user_settings_general() {
2627        return (bool) ( bp_is_user_settings() && bp_is_current_action( 'general' ) );
2628}
2629
2630/**
2631 * Is this a user's Notification Settings page?
2632 *
2633 * Eg http://example.com/members/joe/settings/notifications/.
2634 *
2635 * @since 1.5.0
2636 *
2637 * @return bool True if the current page is a user's Notification Settings page.
2638 */
2639function bp_is_user_settings_notifications() {
2640        return (bool) ( bp_is_user_settings() && bp_is_current_action( 'notifications' ) );
2641}
2642
2643/**
2644 * Is this a user's Account Deletion page?
2645 *
2646 * Eg http://example.com/members/joe/settings/delete-account/.
2647 *
2648 * @since 1.5.0
2649 *
2650 * @return bool True if the current page is a user's Delete Account page.
2651 */
2652function bp_is_user_settings_account_delete() {
2653        return (bool) ( bp_is_user_settings() && bp_is_current_action( 'delete-account' ) );
2654}
2655
2656/**
2657 * Is this a user's profile settings?
2658 *
2659 * Eg http://example.com/members/joe/settings/profile/.
2660 *
2661 * @since 2.0.0
2662 *
2663 * @return bool True if the current page is a user's Profile Settings page.
2664 */
2665function bp_is_user_settings_profile() {
2666        return (bool) ( bp_is_user_settings() && bp_is_current_action( 'profile' ) );
2667}
2668
2669/**
2670 * Is the current page a user's community invitations page?
2671 *
2672 * Eg http://example.com/members/cassie/invitations/ (or a subpage thereof).
2673 *
2674 * @since 8.0.0
2675 *
2676 * @return bool True if the current page is a user's community invitations page.
2677 */
2678function bp_is_user_members_invitations() {
2679        return (bool) ( bp_is_user() && bp_is_members_invitations_screen() );
2680}
2681
2682/**
2683 * Is the current page a user's List Invites page?
2684 *
2685 * Eg http://example.com/members/cassie/invitations/list-invites/.
2686 *
2687 * @since 8.0.0
2688 *
2689 * @return bool True if the current page is a user's List Invites page.
2690 */
2691function bp_is_user_members_invitations_list() {
2692        return (bool) ( bp_is_user_members_invitations() && bp_is_current_action( 'list-invites' ) );
2693}
2694
2695/**
2696 * Is the current page a user's Send Invites page?
2697 *
2698 * Eg http://example.com/members/cassie/invitations/send-invites/.
2699 *
2700 * @since 8.0.0
2701 *
2702 * @return bool True if the current page is a user's Send Invites page.
2703 */
2704function bp_is_user_members_invitations_send_screen() {
2705        return (bool) ( bp_is_user_members_invitations() && bp_is_current_action( 'send-invites' ) );
2706}
2707
2708/** Groups ********************************************************************/
2709
2710/**
2711 * Is the current page the groups directory?
2712 *
2713 * @since 2.0.0
2714 *
2715 * @return bool True if the current page is the groups directory.
2716 */
2717function bp_is_groups_directory() {
2718        if ( bp_is_groups_component() && ! bp_is_group() && ( ! bp_current_action() || ( bp_action_variable() && bp_is_current_action( bp_get_groups_group_type_base() ) ) ) ) {
2719                return true;
2720        }
2721
2722        return false;
2723}
2724
2725/**
2726 * Does the current page belong to a single group?
2727 *
2728 * Will return true for any subpage of a single group.
2729 *
2730 * @since 1.2.0
2731 *
2732 * @return bool True if the current page is part of a single group.
2733 */
2734function bp_is_group() {
2735        $retval = bp_is_active( 'groups' );
2736
2737        if ( ! empty( $retval ) ) {
2738                $retval = bp_is_groups_component() && groups_get_current_group();
2739        }
2740
2741        return (bool) $retval;
2742}
2743
2744/**
2745 * Is the current page a single group's home page?
2746 *
2747 * URL will vary depending on which group tab is set to be the "home". By
2748 * default, it's the group's recent activity.
2749 *
2750 * @since 1.1.0
2751 *
2752 * @return bool True if the current page is a single group's home page.
2753 */
2754function bp_is_group_home() {
2755        if ( bp_is_single_item() && bp_is_groups_component() && ( ! bp_current_action() || bp_is_current_action( 'home' ) ) ) {
2756                return true;
2757        }
2758
2759        return false;
2760}
2761
2762/**
2763 * Is the current page part of the group creation process?
2764 *
2765 * @since 1.1.0
2766 *
2767 * @return bool True if the current page is part of the group creation process.
2768 */
2769function bp_is_group_create() {
2770        return (bool) ( bp_is_groups_component() && bp_is_current_action( 'create' ) );
2771}
2772
2773/**
2774 * Is the current page part of a single group's admin screens?
2775 *
2776 * Eg http://example.com/groups/mygroup/admin/settings/.
2777 *
2778 * @since 1.1.0
2779 *
2780 * @return bool True if the current page is part of a single group's admin.
2781 */
2782function bp_is_group_admin_page() {
2783        return (bool) ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'admin' ) );
2784}
2785
2786/**
2787 * Is the current page a group's activity page?
2788 *
2789 * @since 1.2.1
2790 *
2791 * @return bool True if the current page is a group's activity page.
2792 */
2793function bp_is_group_activity() {
2794        $retval = false;
2795
2796        if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'activity' ) ) {
2797                $retval = true;
2798        }
2799
2800        if ( bp_is_group_home() && bp_is_active( 'activity' ) && ! bp_is_group_custom_front() ) {
2801                $retval = true;
2802        }
2803
2804        return $retval;
2805}
2806
2807/**
2808 * Is the current page a group forum topic?
2809 *
2810 * @since 1.1.0
2811 * @since 3.0.0 Required for bbPress 2 integration.
2812 *
2813 * @return bool True if the current page is part of a group forum topic.
2814 */
2815function bp_is_group_forum_topic() {
2816        return (bool) ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'forum' ) && bp_is_action_variable( 'topic', 0 ) );
2817}
2818
2819/**
2820 * Is the current page a group forum topic edit page?
2821 *
2822 * @since 1.2.0
2823 * @since 3.0.0 Required for bbPress 2 integration.
2824 *
2825 * @return bool True if the current page is part of a group forum topic edit page.
2826 */
2827function bp_is_group_forum_topic_edit() {
2828        return (bool) ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'forum' ) && bp_is_action_variable( 'topic', 0 ) && bp_is_action_variable( 'edit', 2 ) );
2829}
2830
2831/**
2832 * Is the current page a group's Members page?
2833 *
2834 * Eg http://example.com/groups/mygroup/members/.
2835 *
2836 * @since 1.1.0
2837 *
2838 * @return bool True if the current page is part of a group's Members page.
2839 */
2840function bp_is_group_members() {
2841        $retval = false;
2842
2843        if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'members' ) ) {
2844                $retval = true;
2845        }
2846
2847        if ( bp_is_group_home() && ! bp_is_active( 'activity' ) && ! bp_is_group_custom_front() ) {
2848                $retval = true;
2849        }
2850
2851        return $retval;
2852}
2853
2854/**
2855 * Is the current page a group's Invites page?
2856 *
2857 * Eg http://example.com/groups/mygroup/send-invites/.
2858 *
2859 * @since 1.1.0
2860 *
2861 * @return bool True if the current page is a group's Send Invites page.
2862 */
2863function bp_is_group_invites() {
2864        return (bool) ( bp_is_groups_component() && bp_is_current_action( 'send-invites' ) );
2865}
2866
2867/**
2868 * Is the current page a group's Request Membership page?
2869 *
2870 * Eg http://example.com/groups/mygroup/request-membership/.
2871 *
2872 * @since 1.2.0
2873 *
2874 * @return bool True if the current page is a group's Request Membership page.
2875 */
2876function bp_is_group_membership_request() {
2877        return (bool) ( bp_is_groups_component() && bp_is_current_action( 'request-membership' ) );
2878}
2879
2880/**
2881 * Is the current page a leave group attempt?
2882 *
2883 * @since 1.1.0
2884 *
2885 * @return bool True if the current page is a Leave Group attempt.
2886 */
2887function bp_is_group_leave() {
2888        return (bool) ( bp_is_groups_component() && bp_is_single_item() && bp_is_current_action( 'leave-group' ) );
2889}
2890
2891/**
2892 * Is the current page part of a single group?
2893 *
2894 * Not currently used by BuddyPress.
2895 *
2896 * @todo How is this functionally different from bp_is_group()?
2897 *
2898 * @return bool True if the current page is part of a single group.
2899 */
2900function bp_is_group_single() {
2901        return (bool) ( bp_is_groups_component() && bp_is_single_item() );
2902}
2903
2904/**
2905 * Is the current group page a custom front?
2906 *
2907 * @since 2.4.0
2908 *
2909 * @return bool True if the current group page is a custom front.
2910 */
2911function bp_is_group_custom_front() {
2912        $bp = buddypress();
2913        return (bool) bp_is_group_home() && ! empty( $bp->groups->current_group->front_template );
2914}
2915
2916/**
2917 * Is the current page the Create a Blog page?
2918 *
2919 * Eg http://example.com/sites/create/.
2920 *
2921 * @since 1.1.0
2922 *
2923 * @return bool True if the current page is the Create a Blog page.
2924 */
2925function bp_is_create_blog() {
2926        return (bool) ( bp_is_blogs_component() && bp_is_current_action( 'create' ) );
2927}
2928
2929/**
2930 * Is the current page the blogs directory ?
2931 *
2932 * @since 2.0.0
2933 *
2934 * @return bool True if the current page is the blogs directory.
2935 */
2936function bp_is_blogs_directory() {
2937        if ( is_multisite() && bp_is_blogs_component() && ! bp_current_action() ) {
2938                return true;
2939        }
2940
2941        return false;
2942}
2943
2944/** Messages ******************************************************************/
2945
2946/**
2947 * Is the current page part of a user's Messages pages?
2948 *
2949 * Eg http://example.com/members/joe/messages/ (or a subpage thereof).
2950 *
2951 * @since 1.2.0
2952 *
2953 * @return bool True if the current page is part of a user's Messages pages.
2954 */
2955function bp_is_user_messages() {
2956        return (bool) ( bp_is_user() && bp_is_messages_component() );
2957}
2958
2959/**
2960 * Is the current page a user's Messages Inbox?
2961 *
2962 * Eg http://example.com/members/joe/messages/inbox/.
2963 *
2964 * @since 1.1.0
2965 *
2966 * @return bool True if the current page is a user's Messages Inbox.
2967 */
2968function bp_is_messages_inbox() {
2969        if ( bp_is_user_messages() && ( ! bp_current_action() || bp_is_current_action( 'inbox' ) ) ) {
2970                return true;
2971        }
2972
2973        return false;
2974}
2975
2976/**
2977 * Is the current page a user's Messages Sentbox?
2978 *
2979 * Eg http://example.com/members/joe/messages/sentbox/.
2980 *
2981 * @since 1.1.0
2982 *
2983 * @return bool True if the current page is a user's Messages Sentbox.
2984 */
2985function bp_is_messages_sentbox() {
2986        return (bool) ( bp_is_user_messages() && bp_is_current_action( 'sentbox' ) );
2987}
2988
2989/**
2990 * Is the current page a user's Messages Compose screen??
2991 *
2992 * Eg http://example.com/members/joe/messages/compose/.
2993 *
2994 * @since 1.1.0
2995 *
2996 * @return bool True if the current page is a user's Messages Compose screen.
2997 */
2998function bp_is_messages_compose_screen() {
2999        return (bool) ( bp_is_user_messages() && bp_is_current_action( 'compose' ) );
3000}
3001
3002/**
3003 * Is the current page the Notices screen?
3004 *
3005 * Eg http://example.com/members/joe/messages/notices/.
3006 *
3007 * @since 1.1.0
3008 *
3009 * @return bool True if the current page is the Notices screen.
3010 */
3011function bp_is_notices() {
3012        return (bool) ( bp_is_user_messages() && bp_is_current_action( 'notices' ) );
3013}
3014
3015/**
3016 * Is the current page a single Messages conversation thread?
3017 *
3018 * @since 1.6.0
3019 *
3020 * @return bool True if the current page a single Messages conversation thread?
3021 */
3022function bp_is_messages_conversation() {
3023        return (bool) ( bp_is_user_messages() && ( bp_is_current_action( 'view' ) ) );
3024}
3025
3026/**
3027 * Not currently used by BuddyPress.
3028 *
3029 * @param string $component Current component to check for.
3030 * @param string $callback  Callback to invoke.
3031 * @return bool
3032 */
3033function bp_is_single( $component, $callback ) {
3034        return (bool) ( bp_is_current_component( $component ) && ( true === call_user_func( $callback ) ) );
3035}
3036
3037/** Registration **************************************************************/
3038
3039/**
3040 * Is the current page the Activate page?
3041 *
3042 * Eg http://example.com/activate/.
3043 *
3044 * @since 1.1.0
3045 *
3046 * @return bool True if the current page is the Activate page.
3047 */
3048function bp_is_activation_page() {
3049        return (bool) bp_is_current_component( 'activate' );
3050}
3051
3052/**
3053 * Is the current page the Register page?
3054 *
3055 * Eg http://example.com/register/.
3056 *
3057 * @since 1.1.0
3058 *
3059 * @return bool True if the current page is the Register page.
3060 */
3061function bp_is_register_page() {
3062        return (bool) bp_is_current_component( 'register' );
3063}
3064
3065/**
3066 * Get the title parts of the BuddyPress displayed page
3067 *
3068 * @since 2.4.3
3069 *
3070 * @param string $seplocation Location for the separator.
3071 * @return array the title parts
3072 */
3073function bp_get_title_parts( $seplocation = 'right' ) {
3074        $bp = buddypress();
3075
3076        // Defaults to an empty array.
3077        $bp_title_parts = array();
3078
3079        // If this is not a BP page, return the empty array.
3080        if ( bp_is_blog_page() ) {
3081                return $bp_title_parts;
3082        }
3083
3084        // If this is a 404, return the empty array.
3085        if ( is_404() ) {
3086                return $bp_title_parts;
3087        }
3088
3089        // If this is the front page of the site, return the empty array.
3090        if ( is_front_page() || is_home() ) {
3091                return $bp_title_parts;
3092        }
3093
3094        // Return the empty array if not a BuddyPress page.
3095        if ( ! is_buddypress() ) {
3096                return $bp_title_parts;
3097        }
3098
3099        // Now we can build the BP Title Parts.
3100        // Is there a displayed user, and do they have a name?
3101        $displayed_user_name = bp_get_displayed_user_fullname();
3102
3103        // Displayed user.
3104        if ( ! empty( $displayed_user_name ) && ! is_404() ) {
3105
3106                // Get the component's ID to try and get its name.
3107                $component_id = $component_name = bp_current_component();
3108
3109                // Set empty subnav name.
3110                $component_subnav_name = '';
3111
3112                if ( ! empty( $bp->members->nav ) ) {
3113                        $primary_nav_item = (array) $bp->members->nav->get_primary( array( 'slug' => $component_id ), false );
3114                        $primary_nav_item = reset( $primary_nav_item );
3115                }
3116
3117                // Use the component nav name.
3118                if ( ! empty( $primary_nav_item->name ) ) {
3119                        $component_name = _bp_strip_spans_from_title( $primary_nav_item->name );
3120
3121                // Fall back on the component ID.
3122                } elseif ( ! empty( $bp->{$component_id}->id ) ) {
3123                        $component_name = ucwords( $bp->{$component_id}->id );
3124                }
3125
3126                if ( ! empty( $bp->members->nav ) ) {
3127                        $secondary_nav_item = $bp->members->nav->get_secondary( array(
3128                                'parent_slug' => $component_id,
3129                                'slug'        => bp_current_action()
3130                        ), false );
3131
3132                        if ( $secondary_nav_item ) {
3133                                $secondary_nav_item = reset( $secondary_nav_item );
3134                        }
3135                }
3136
3137                // Append action name if we're on a member component sub-page.
3138                if ( ! empty( $secondary_nav_item->name ) && ! empty( $bp->canonical_stack['action'] ) ) {
3139                        $component_subnav_name = $secondary_nav_item->name;
3140                }
3141
3142                // If on the user profile's landing page, just use the fullname.
3143                if ( bp_is_current_component( $bp->default_component ) && ( bp_get_requested_url() === bp_displayed_user_domain() ) ) {
3144                        $bp_title_parts[] = $displayed_user_name;
3145
3146                // Use component name on member pages.
3147                } else {
3148                        $bp_title_parts = array_merge( $bp_title_parts, array_map( 'strip_tags', array(
3149                                $displayed_user_name,
3150                                $component_name,
3151                        ) ) );
3152
3153                        // If we have a subnav name, add it separately for localization.
3154                        if ( ! empty( $component_subnav_name ) ) {
3155                                $bp_title_parts[] = strip_tags( $component_subnav_name );
3156                        }
3157                }
3158
3159        // A single item from a component other than Members.
3160        } elseif ( bp_is_single_item() ) {
3161                $component_id = bp_current_component();
3162
3163                if ( ! empty( $bp->{$component_id}->nav ) ) {
3164                        $secondary_nav_item = $bp->{$component_id}->nav->get_secondary( array(
3165                                'parent_slug' => bp_current_item(),
3166                                'slug'        => bp_current_action()
3167                        ), false );
3168
3169                        if ( $secondary_nav_item ) {
3170                                $secondary_nav_item = reset( $secondary_nav_item );
3171                        }
3172                }
3173
3174                $single_item_subnav = '';
3175
3176                if ( ! empty( $secondary_nav_item->name ) ) {
3177                        $single_item_subnav = $secondary_nav_item->name;
3178                }
3179
3180                $bp_title_parts = array( $bp->bp_options_title, $single_item_subnav );
3181
3182        // An index or directory.
3183        } elseif ( bp_is_directory() ) {
3184                $current_component = bp_current_component();
3185
3186                // No current component (when does this happen?).
3187                $bp_title_parts = array( _x( 'Directory', 'component directory title', 'buddypress' ) );
3188
3189                if ( ! empty( $current_component ) ) {
3190                        $bp_title_parts = array( bp_get_directory_title( $current_component ) );
3191                }
3192
3193        // Sign up page.
3194        } elseif ( bp_is_register_page() ) {
3195                if ( bp_get_membership_requests_required() ) {
3196                        $bp_title_parts = array( __( 'Request Membership', 'buddypress' ) );
3197                } else {
3198                        $bp_title_parts = array( __( 'Create an Account', 'buddypress' ) );
3199                }
3200
3201        // Activation page.
3202        } elseif ( bp_is_activation_page() ) {
3203                $bp_title_parts = array( __( 'Activate Your Account', 'buddypress' ) );
3204
3205        // Group creation page.
3206        } elseif ( bp_is_group_create() ) {
3207                $bp_title_parts = array( __( 'Create a Group', 'buddypress' ) );
3208
3209        // Blog creation page.
3210        } elseif ( bp_is_create_blog() ) {
3211                $bp_title_parts = array( __( 'Create a Site', 'buddypress' ) );
3212        }
3213
3214        // Strip spans.
3215        $bp_title_parts = array_map( '_bp_strip_spans_from_title', $bp_title_parts );
3216
3217        // Sep on right, so reverse the order.
3218        if ( 'right' === $seplocation ) {
3219                $bp_title_parts = array_reverse( $bp_title_parts );
3220        }
3221
3222        /**
3223         * Filter BuddyPress title parts before joining.
3224         *
3225         * @since 2.4.3
3226         *
3227         * @param array $bp_title_parts Current BuddyPress title parts.
3228         * @return array
3229         */
3230        return (array) apply_filters( 'bp_get_title_parts', $bp_title_parts );
3231}
3232
3233/**
3234 * Customize the body class, according to the currently displayed BP content.
3235 *
3236 * @since 1.1.0
3237 */
3238function bp_the_body_class() {
3239        echo bp_get_the_body_class();
3240}
3241        /**
3242         * Customize the body class, according to the currently displayed BP content.
3243         *
3244         * Uses the above is_() functions to output a body class for each scenario.
3245         *
3246         * @since 1.1.0
3247         *
3248         * @param array      $wp_classes     The body classes coming from WP.
3249         * @param array|bool $custom_classes Classes that were passed to get_body_class().
3250         * @return array $classes The BP-adjusted body classes.
3251         */
3252        function bp_get_the_body_class( $wp_classes = array(), $custom_classes = false ) {
3253
3254                $bp_classes = array();
3255
3256                /* Pages *************************************************************/
3257
3258                if ( is_front_page() ) {
3259                        $bp_classes[] = 'home-page';
3260                }
3261
3262                if ( bp_is_directory() ) {
3263                        $bp_classes[] = 'directory';
3264                }
3265
3266                if ( bp_is_single_item() ) {
3267                        $bp_classes[] = 'single-item';
3268                }
3269
3270                /* Components ********************************************************/
3271
3272                if ( ! bp_is_blog_page() ) {
3273                        if ( bp_is_user_profile() )  {
3274                                $bp_classes[] = 'xprofile';
3275                        }
3276
3277                        if ( bp_is_activity_component() ) {
3278                                $bp_classes[] = 'activity';
3279                        }
3280
3281                        if ( bp_is_blogs_component() ) {
3282                                $bp_classes[] = 'blogs';
3283                        }
3284
3285                        if ( bp_is_messages_component() ) {
3286                                $bp_classes[] = 'messages';
3287                        }
3288
3289                        if ( bp_is_friends_component() ) {
3290                                $bp_classes[] = 'friends';
3291                        }
3292
3293                        if ( bp_is_groups_component() ) {
3294                                $bp_classes[] = 'groups';
3295                        }
3296
3297                        if ( bp_is_settings_component()  ) {
3298                                $bp_classes[] = 'settings';
3299                        }
3300                }
3301
3302                /* User **************************************************************/
3303
3304                if ( bp_is_user() ) {
3305                        $bp_classes[] = 'bp-user';
3306
3307                        // Add current user member types.
3308                        if ( $member_types = bp_get_member_type( bp_displayed_user_id(), false ) ) {
3309                                foreach( $member_types as $member_type ) {
3310                                        $bp_classes[] = sprintf( 'member-type-%s', esc_attr( $member_type ) );
3311                                }
3312                        }
3313                }
3314
3315                if ( ! bp_is_directory() ) {
3316                        if ( bp_is_user_blogs() ) {
3317                                $bp_classes[] = 'my-blogs';
3318                        }
3319
3320                        if ( bp_is_user_groups() ) {
3321                                $bp_classes[] = 'my-groups';
3322                        }
3323
3324                        if ( bp_is_user_activity() ) {
3325                                $bp_classes[] = 'my-activity';
3326                        }
3327                } else {
3328                        if ( bp_get_current_member_type() || ( bp_is_groups_directory() && bp_get_current_group_directory_type() ) ) {
3329                                $bp_classes[] = 'type';
3330                        }
3331                }
3332
3333                if ( bp_is_my_profile() ) {
3334                        $bp_classes[] = 'my-account';
3335                }
3336
3337                if ( bp_is_user_profile() ) {
3338                        $bp_classes[] = 'my-profile';
3339                }
3340
3341                if ( bp_is_user_friends() ) {
3342                        $bp_classes[] = 'my-friends';
3343                }
3344
3345                if ( bp_is_user_messages() ) {
3346                        $bp_classes[] = 'my-messages';
3347                }
3348
3349                if ( bp_is_user_recent_commments() ) {
3350                        $bp_classes[] = 'recent-comments';
3351                }
3352
3353                if ( bp_is_user_recent_posts() ) {
3354                        $bp_classes[] = 'recent-posts';
3355                }
3356
3357                if ( bp_is_user_change_avatar() ) {
3358                        $bp_classes[] = 'change-avatar';
3359                }
3360
3361                if ( bp_is_user_profile_edit() ) {
3362                        $bp_classes[] = 'profile-edit';
3363                }
3364
3365                if ( bp_is_user_friends_activity() ) {
3366                        $bp_classes[] = 'friends-activity';
3367                }
3368
3369                if ( bp_is_user_groups_activity() ) {
3370                        $bp_classes[] = 'groups-activity';
3371                }
3372
3373                /* Messages **********************************************************/
3374
3375                if ( bp_is_messages_inbox() ) {
3376                        $bp_classes[] = 'inbox';
3377                }
3378
3379                if ( bp_is_messages_sentbox() ) {
3380                        $bp_classes[] = 'sentbox';
3381                }
3382
3383                if ( bp_is_messages_compose_screen() ) {
3384                        $bp_classes[] = 'compose';
3385                }
3386
3387                if ( bp_is_notices() ) {
3388                        $bp_classes[] = 'notices';
3389                }
3390
3391                if ( bp_is_user_friend_requests() ) {
3392                        $bp_classes[] = 'friend-requests';
3393                }
3394
3395                if ( bp_is_create_blog() ) {
3396                        $bp_classes[] = 'create-blog';
3397                }
3398
3399                /* Groups ************************************************************/
3400
3401                if ( bp_is_group() ) {
3402                        $bp_classes[] = 'group-' . groups_get_current_group()->slug;
3403
3404                        // Add current group types.
3405                        if ( $group_types = bp_groups_get_group_type( bp_get_current_group_id(), false ) ) {
3406                                foreach ( $group_types as $group_type ) {
3407                                        $bp_classes[] = sprintf( 'group-type-%s', esc_attr( $group_type ) );
3408                                }
3409                        }
3410                }
3411
3412                if ( bp_is_group_leave() ) {
3413                        $bp_classes[] = 'leave-group';
3414                }
3415
3416                if ( bp_is_group_invites() ) {
3417                        $bp_classes[] = 'group-invites';
3418                }
3419
3420                if ( bp_is_group_members() ) {
3421                        $bp_classes[] = 'group-members';
3422                }
3423
3424                if ( bp_is_group_admin_page() ) {
3425                        $bp_classes[] = 'group-admin';
3426                        $bp_classes[] = bp_get_group_current_admin_tab();
3427                }
3428
3429                if ( bp_is_group_create() ) {
3430                        $bp_classes[] = 'group-create';
3431                        $bp_classes[] = bp_get_groups_current_create_step();
3432                }
3433
3434                if ( bp_is_group_home() ) {
3435                        $bp_classes[] = 'group-home';
3436                }
3437
3438                if ( bp_is_single_activity() ) {
3439                        $bp_classes[] = 'activity-permalink';
3440                }
3441
3442                /* Registration ******************************************************/
3443
3444                if ( bp_is_register_page() ) {
3445                        $bp_classes[] = 'registration';
3446                }
3447
3448                if ( bp_is_activation_page() ) {
3449                        $bp_classes[] = 'activation';
3450                }
3451
3452                /* Current Component & Action ****************************************/
3453
3454                if ( ! bp_is_blog_page() ) {
3455                        $bp_classes[] = bp_current_component();
3456                        $bp_classes[] = bp_current_action();
3457                }
3458
3459                /* Clean up ***********************************************************/
3460
3461                // Add BuddyPress class if we are within a BuddyPress page.
3462                if ( ! bp_is_blog_page() ) {
3463                        $bp_classes[] = 'buddypress';
3464                }
3465
3466                // Add the theme name/id to the body classes
3467                $bp_classes[] = 'bp-' . bp_get_theme_compat_id();
3468
3469                // Merge WP classes with BuddyPress classes and remove any duplicates.
3470                $classes = array_unique( array_merge( (array) $bp_classes, (array) $wp_classes ) );
3471
3472                /**
3473                 * Filters the BuddyPress classes to be added to body_class()
3474                 *
3475                 * @since 1.1.0
3476                 *
3477                 * @param array $classes        Array of body classes to add.
3478                 * @param array $bp_classes     Array of BuddyPress-based classes.
3479                 * @param array $wp_classes     Array of WordPress-based classes.
3480                 * @param array $custom_classes Array of classes that were passed to get_body_class().
3481                 */
3482                return apply_filters( 'bp_get_the_body_class', $classes, $bp_classes, $wp_classes, $custom_classes );
3483        }
3484        add_filter( 'body_class', 'bp_get_the_body_class', 10, 2 );
3485
3486/**
3487 * Customizes the post CSS class according to BuddyPress content.
3488 *
3489 * Hooked to the 'post_class' filter.
3490 *
3491 * @since 2.1.0
3492 *
3493 * @param array $wp_classes The post classes coming from WordPress.
3494 * @return array
3495 */
3496function bp_get_the_post_class( $wp_classes = array() ) {
3497        // Don't do anything if we're not on a BP page.
3498        if ( ! is_buddypress() ) {
3499                return $wp_classes;
3500        }
3501
3502        $bp_classes = array();
3503
3504        if ( bp_is_user() || bp_is_single_activity() ) {
3505                $bp_classes[] = 'bp_members';
3506
3507        } elseif ( bp_is_group() ) {
3508                $bp_classes[] = 'bp_group';
3509
3510        } elseif ( bp_is_activity_component() ) {
3511                $bp_classes[] = 'bp_activity';
3512
3513        } elseif ( bp_is_blogs_component() ) {
3514                $bp_classes[] = 'bp_blogs';
3515
3516        } elseif ( bp_is_register_page() ) {
3517                $bp_classes[] = 'bp_register';
3518
3519        } elseif ( bp_is_activation_page() ) {
3520                $bp_classes[] = 'bp_activate';
3521        }
3522
3523        if ( empty( $bp_classes ) ) {
3524                return $wp_classes;
3525        }
3526
3527        // Emulate post type css class.
3528        foreach ( $bp_classes as $bp_class ) {
3529                $bp_classes[] = "type-{$bp_class}";
3530        }
3531
3532        // Okay let's merge!
3533        return array_unique( array_merge( $bp_classes, $wp_classes ) );
3534}
3535add_filter( 'post_class', 'bp_get_the_post_class' );
3536
3537/**
3538 * Sort BuddyPress nav menu items by their position property.
3539 *
3540 * This is an internal convenience function and it will probably be removed in
3541 * a later release. Do not use.
3542 *
3543 * @access private
3544 * @since 1.7.0
3545 *
3546 * @param array $a First item.
3547 * @param array $b Second item.
3548 * @return int Returns an integer less than, equal to, or greater than zero if
3549 *             the first argument is considered to be respectively less than,
3550 *             equal to, or greater than the second.
3551 */
3552function _bp_nav_menu_sort( $a, $b ) {
3553        if ( $a['position'] == $b['position'] ) {
3554                return 0;
3555        } elseif ( $a['position'] < $b['position'] ) {
3556                return -1;
3557        } else {
3558                return 1;
3559        }
3560}
3561
3562/**
3563 * Get the items registered in the primary and secondary BuddyPress navigation menus.
3564 *
3565 * @since 1.7.0
3566 * @since 2.6.0 Introduced the `$component` parameter.
3567 *
3568 * @param string $component Optional. Component whose nav items are being fetched.
3569 * @return array A multidimensional array of all navigation items.
3570 */
3571function bp_get_nav_menu_items( $component = 'members' ) {
3572        $bp    = buddypress();
3573        $menus = array();
3574
3575        if ( ! isset( $bp->{$component}->nav ) ) {
3576                return $menus;
3577        }
3578
3579        // Get the item nav and build the menus.
3580        foreach ( $bp->{$component}->nav->get_item_nav() as $nav_menu ) {
3581                // Get the correct menu link. See https://buddypress.trac.wordpress.org/ticket/4624.
3582                $link = bp_loggedin_user_domain() ? str_replace( bp_loggedin_user_domain(), bp_displayed_user_domain(), $nav_menu->link ) : trailingslashit( bp_displayed_user_domain() . $nav_menu->link );
3583
3584                // Add this menu.
3585                $menu         = new stdClass;
3586                $menu->class  = array( 'menu-parent' );
3587                $menu->css_id = $nav_menu->css_id;
3588                $menu->link   = $link;
3589                $menu->name   = $nav_menu->name;
3590                $menu->parent = 0;
3591
3592                if ( ! empty( $nav_menu->children ) ) {
3593                        $submenus = array();
3594
3595                        foreach( $nav_menu->children as $sub_menu ) {
3596                                $submenu = new stdClass;
3597                                $submenu->class  = array( 'menu-child' );
3598                                $submenu->css_id = $sub_menu->css_id;
3599                                $submenu->link   = $sub_menu->link;
3600                                $submenu->name   = $sub_menu->name;
3601                                $submenu->parent = $nav_menu->slug;
3602
3603                                // If we're viewing this item's screen, record that we need to mark its parent menu to be selected.
3604                                if ( bp_is_current_action( $sub_menu->slug ) && bp_is_current_component( $nav_menu->slug ) ) {
3605                                        $menu->class[]    = 'current-menu-parent';
3606                                        $submenu->class[] = 'current-menu-item';
3607                                }
3608
3609                                $submenus[] = $submenu;
3610                        }
3611                }
3612
3613                $menus[] = $menu;
3614
3615                if ( ! empty( $submenus ) ) {
3616                        $menus = array_merge( $menus, $submenus );
3617                }
3618        }
3619
3620        /**
3621         * Filters the items registered in the primary and secondary BuddyPress navigation menus.
3622         *
3623         * @since 1.7.0
3624         *
3625         * @param array $menus Array of items registered in the primary and secondary BuddyPress navigation.
3626         */
3627        return apply_filters( 'bp_get_nav_menu_items', $menus );
3628}
3629
3630/**
3631 * Display a navigation menu.
3632 *
3633 * @since 1.7.0
3634 *
3635 * @param string|array $args {
3636 *     An array of optional arguments.
3637 *
3638 *     @type string $after           Text after the link text. Default: ''.
3639 *     @type string $before          Text before the link text. Default: ''.
3640 *     @type string $container       The name of the element to wrap the navigation
3641 *                                   with. 'div' or 'nav'. Default: 'div'.
3642 *     @type string $container_class The class that is applied to the container.
3643 *                                   Default: 'menu-bp-container'.
3644 *     @type string $container_id    The ID that is applied to the container.
3645 *                                   Default: ''.
3646 *     @type int    $depth           How many levels of the hierarchy are to be included.
3647 *                                   0 means all. Default: 0.
3648 *     @type bool   $echo            True to echo the menu, false to return it.
3649 *                                   Default: true.
3650 *     @type bool   $fallback_cb     If the menu doesn't exist, should a callback
3651 *                                   function be fired? Default: false (no fallback).
3652 *     @type string $items_wrap      How the list items should be wrapped. Should be
3653 *                                   in the form of a printf()-friendly string, using numbered
3654 *                                   placeholders. Default: '<ul id="%1$s" class="%2$s">%3$s</ul>'.
3655 *     @type string $link_after      Text after the link. Default: ''.
3656 *     @type string $link_before     Text before the link. Default: ''.
3657 *     @type string $menu_class      CSS class to use for the <ul> element which
3658 *                                   forms the menu. Default: 'menu'.
3659 *     @type string $menu_id         The ID that is applied to the <ul> element which
3660 *                                   forms the menu. Default: 'menu-bp', incremented.
3661 *     @type string $walker          Allows a custom walker class to be specified.
3662 *                                   Default: 'BP_Walker_Nav_Menu'.
3663 * }
3664 * @return string|null If $echo is false, returns a string containing the nav
3665 *                     menu markup.
3666 */
3667function bp_nav_menu( $args = array() ) {
3668        static $menu_id_slugs = array();
3669
3670        $defaults = array(
3671                'after'           => '',
3672                'before'          => '',
3673                'container'       => 'div',
3674                'container_class' => '',
3675                'container_id'    => '',
3676                'depth'           => 0,
3677                'echo'            => true,
3678                'fallback_cb'     => false,
3679                'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>',
3680                'link_after'      => '',
3681                'link_before'     => '',
3682                'menu_class'      => 'menu',
3683                'menu_id'         => '',
3684                'walker'          => '',
3685        );
3686
3687        $args = bp_parse_args(
3688                $args,
3689                $defaults
3690        );
3691
3692        /**
3693         * Filters the parsed bp_nav_menu arguments.
3694         *
3695         * @since 1.7.0
3696         *
3697         * @param array $args Array of parsed arguments.
3698         */
3699        $args = apply_filters( 'bp_nav_menu_args', $args );
3700        $args = (object) $args;
3701
3702        $items = $nav_menu = '';
3703        $show_container = false;
3704
3705        // Create custom walker if one wasn't set.
3706        if ( empty( $args->walker ) ) {
3707                $args->walker = new BP_Walker_Nav_Menu;
3708        }
3709
3710        // Sanitize values for class and ID.
3711        $args->container_class = sanitize_html_class( $args->container_class );
3712        $args->container_id    = sanitize_html_class( $args->container_id );
3713
3714        // Whether to wrap the ul, and what to wrap it with.
3715        if ( $args->container ) {
3716
3717                /**
3718                 * Filters the allowed tags for the wp_nav_menu_container.
3719                 *
3720                 * @since 1.7.0
3721                 *
3722                 * @param array $value Array of allowed tags. Default 'div' and 'nav'.
3723                 */
3724                $allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav', ) );
3725
3726                if ( in_array( $args->container, $allowed_tags ) ) {
3727                        $show_container = true;
3728
3729                        $class     = $args->container_class ? ' class="' . esc_attr( $args->container_class ) . '"' : ' class="menu-bp-container"';
3730                        $id        = $args->container_id    ? ' id="' . esc_attr( $args->container_id ) . '"'       : '';
3731                        $nav_menu .= '<' . $args->container . $id . $class . '>';
3732                }
3733        }
3734
3735        /**
3736         * Filters the BuddyPress menu objects.
3737         *
3738         * @since 1.7.0
3739         *
3740         * @param array $value Array of nav menu objects.
3741         * @param array $args  Array of arguments for the menu.
3742         */
3743        $menu_items = apply_filters( 'bp_nav_menu_objects', bp_get_nav_menu_items(), $args );
3744        $items      = walk_nav_menu_tree( $menu_items, $args->depth, $args );
3745        unset( $menu_items );
3746
3747        // Set the ID that is applied to the ul element which forms the menu.
3748        if ( ! empty( $args->menu_id ) ) {
3749                $wrap_id = $args->menu_id;
3750
3751        } else {
3752                $wrap_id = 'menu-bp';
3753
3754                // If a specific ID wasn't requested, and there are multiple menus on the same screen, make sure the autogenerated ID is unique.
3755                while ( in_array( $wrap_id, $menu_id_slugs ) ) {
3756                        if ( preg_match( '#-(\d+)$#', $wrap_id, $matches ) ) {
3757                                $wrap_id = preg_replace('#-(\d+)$#', '-' . ++$matches[1], $wrap_id );
3758                        } else {
3759                                $wrap_id = $wrap_id . '-1';
3760                        }
3761                }
3762        }
3763        $menu_id_slugs[] = $wrap_id;
3764
3765        /**
3766         * Filters the BuddyPress menu items.
3767         *
3768         * Allow plugins to hook into the menu to add their own <li>'s
3769         *
3770         * @since 1.7.0
3771         *
3772         * @param array $items Array of nav menu items.
3773         * @param array $args  Array of arguments for the menu.
3774         */
3775        $items = apply_filters( 'bp_nav_menu_items', $items, $args );
3776
3777        // Build the output.
3778        $wrap_class  = $args->menu_class ? $args->menu_class : '';
3779        $nav_menu   .= sprintf( $args->items_wrap, esc_attr( $wrap_id ), esc_attr( $wrap_class ), $items );
3780        unset( $items );
3781
3782        // If we've wrapped the ul, close it.
3783        if ( ! empty( $show_container ) ) {
3784                $nav_menu .= '</' . $args->container . '>';
3785        }
3786
3787        /**
3788         * Filters the final BuddyPress menu output.
3789         *
3790         * @since 1.7.0
3791         *
3792         * @param string $nav_menu Final nav menu output.
3793         * @param array  $args     Array of arguments for the menu.
3794         */
3795        $nav_menu = apply_filters( 'bp_nav_menu', $nav_menu, $args );
3796
3797        if ( ! empty( $args->echo ) ) {
3798                echo $nav_menu;
3799        } else {
3800                return $nav_menu;
3801        }
3802}
3803
3804/**
3805 * Prints the Recipient Salutation.
3806 *
3807 * @since 2.5.0
3808 *
3809 * @param array $settings Email Settings.
3810 */
3811function bp_email_the_salutation( $settings = array() ) {
3812        echo bp_email_get_salutation( $settings );
3813}
3814
3815        /**
3816         * Gets the Recipient Salutation.
3817         *
3818         * @since 2.5.0
3819         * @since 8.0.0 Checks current BP Email type schema to eventually use the unnamed salutation.
3820         *
3821         * @param array $settings Email Settings.
3822         * @return string The Recipient Salutation.
3823         */
3824        function bp_email_get_salutation( $settings = array() ) {
3825                $email_type = bp_email_get_type();
3826                $salutation  = '';
3827
3828                if ( $email_type ) {
3829                        $types_schema = bp_email_get_type_schema( 'named_salutation' );
3830
3831                        if ( isset( $types_schema[ $email_type ] ) && false === $types_schema[ $email_type ] ) {
3832                                /**
3833                                 * Filters The Recipient Unnamed Salutation inside the Email Template.
3834                                 *
3835                                 * @since 8.0.0
3836                                 *
3837                                 * @param string $value    The Recipient Salutation.
3838                                 * @param array  $settings Email Settings.
3839                                 */
3840                                $salutation = apply_filters(
3841                                        'bp_email_get_unnamed_salutation',
3842                                        _x( 'Hi,', 'Unnamed recipient salutation', 'buddypress' ),
3843                                        $settings
3844                                );
3845                        }
3846                }
3847
3848                // Named salutations are default.
3849                if ( ! $salutation ) {
3850                        $token = '{{recipient.name}}';
3851
3852                        /**
3853                         * Filters The Recipient Named Salutation inside the Email Template.
3854                         *
3855                         * @since 2.5.0
3856                         *
3857                         * @param string $value    The Recipient Salutation.
3858                         * @param array  $settings Email Settings.
3859                         * @param string $token    The Recipient token.
3860                         */
3861                        $salutation = apply_filters(
3862                                'bp_email_get_salutation',
3863                                sprintf(
3864                                        /* translators: %s: the email token for the recipient name */
3865                                        _x( 'Hi %s,', 'Named recipient salutation', 'buddypress' ),
3866                                        $token
3867                                ),
3868                                $settings,
3869                                $token
3870                        );
3871                }
3872
3873                return $salutation;
3874        }
3875
3876/**
3877 * Checks if a Widget/Block is active.
3878 *
3879 * @since 9.0.0
3880 *
3881 * @param string $block_name     The Block name to check (eg: 'bp/sitewide-notices'). Optional.
3882 * @param string $widget_id_base The Widget ID base to check (eg: 'bp_messages_sitewide_notices_widget' ). Optional.
3883 * @return boolean True if the Widget/Block is active. False otherwise.
3884 */
3885function bp_is_widget_block_active( $block_name = '', $widget_id_base = '' ) {
3886        $is_active = array(
3887                'widget' => false,
3888                'block'  => false,
3889        );
3890
3891        if ( $block_name && bp_is_running_wp( '5.8.0', '>=' ) ) {
3892                $widget_blocks = get_option( 'widget_block', array() );
3893                $sidebars      = wp_get_sidebars_widgets();
3894
3895                if ( ! $widget_blocks || ! $sidebars ) {
3896                        return false;
3897                }
3898
3899                // Neutralize inactive sidebar.
3900                unset( $sidebars['wp_inactive_widgets'] );
3901
3902                $widgets_content = '';
3903                foreach ( $widget_blocks as $key => $widget_block ) {
3904                        $widget_block_reference = 'block-' . $key;
3905
3906                        if ( ! isset( $widget_block['content'] ) || ! $widget_block['content'] ) {
3907                                continue;
3908                        }
3909
3910                        foreach ( $sidebars as $sidebar ) {
3911                                if ( is_array( $sidebar ) && in_array( $widget_block_reference, $sidebar, true ) ) {
3912                                        $widgets_content .= $widget_block['content'] . "\n";
3913                                }
3914                        }
3915                }
3916
3917                $is_active['block'] = has_block( $block_name, $widgets_content );
3918        }
3919
3920        if ( $widget_id_base ) {
3921                $is_active['widget'] = is_active_widget( false, false, $widget_id_base, true );
3922        }
3923
3924        return 0 !== count( array_filter( $is_active ) );
3925}
Note: See TracBrowser for help on using the repository browser.