Skip to:
Content

BuddyPress.org

source: trunk/bp-core/bp-core-template.php @ 7100

Last change on this file since 7100 was 7100, checked in by boonebgorges, 9 years ago

Reformats docblock for bp_nav_menu().

  • Break lines before 80 characters
  • Indent argument descriptions for better readability
  • Property svn:eol-style set to native
File size: 55.3 KB
Line 
1<?php
2
3// Exit if accessed directly
4if ( !defined( 'ABSPATH' ) ) exit;
5
6/**
7 * Uses the $bp->bp_options_nav global to render out the sub navigation for the current component.
8 * Each component adds to its sub navigation array within its own setup_nav() function.
9 *
10 * This sub navigation array is the secondary level navigation, so for profile it contains:
11 *      [Public, Edit Profile, Change Avatar]
12 *
13 * The function will also analyze the current action for the current component to determine whether
14 * or not to highlight a particular sub nav item.
15 *
16 * @package BuddyPress Core
17 * @global BuddyPress $bp The one true BuddyPress instance
18 * @uses bp_get_user_nav() Renders the navigation for a profile of a currently viewed user.
19 */
20function bp_get_options_nav() {
21        global $bp;
22
23        // If we are looking at a member profile, then the we can use the current component as an
24        // index. Otherwise we need to use the component's root_slug
25        $component_index = !empty( $bp->displayed_user ) ? bp_current_component() : bp_get_root_slug( bp_current_component() );
26
27        if ( !bp_is_single_item() ) {
28                if ( !isset( $bp->bp_options_nav[$component_index] ) || count( $bp->bp_options_nav[$component_index] ) < 1 ) {
29                        return false;
30                } else {
31                        $the_index = $component_index;
32                }
33        } else {
34                if ( !isset( $bp->bp_options_nav[bp_current_item()] ) || count( $bp->bp_options_nav[bp_current_item()] ) < 1 ) {
35                        return false;
36                } else {
37                        $the_index = bp_current_item();
38                }
39        }
40
41        // Loop through each navigation item
42        foreach ( (array) $bp->bp_options_nav[$the_index] as $subnav_item ) {
43                if ( !$subnav_item['user_has_access'] )
44                        continue;
45
46                // If the current action or an action variable matches the nav item id, then add a highlight CSS class.
47                if ( $subnav_item['slug'] == bp_current_action() ) {
48                        $selected = ' class="current selected"';
49                } else {
50                        $selected = '';
51                }
52
53                // List type depends on our current component
54                $list_type = bp_is_group() ? 'groups' : 'personal';
55
56                // echo out the final list item
57                echo apply_filters( 'bp_get_options_nav_' . $subnav_item['css_id'], '<li id="' . $subnav_item['css_id'] . '-' . $list_type . '-li" ' . $selected . '><a id="' . $subnav_item['css_id'] . '" href="' . $subnav_item['link'] . '">' . $subnav_item['name'] . '</a></li>', $subnav_item );
58        }
59}
60
61function bp_get_options_title() {
62        global $bp;
63
64        if ( empty( $bp->bp_options_title ) )
65                $bp->bp_options_title = __( 'Options', 'buddypress' );
66
67        echo apply_filters( 'bp_get_options_title', esc_attr( $bp->bp_options_title ) );
68}
69
70/** Avatars *******************************************************************/
71
72/**
73 * Check to see if there is an options avatar. An options avatar is an avatar for something
74 * like a group, or a friend. Basically an avatar that appears in the sub nav options bar.
75 *
76 * @package BuddyPress Core
77 * @global BuddyPress $bp The one true BuddyPress instance
78 */
79function bp_has_options_avatar() {
80        global $bp;
81
82        if ( empty( $bp->bp_options_avatar ) )
83                return false;
84
85        return true;
86}
87
88function bp_get_options_avatar() {
89        global $bp;
90
91        echo apply_filters( 'bp_get_options_avatar', $bp->bp_options_avatar );
92}
93
94function bp_comment_author_avatar() {
95        global $comment;
96
97        if ( function_exists( 'bp_core_fetch_avatar' ) )
98                echo apply_filters( 'bp_comment_author_avatar', bp_core_fetch_avatar( array( 'item_id' => $comment->user_id, 'type' => 'thumb', 'alt' => sprintf( __( 'Avatar of %s', 'buddypress' ), bp_core_get_user_displayname( $comment->user_id ) ) ) ) );
99        else if ( function_exists('get_avatar') )
100                get_avatar();
101}
102
103function bp_post_author_avatar() {
104        global $post;
105
106        if ( function_exists( 'bp_core_fetch_avatar' ) )
107                echo apply_filters( 'bp_post_author_avatar', bp_core_fetch_avatar( array( 'item_id' => $post->post_author, 'type' => 'thumb', 'alt' => sprintf( __( 'Avatar of %s', 'buddypress' ), bp_core_get_user_displayname( $post->post_author ) ) ) ) );
108        else if ( function_exists('get_avatar') )
109                get_avatar();
110}
111
112function bp_avatar_admin_step() {
113        echo bp_get_avatar_admin_step();
114}
115        function bp_get_avatar_admin_step() {
116                global $bp;
117
118                if ( isset( $bp->avatar_admin->step ) )
119                        $step = $bp->avatar_admin->step;
120                else
121                        $step = 'upload-image';
122
123                return apply_filters( 'bp_get_avatar_admin_step', $step );
124        }
125
126function bp_avatar_to_crop() {
127        echo bp_get_avatar_to_crop();
128}
129        function bp_get_avatar_to_crop() {
130                global $bp;
131
132                if ( isset( $bp->avatar_admin->image->url ) )
133                        $url = $bp->avatar_admin->image->url;
134                else
135                        $url = '';
136
137                return apply_filters( 'bp_get_avatar_to_crop', $url );
138        }
139
140function bp_avatar_to_crop_src() {
141        echo bp_get_avatar_to_crop_src();
142}
143        function bp_get_avatar_to_crop_src() {
144                global $bp;
145
146                return apply_filters( 'bp_get_avatar_to_crop_src', str_replace( WP_CONTENT_DIR, '', $bp->avatar_admin->image->dir ) );
147        }
148
149function bp_avatar_cropper() {
150        global $bp;
151
152        echo '<img id="avatar-to-crop" class="avatar" src="' . $bp->avatar_admin->image . '" />';
153}
154
155/**
156 * Echoes bp_get_site_name()
157 */
158function bp_site_name() {
159        echo bp_get_site_name();
160}
161        /**
162         * Returns the name of the BP site. Used in RSS headers
163         *
164         * @since BuddyPress (1.6)
165         */
166        function bp_get_site_name() {
167                return apply_filters( 'bp_site_name', get_bloginfo( 'name', 'display' ) );
168        }
169
170function bp_format_time( $time, $just_date = false, $localize_time = true ) {
171        if ( !isset( $time ) || !is_numeric( $time ) )
172                return false;
173
174        // Get GMT offset from root blog
175        $root_blog_offset = false;
176        if ( $localize_time )
177                $root_blog_offset = get_blog_option( bp_get_root_blog_id(), 'gmt_offset' );
178
179        // Calculate offset time
180        $time_offset = $time + ( $root_blog_offset * 3600 );
181
182        // Current date (January 1, 2010)
183        $date = date_i18n( get_option( 'date_format' ), $time_offset );
184
185        // Should we show the time also?
186        if ( !$just_date ) {
187                // Current time (9:50pm)
188                $time = date_i18n( get_option( 'time_format' ), $time_offset );
189
190                // Return string formatted with date and time
191                $date = sprintf( __( '%1$s at %2$s', 'buddypress' ), $date, $time );
192        }
193
194        return apply_filters( 'bp_format_time', $date );
195}
196
197function bp_word_or_name( $youtext, $nametext, $capitalize = true, $echo = true ) {
198
199        if ( !empty( $capitalize ) )
200                $youtext = bp_core_ucfirst( $youtext );
201
202        if ( bp_displayed_user_id() == bp_loggedin_user_id() ) {
203                if ( true == $echo ) {
204                        echo apply_filters( 'bp_word_or_name', $youtext );
205                } else {
206                        return apply_filters( 'bp_word_or_name', $youtext );
207                }
208        } else {
209                $fullname = bp_get_displayed_user_fullname();
210                $fullname = (array) explode( ' ', $fullname );
211                $nametext = sprintf( $nametext, $fullname[0] );
212                if ( true == $echo ) {
213                        echo apply_filters( 'bp_word_or_name', $nametext );
214                } else {
215                        return apply_filters( 'bp_word_or_name', $nametext );
216                }
217        }
218}
219
220
221function bp_styles() {
222        do_action( 'bp_styles' );
223        wp_print_styles();
224}
225
226/** Search Form ***************************************************************/
227
228function bp_search_form_action() {
229        return apply_filters( 'bp_search_form_action', trailingslashit( bp_get_root_domain() . '/' . bp_get_search_slug() ) );
230}
231
232/**
233 * Generates the basic search form as used in BP-Default's header.
234 *
235 * @return string HTML <select> element
236 * @since BuddyPress (1.0)
237 */
238function bp_search_form_type_select() {
239
240        $options = array();
241
242        if ( bp_is_active( 'xprofile' ) )
243                $options['members'] = __( 'Members', 'buddypress' );
244
245        if ( bp_is_active( 'groups' ) )
246                $options['groups']  = __( 'Groups',  'buddypress' );
247
248        if ( bp_is_active( 'blogs' ) && is_multisite() )
249                $options['blogs']   = __( 'Blogs',   'buddypress' );
250
251        if ( bp_is_active( 'forums' ) && bp_forums_is_installed_correctly() && bp_forums_has_directory() )
252                $options['forums']  = __( 'Forums',  'buddypress' );
253
254        $options['posts'] = __( 'Posts', 'buddypress' );
255
256        // Eventually this won't be needed and a page will be built to integrate all search results.
257        $selection_box  = '<label for="search-which" class="accessibly-hidden">' . __( 'Search these:', 'buddypress' ) . '</label>';
258        $selection_box .= '<select name="search-which" id="search-which" style="width: auto">';
259
260        $options = apply_filters( 'bp_search_form_type_select_options', $options );
261        foreach( (array) $options as $option_value => $option_title )
262                $selection_box .= sprintf( '<option value="%s">%s</option>', $option_value, $option_title );
263
264        $selection_box .= '</select>';
265
266        return apply_filters( 'bp_search_form_type_select', $selection_box );
267}
268
269/**
270 * Get the default text for the search box for a given component.
271 *
272 * @global object $bp BuddyPress global settings
273 * @return string
274 * @since BuddyPress (1.5)
275 */
276function bp_search_default_text( $component = '' ) {
277        echo bp_get_search_default_text( $component );
278}
279        function bp_get_search_default_text( $component = '' ) {
280                global $bp;
281
282                if ( empty( $component ) )
283                        $component = bp_current_component();
284
285                $default_text = __( 'Search anything...', 'buddypress' );
286
287                // Most of the time, $component will be the actual component ID
288                if ( !empty( $component ) ) {
289                        if ( !empty( $bp->{$component}->search_string ) ) {
290                                $default_text = $bp->{$component}->search_string;
291                        } else {
292                                // When the request comes through AJAX, we need to get the component
293                                // name out of $bp->pages
294                                if ( !empty( $bp->pages->{$component}->slug ) ) {
295                                        $key = $bp->pages->{$component}->slug;
296                                        if ( !empty( $bp->{$key}->search_string ) )
297                                                $default_text = $bp->{$key}->search_string;
298                                }
299                        }
300                }
301
302                return apply_filters( 'bp_get_search_default_text', $default_text, $component );
303        }
304
305function bp_custom_profile_boxes() {
306        do_action( 'bp_custom_profile_boxes' );
307}
308
309function bp_custom_profile_sidebar_boxes() {
310        do_action( 'bp_custom_profile_sidebar_boxes' );
311}
312
313/**
314 * Creates and outputs a button.
315 *
316 * @param array $args See bp_get_button() for the list of arguments.
317 * @see bp_get_button()
318 */
319function bp_button( $args = '' ) {
320        echo bp_get_button( $args );
321}
322        /**
323         * Creates and returns a button.
324         *
325         * Args:
326         * component: Which component this button is for
327         * must_be_logged_in: Button only appears for logged in users
328         * block_self: Button will not appear when viewing your own profile.
329         * wrapper: div|span|p|li|
330         * wrapper_id: The DOM ID of the button wrapper
331         * wrapper_class: The DOM class of the button wrapper
332         * link_href: The destination link of the button
333         * link_title: Title of the button
334         * link_id: The DOM ID of the button
335         * link_class: The DOM class of the button
336         * link_rel: The DOM rel of the button
337         * link_text: The contents of the button
338         *
339         * @param array $button
340         * @return string
341         * @see bp_add_friend_button()
342         * @see bp_send_public_message_button()
343         * @see bp_send_private_message_button()
344         */
345        function bp_get_button( $args = '' ) {
346                $button = new BP_Button( $args );
347                return apply_filters( 'bp_get_button', $button->contents, $args, $button );
348        }
349
350
351/**
352 * Truncates text.
353 *
354 * Cuts a string to the length of $length and replaces the last characters
355 * with the ending if the text is longer than length.
356 *
357 * This function is borrowed from CakePHP v2.0, under the MIT license. See
358 * http://book.cakephp.org/view/1469/Text#truncate-1625
359 *
360 * ### Options:
361 *
362 * - `ending` Will be used as Ending and appended to the trimmed string
363 * - `exact` If false, $text will not be cut mid-word
364 * - `html` If true, HTML tags would be handled correctly
365 * - `filter_shortcodes` If true, shortcodes will be stripped before truncating
366 *
367 * @package BuddyPress
368 *
369 * @param string  $text String to truncate.
370 * @param integer $length Length of returned string, including ellipsis.
371 * @param array $options An array of html attributes and options.
372 * @return string Trimmed string.
373 */
374function bp_create_excerpt( $text, $length = 225, $options = array() ) {
375        // Backward compatibility. The third argument used to be a boolean $filter_shortcodes
376        $filter_shortcodes_default = is_bool( $options ) ? $options : true;
377
378        $defaults = array(
379                'ending'            => __( ' [&hellip;]', 'buddypress' ),
380                'exact'             => false,
381                'html'              => true,
382                'filter_shortcodes' => $filter_shortcodes_default
383        );
384        $r = wp_parse_args( $options, $defaults );
385        extract( $r );
386
387        // Save the original text, to be passed along to the filter
388        $original_text = $text;
389
390        // Allow plugins to modify these values globally
391        $length = apply_filters( 'bp_excerpt_length', $length );
392        $ending = apply_filters( 'bp_excerpt_append_text', $ending );
393
394        // Remove shortcodes if necessary
395        if ( !empty( $filter_shortcodes ) )
396                $text = strip_shortcodes( $text );
397
398        // When $html is true, the excerpt should be created without including HTML tags in the
399        // excerpt length
400        if ( !empty( $html ) ) {
401                // The text is short enough. No need to truncate
402                if ( mb_strlen( preg_replace( '/<.*?>/', '', $text ) ) <= $length ) {
403                        return $text;
404                }
405
406                $totalLength = mb_strlen( strip_tags( $ending ) );
407                $openTags    = array();
408                $truncate    = '';
409
410                // Find all the tags and put them in a stack for later use
411                preg_match_all( '/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER );
412                foreach ( $tags as $tag ) {
413                        // Process tags that need to be closed
414                        if ( !preg_match( '/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s',  $tag[2] ) ) {
415                                if ( preg_match( '/<[\w]+[^>]*>/s', $tag[0] ) ) {
416                                        array_unshift( $openTags, $tag[2] );
417                                } else if ( preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag ) ) {
418                                        $pos = array_search( $closeTag[1], $openTags );
419                                        if ( $pos !== false ) {
420                                                array_splice( $openTags, $pos, 1 );
421                                        }
422                                }
423                        }
424                        $truncate .= $tag[1];
425
426                        $contentLength = mb_strlen( preg_replace( '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3] ) );
427                        if ( $contentLength + $totalLength > $length ) {
428                                $left = $length - $totalLength;
429                                $entitiesLength = 0;
430                                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 ) ) {
431                                        foreach ( $entities[0] as $entity ) {
432                                                if ( $entity[1] + 1 - $entitiesLength <= $left ) {
433                                                        $left--;
434                                                        $entitiesLength += mb_strlen( $entity[0] );
435                                                } else {
436                                                        break;
437                                                }
438                                        }
439                                }
440
441                                $truncate .= mb_substr( $tag[3], 0 , $left + $entitiesLength );
442                                break;
443                        } else {
444                                $truncate .= $tag[3];
445                                $totalLength += $contentLength;
446                        }
447                        if ( $totalLength >= $length ) {
448                                break;
449                        }
450                }
451        } else {
452                if ( mb_strlen( $text ) <= $length ) {
453                        return $text;
454                } else {
455                        $truncate = mb_substr( $text, 0, $length - mb_strlen( $ending ) );
456                }
457        }
458
459        // If $exact is false, we can't break on words
460        if ( empty( $exact ) ) {
461                $spacepos = mb_strrpos( $truncate, ' ' );
462                if ( isset( $spacepos ) ) {
463                        if ( $html ) {
464                                $bits = mb_substr( $truncate, $spacepos );
465                                preg_match_all( '/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER );
466                                if ( !empty( $droppedTags ) ) {
467                                        foreach ( $droppedTags as $closingTag ) {
468                                                if ( !in_array( $closingTag[1], $openTags ) ) {
469                                                        array_unshift( $openTags, $closingTag[1] );
470                                                }
471                                        }
472                                }
473                        }
474                        $truncate = mb_substr( $truncate, 0, $spacepos );
475                }
476        }
477        $truncate .= $ending;
478
479        if ( $html ) {
480                foreach ( $openTags as $tag ) {
481                        $truncate .= '</' . $tag . '>';
482                }
483        }
484
485        return apply_filters( 'bp_create_excerpt', $truncate, $original_text, $length, $options );
486
487}
488add_filter( 'bp_create_excerpt', 'stripslashes_deep' );
489add_filter( 'bp_create_excerpt', 'force_balance_tags' );
490
491/**
492 * Echoes the output of bp_get_total_member_count()
493 */
494function bp_total_member_count() {
495        echo bp_get_total_member_count();
496}
497        /**
498         * Returns the total member count in your BP instance
499         *
500         * Since BuddyPress 1.6, this function has used bp_core_get_active_member_count(), which
501         * counts non-spam, non-deleted users who have last_activity. This value will correctly
502         * match the total member count number used for pagination on member directories.
503         *
504         * Before BuddyPress 1.6, this function used bp_core_get_total_member_count(), which did
505         * not take into account last_activity, and thus often resulted in higher counts than
506         * shown by member directory pagination.
507         */
508        function bp_get_total_member_count() {
509                return apply_filters( 'bp_get_total_member_count', bp_core_get_active_member_count() );
510        }
511        add_filter( 'bp_get_total_member_count', 'bp_core_number_format' );
512
513function bp_blog_signup_allowed() {
514        echo bp_get_blog_signup_allowed();
515}
516        function bp_get_blog_signup_allowed() {
517                global $bp;
518
519                if ( !is_multisite() )
520                        return false;
521
522                $status = $bp->site_options['registration'];
523                if ( 'none' != $status && 'user' != $status )
524                        return true;
525
526                return false;
527        }
528
529function bp_account_was_activated() {
530        global $bp;
531
532        $activation_complete = !empty( $bp->activation_complete ) ? $bp->activation_complete : false;
533
534        return $activation_complete;
535}
536
537function bp_registration_needs_activation() {
538        return apply_filters( 'bp_registration_needs_activation', true );
539}
540
541/**
542 * Retrieve a client friendly version of the root blog name, plus take care of
543 * the typical formatting bits and bobs.
544 *
545 * The blogname option is escaped with esc_html on the way into the database in
546 * sanitize_option, we want to reverse this for the plain text arena of emails.
547 *
548 * @link http://buddypress.trac.wordpress.org/ticket/4401
549 * @since BuddyPress (1.7)
550 * @return string
551 */
552function bp_get_email_subject( $args = array() ) {
553
554        $r = wp_parse_args( $args, array(
555                'before'  => '[',
556                'after'   => ']',
557                'default' => __( 'Community', 'buddypress' ),
558                'text'    => ''
559        ) );
560
561        $subject = $r['before'] . wp_specialchars_decode( bp_get_option( 'blogname', $r['default'] ), ENT_QUOTES ) . $r['after'] . ' ' . $r['text'];
562
563        return apply_filters( 'bp_get_email_subject', $subject, $r );
564}
565
566/**
567 * Allow templates to pass parameters directly into the template loops via AJAX
568 *
569 * For the most part this will be filtered in a theme's functions.php for example
570 * in the default theme it is filtered via bp_dtheme_ajax_querystring()
571 *
572 * By using this template tag in the templates it will stop them from showing errors
573 * if someone copies the templates from the default theme into another WordPress theme
574 * without coping the functions from functions.php.
575 */
576function bp_ajax_querystring( $object = false ) {
577        global $bp;
578
579        if ( !isset( $bp->ajax_querystring ) )
580                $bp->ajax_querystring = '';
581
582        return apply_filters( 'bp_ajax_querystring', $bp->ajax_querystring, $object );
583}
584
585/** Template Classes and _is functions ****************************************/
586
587function bp_current_component() {
588        global $bp;
589        $current_component = !empty( $bp->current_component ) ? $bp->current_component : false;
590        return apply_filters( 'bp_current_component', $current_component );
591}
592
593function bp_current_action() {
594        global $bp;
595        $current_action = !empty( $bp->current_action ) ? $bp->current_action : '';
596        return apply_filters( 'bp_current_action', $current_action );
597}
598
599function bp_current_item() {
600        global $bp;
601        $current_item = !empty( $bp->current_item ) ? $bp->current_item : false;
602        return apply_filters( 'bp_current_item', $current_item );
603}
604
605/**
606 * Return the value of $bp->action_variables
607 *
608 * @package BuddyPress
609 *
610 * @param mixed $action_variables The action variables array, or false if the array is empty
611 */
612function bp_action_variables() {
613        global $bp;
614        $action_variables = !empty( $bp->action_variables ) ? $bp->action_variables : false;
615        return apply_filters( 'bp_action_variables', $action_variables );
616}
617
618/**
619 * Return the value of a given action variable
620 *
621 * @package BuddyPress
622 * @since BuddyPress (1.5)
623 *
624 * @param int $position The key of the action_variables array that you want
625 * @return str $action_variable The value of that position in the array
626 */
627function bp_action_variable( $position = 0 ) {
628        $action_variables = bp_action_variables();
629        $action_variable  = isset( $action_variables[$position] ) ? $action_variables[$position] : false;
630
631        return apply_filters( 'bp_action_variable', $action_variable, $position );
632}
633
634function bp_root_domain() {
635        echo bp_get_root_domain();
636}
637        function bp_get_root_domain() {
638                global $bp;
639
640                if ( isset( $bp->root_domain ) && !empty( $bp->root_domain ) ) {
641                        $domain = $bp->root_domain;
642                } else {
643                        $domain          = bp_core_get_root_domain();
644                        $bp->root_domain = $domain;
645                }
646
647                return apply_filters( 'bp_get_root_domain', $domain );
648        }
649
650/**
651 * Echoes the output of bp_get_root_slug()
652 *
653 * @package BuddyPress Core
654 * @since BuddyPress (1.5)
655 */
656function bp_root_slug( $component = '' ) {
657        echo bp_get_root_slug( $component );
658}
659        /**
660         * Gets the root slug for a component slug
661         *
662         * In order to maintain backward compatibility, the following procedure is used:
663         * 1) Use the short slug to get the canonical component name from the
664         *    active component array
665         * 2) Use the component name to get the root slug out of the appropriate part of the $bp
666         *    global
667         * 3) If nothing turns up, it probably means that $component is itself a root slug
668         *
669         * Example: If your groups directory is at /community/companies, this function first uses
670         * the short slug 'companies' (ie the current component) to look up the canonical name
671         * 'groups' in $bp->active_components. Then it uses 'groups' to get the root slug, from
672         * $bp->groups->root_slug.
673         *
674         * @package BuddyPress Core
675         * @since BuddyPress (1.5)
676         *
677         * @global BuddyPress $bp The one true BuddyPress instance
678         * @param string $component Optional. Defaults to the current component
679         * @return string $root_slug The root slug
680         */
681        function bp_get_root_slug( $component = '' ) {
682                global $bp;
683
684                $root_slug = '';
685
686                // Use current global component if none passed
687                if ( empty( $component ) )
688                        $component = bp_current_component();
689
690                // Component is active
691                if ( !empty( $bp->active_components[$component] ) ) {
692                        // Backward compatibility: in legacy plugins, the canonical component id
693                        // was stored as an array value in $bp->active_components
694                        $component_name = '1' == $bp->active_components[$component] ? $component : $bp->active_components[$component];
695
696                        // Component has specific root slug
697                        if ( !empty( $bp->{$component_name}->root_slug ) ) {
698                                $root_slug = $bp->{$component_name}->root_slug;
699                        }
700                }
701
702                // No specific root slug, so fall back to component slug
703                if ( empty( $root_slug ) )
704                        $root_slug = $component;
705
706                return apply_filters( 'bp_get_root_slug', $root_slug, $component );
707        }
708
709/**
710 * Return the component name based on the current root slug
711 *
712 * @since BuddyPress {r3923}
713 * @global BuddyPress $bp The one true BuddyPress instance
714 * @param str $root_slug Needle to our active component haystack
715 * @return mixed False if none found, component name if found
716 */
717function bp_get_name_from_root_slug( $root_slug = '' ) {
718        global $bp;
719
720        // If no slug is passed, look at current_component
721        if ( empty( $root_slug ) )
722                $root_slug = bp_current_component();
723
724        // No current component or root slug, so flee
725        if ( empty( $root_slug ) )
726                return false;
727
728        // Loop through active components and look for a match
729        foreach ( array_keys( $bp->active_components ) as $component ) {
730                if ( ( !empty( $bp->{$component}->slug ) && ( $bp->{$component}->slug == $root_slug ) ) || ( !empty( $bp->{$component}->root_slug ) && ( $bp->{$component}->root_slug == $root_slug ) ) ) {
731                        return $bp->{$component}->name;
732                }
733        }
734
735        return false;
736}
737
738function bp_user_has_access() {
739        $has_access = ( bp_current_user_can( 'bp_moderate' ) || bp_is_my_profile() ) ? true : false;
740
741        return apply_filters( 'bp_user_has_access', $has_access );
742}
743
744/**
745 * Output the search slug
746 *
747 * @package BuddyPress
748 * @since BuddyPress (1.5)
749 *
750 * @uses bp_get_search_slug()
751 */
752function bp_search_slug() {
753        echo bp_get_search_slug();
754}
755        /**
756         * Return the search slug
757         *
758         * @package BuddyPress
759         * @since BuddyPress (1.5)
760         */
761        function bp_get_search_slug() {
762                return apply_filters( 'bp_get_search_slug', BP_SEARCH_SLUG );
763        }
764
765/**
766 * Get the id of the currently displayed user
767 *
768 * @uses apply_filters() Filter 'bp_displayed_user_id' to change this value
769 * @return int
770 */
771function bp_displayed_user_id() {
772        $bp = buddypress();
773        $id = !empty( $bp->displayed_user->id ) ? $bp->displayed_user->id : 0;
774
775        return (int) apply_filters( 'bp_displayed_user_id', $id );
776}
777
778/**
779 * Get the id of the currently logged-in user
780 *
781 * @uses apply_filters() Filter 'bp_loggedin_user_id' to change this value
782 * @return int
783 */
784function bp_loggedin_user_id() {
785        $bp = buddypress();
786        $id = !empty( $bp->loggedin_user->id ) ? $bp->loggedin_user->id : 0;
787
788        return (int) apply_filters( 'bp_loggedin_user_id', $id );
789}
790
791/** is_() functions to determine the current page *****************************/
792
793/**
794 * Checks to see whether the current page belongs to the specified component
795 *
796 * This function is designed to be generous, accepting several different kinds
797 * of value for the $component parameter. It checks $component_name against:
798 * - the component's root_slug, which matches the page slug in $bp->pages
799 * - the component's regular slug
800 * - the component's id, or 'canonical' name
801 *
802 * @package BuddyPress Core
803 * @since BuddyPress (1.5)
804 * @return bool Returns true if the component matches, or else false.
805 */
806function bp_is_current_component( $component ) {
807        global $bp;
808
809        $is_current_component = false;
810
811        // Backward compatibility: 'xprofile' should be read as 'profile'
812        if ( 'xprofile' == $component )
813                $component = 'profile';
814
815        if ( !empty( $bp->current_component ) ) {
816
817                // First, check to see whether $component_name and the current
818                // component are a simple match
819                if ( $bp->current_component == $component ) {
820                        $is_current_component = true;
821
822                // Since the current component is based on the visible URL slug let's
823                // check the component being passed and see if its root_slug matches
824                } elseif ( isset( $bp->{$component}->root_slug ) && $bp->{$component}->root_slug == $bp->current_component ) {
825                        $is_current_component = true;
826
827                // Because slugs can differ from root_slugs, we should check them too
828                } elseif ( isset( $bp->{$component}->slug ) && $bp->{$component}->slug == $bp->current_component ) {
829                        $is_current_component = true;
830
831                // Next, check to see whether $component is a canonical,
832                // non-translatable component name. If so, we can return its
833                // corresponding slug from $bp->active_components.
834                } else if ( $key = array_search( $component, $bp->active_components ) ) {
835                        if ( strstr( $bp->current_component, $key ) ) {
836                                $is_current_component = true;
837                        }
838
839                // If we haven't found a match yet, check against the root_slugs
840                // created by $bp->pages, as well as the regular slugs
841                } else {
842                        foreach ( $bp->active_components as $id ) {
843                                // If the $component parameter does not match the current_component,
844                                // then move along, these are not the droids you are looking for
845                                if ( empty( $bp->{$id}->root_slug ) || $bp->{$id}->root_slug != $bp->current_component ) {
846                                        continue;
847                                }
848
849                                if ( $id == $component ) {
850                                        $is_current_component = true;
851                                        break;
852                                }
853                        }
854                }
855
856        // Page template fallback check if $bp->current_component is empty
857        } elseif ( !is_admin() && is_page() ) {
858                global $wp_query;
859                $page          = $wp_query->get_queried_object();
860                $custom_fields = get_post_custom_values( '_wp_page_template', $page->ID );
861                $page_template = $custom_fields[0];
862
863                // Component name is in the page template name
864                if ( !empty( $page_template ) && strstr( strtolower( $page_template ), strtolower( $component ) ) ) {
865                        $is_current_component = true;
866                }
867        }
868
869        return apply_filters( 'bp_is_current_component', $is_current_component, $component );
870}
871
872/**
873 * Check to see whether the current page matches a given action.
874 *
875 * Along with bp_is_current_component() and bp_is_action_variable(), this function is mostly used
876 * to help determine when to use a given screen function.
877 *
878 * In BP parlance, the current_action is the URL chunk that comes directly after the
879 * current item slug. E.g., in
880 *   http://example.com/groups/my-group/members
881 * the current_action is 'members'.
882 *
883 * @package BuddyPress
884 * @since BuddyPress (1.5)
885 *
886 * @param str $action The action being tested against
887 * @return bool True if the current action matches $action
888 */
889function bp_is_current_action( $action = '' ) {
890        if ( $action == bp_current_action() )
891                return true;
892
893        return false;
894}
895
896/**
897 * Check to see whether the current page matches a given action_variable.
898 *
899 * Along with bp_is_current_component() and bp_is_current_action(), this function is mostly used
900 * to help determine when to use a given screen function.
901 *
902 * In BP parlance, action_variables are an array made up of the URL chunks appearing after the
903 * current_action in a URL. For example,
904 *   http://example.com/groups/my-group/admin/group-settings
905 * $action_variables[0] is 'group-settings'.
906 *
907 * @package BuddyPress
908 * @since BuddyPress (1.5)
909 *
910 * @param str $action_variable The action_variable being tested against
911 * @param int $position The array key you're testing against. If you don't provide a $position,
912 *   the function will return true if the $action_variable is found *anywhere* in the action
913 *   variables array.
914 * @return bool
915 */
916function bp_is_action_variable( $action_variable = '', $position = false ) {
917        $is_action_variable = false;
918
919        if ( false !== $position ) {
920                // When a $position is specified, check that slot in the action_variables array
921                if ( $action_variable ) {
922                        $is_action_variable = $action_variable == bp_action_variable( $position );
923                } else {
924                        // If no $action_variable is provided, we are essentially checking to see
925                        // whether the slot is empty
926                        $is_action_variable = !bp_action_variable( $position );
927                }
928        } else {
929                // When no $position is specified, check the entire array
930                $is_action_variable = in_array( $action_variable, (array)bp_action_variables() );
931        }
932
933        return apply_filters( 'bp_is_action_variable', $is_action_variable, $action_variable, $position );
934}
935
936function bp_is_current_item( $item = '' ) {
937        if ( !empty( $item ) && $item == bp_current_item() )
938                return true;
939
940        return false;
941}
942
943function bp_is_single_item() {
944        global $bp;
945
946        if ( !empty( $bp->is_single_item ) )
947                return true;
948
949        return false;
950}
951
952function bp_is_item_admin() {
953        global $bp;
954
955        if ( !empty( $bp->is_item_admin ) )
956                return true;
957
958        return false;
959}
960
961function bp_is_item_mod() {
962        global $bp;
963
964        if ( !empty( $bp->is_item_mod ) )
965                return true;
966
967        return false;
968}
969
970function bp_is_directory() {
971        global $bp;
972
973        if ( !empty( $bp->is_directory ) )
974                return true;
975
976        return false;
977}
978
979/**
980 * Checks to see if a component's URL should be in the root, not under a
981 * member page:
982 *
983 *   Yes: http://domain.com/groups/the-group
984 *   No:  http://domain.com/members/andy/groups/the-group
985 *
986 * @package BuddyPress Core
987 * @return true if root component, else false.
988 */
989function bp_is_root_component( $component_name ) {
990        global $bp;
991
992        if ( !isset( $bp->active_components ) )
993                return false;
994
995        foreach ( (array) $bp->active_components as $key => $slug ) {
996                if ( $key == $component_name || $slug == $component_name )
997                        return true;
998        }
999
1000        return false;
1001}
1002
1003/**
1004 * Checks if the site's front page is set to the specified BuddyPress component
1005 * page in wp-admin's Settings > Reading screen.
1006 *
1007 * @global BuddyPress $bp The one true BuddyPress instance
1008 * @global $current_blog WordPress global for the current blog
1009 * @param string $component Optional; Name of the component to check for.
1010 * @return bool True If the specified component is set to be the site's front page.
1011 * @since BuddyPress (1.5)
1012 */
1013function bp_is_component_front_page( $component = '' ) {
1014        global $bp, $current_blog;
1015
1016        if ( !$component && !empty( $bp->current_component ) )
1017                $component = $bp->current_component;
1018
1019        $path = is_main_site() ? bp_core_get_site_path() : $current_blog->path;
1020
1021        if ( 'page' != get_option( 'show_on_front' ) || !$component || empty( $bp->pages->{$component} ) || $_SERVER['REQUEST_URI'] != $path )
1022                return false;
1023
1024        return apply_filters( 'bp_is_component_front_page', ( $bp->pages->{$component}->id == get_option( 'page_on_front' ) ), $component );
1025}
1026
1027/**
1028 * Is this a blog page, ie a non-BP page?
1029 *
1030 * You can tell if a page is displaying BP content by whether the current_component has been defined
1031 *
1032 * @package BuddyPress
1033 *
1034 * @return bool True if it's a non-BP page, false otherwise
1035 */
1036function bp_is_blog_page() {
1037
1038        $is_blog_page = false;
1039
1040        // Generally, we can just check to see that there's no current component. The one exception
1041        // is single user home tabs, where $bp->current_component is unset. Thus the addition
1042        // of the bp_is_user() check.
1043        if ( !bp_current_component() && !bp_is_user() )
1044                $is_blog_page = true;
1045
1046        return apply_filters( 'bp_is_blog_page', $is_blog_page );
1047}
1048
1049/**
1050 * Is this a BuddyPress component?
1051 *
1052 * You can tell if a page is displaying BP content by whether the
1053 * current_component has been defined
1054 *
1055 * Generally, we can just check to see that there's no current component.
1056 * The one exception is single user home tabs, where $bp->current_component
1057 * is unset. Thus the addition of the bp_is_user() check.
1058 *
1059 * @since BuddyPress (1.7)
1060 *
1061 * @package BuddyPress
1062 * @return bool True if it's a BuddyPress page, false otherwise
1063 */
1064function is_buddypress() {
1065        $retval = (bool) ( bp_current_component() || bp_is_user() );
1066
1067        return apply_filters( 'is_buddypress', $retval );
1068}
1069
1070/** Components ****************************************************************/
1071
1072function bp_is_active( $component ) {
1073        global $bp;
1074
1075        if ( isset( $bp->active_components[$component] ) || 'core' == $component )
1076                return true;
1077
1078        return false;
1079}
1080
1081function bp_is_members_component() {
1082        if ( bp_is_current_component( 'members' ) )
1083                return true;
1084
1085        return false;
1086}
1087
1088function bp_is_profile_component() {
1089        if ( bp_is_current_component( 'xprofile' ) )
1090                return true;
1091
1092        return false;
1093}
1094
1095function bp_is_activity_component() {
1096        if ( bp_is_current_component( 'activity' ) )
1097                return true;
1098
1099        return false;
1100}
1101
1102function bp_is_blogs_component() {
1103        if ( is_multisite() && bp_is_current_component( 'blogs' ) )
1104                return true;
1105
1106        return false;
1107}
1108
1109function bp_is_messages_component() {
1110        if ( bp_is_current_component( 'messages' ) )
1111                return true;
1112
1113        return false;
1114}
1115
1116function bp_is_friends_component() {
1117        if ( bp_is_current_component( 'friends' ) )
1118                return true;
1119
1120        return false;
1121}
1122
1123function bp_is_groups_component() {
1124        if ( bp_is_current_component( 'groups' ) )
1125                return true;
1126
1127        return false;
1128}
1129
1130function bp_is_forums_component() {
1131        if ( bp_is_current_component( 'forums' ) )
1132                return true;
1133
1134        return false;
1135}
1136
1137function bp_is_settings_component() {
1138        if ( bp_is_current_component( 'settings' ) )
1139                return true;
1140
1141        return false;
1142}
1143
1144/**
1145 * Is the current component an active core component.
1146 *
1147 * Use this function when you need to check if the current component is an
1148 * active core component of BuddyPress. If the current component is inactive, it
1149 * will return false. If the current component is not part of BuddyPress core,
1150 * it will return false. If the current component is active, and is part of
1151 * BuddyPress core, it will return true.
1152 *
1153 * @since BuddyPress (1.7)
1154 * @return boolean
1155 */
1156function bp_is_current_component_core() {
1157        $retval            = false;
1158        $active_components = apply_filters( 'bp_active_components', bp_get_option( 'bp-active-components' ) );
1159
1160        foreach ( array_keys( $active_components ) as $active_component ) {
1161                if ( bp_is_current_component( $active_component ) ) {
1162                        $retval = true;
1163                        break;
1164                }
1165        }
1166
1167        return $retval;
1168}
1169
1170/** Activity ******************************************************************/
1171
1172function bp_is_single_activity() {
1173        if ( bp_is_activity_component() && is_numeric( bp_current_action() ) )
1174                return true;
1175
1176        return false;
1177}
1178
1179/** User **********************************************************************/
1180
1181function bp_is_my_profile() {
1182        if ( is_user_logged_in() && bp_loggedin_user_id() == bp_displayed_user_id() )
1183                $my_profile = true;
1184        else
1185                $my_profile = false;
1186
1187        return apply_filters( 'bp_is_my_profile', $my_profile );
1188}
1189
1190function bp_is_user() {
1191        if ( bp_displayed_user_id() )
1192                return true;
1193
1194        return false;
1195}
1196
1197function bp_is_user_activity() {
1198        if ( bp_is_user() && bp_is_activity_component() )
1199                return true;
1200
1201        return false;
1202}
1203
1204function bp_is_user_friends_activity() {
1205
1206        if ( !bp_is_active( 'friends' ) )
1207                return false;
1208
1209        $slug = bp_get_friends_slug();
1210
1211        if ( empty( $slug ) )
1212                $slug = 'friends';
1213
1214        if ( bp_is_user_activity() && bp_is_current_action( $slug ) )
1215                return true;
1216
1217        return false;
1218}
1219
1220function bp_is_user_groups_activity() {
1221
1222        if ( !bp_is_active( 'groups' ) )
1223                return false;
1224
1225        $slug = bp_get_groups_slug();
1226
1227        if ( empty( $slug ) )
1228                $slug = 'groups';
1229
1230        if ( bp_is_user_activity() && bp_is_current_action( $slug ) )
1231                return true;
1232
1233        return false;
1234}
1235
1236function bp_is_user_profile() {
1237        if ( bp_is_profile_component() || bp_is_current_component( 'profile' ) )
1238                return true;
1239
1240        return false;
1241}
1242
1243function bp_is_user_profile_edit() {
1244        if ( bp_is_profile_component() && bp_is_current_action( 'edit' ) )
1245                return true;
1246
1247        return false;
1248}
1249
1250function bp_is_user_change_avatar() {
1251        if ( bp_is_profile_component() && bp_is_current_action( 'change-avatar' ) )
1252                return true;
1253
1254        return false;
1255}
1256
1257/**
1258 * Is this a user's forums page?
1259 *
1260 * @package BuddyPress
1261 *
1262 * @return bool
1263 */
1264function bp_is_user_forums() {
1265
1266        if ( ! bp_is_active( 'forums' ) )
1267                return false;
1268
1269        if ( bp_is_user() && bp_is_forums_component() )
1270                return true;
1271
1272        return false;
1273}
1274
1275/**
1276 * Is this a user's "Topics Started" page?
1277 *
1278 * @package BuddyPress
1279 * @since BuddyPress (1.5)
1280 *
1281 * @return bool
1282 */
1283function bp_is_user_forums_started() {
1284        if ( bp_is_user_forums() && bp_is_current_action( 'topics' ) )
1285                return true;
1286
1287        return false;
1288}
1289
1290/**
1291 * Is this a user's "Replied To" page?
1292 *
1293 * @package BuddyPress
1294 * @since BuddyPress (1.5)
1295 *
1296 * @return bool
1297 */
1298function bp_is_user_forums_replied_to() {
1299        if ( bp_is_user_forums() && bp_is_current_action( 'replies' ) )
1300                return true;
1301
1302        return false;
1303}
1304
1305function bp_is_user_groups() {
1306        if ( bp_is_user() && bp_is_groups_component() )
1307                return true;
1308
1309        return false;
1310}
1311
1312function bp_is_user_blogs() {
1313        if ( bp_is_user() && bp_is_blogs_component() )
1314                return true;
1315
1316        return false;
1317}
1318
1319function bp_is_user_recent_posts() {
1320        if ( bp_is_user_blogs() && bp_is_current_action( 'recent-posts' ) )
1321                return true;
1322
1323        return false;
1324}
1325
1326function bp_is_user_recent_commments() {
1327        if ( bp_is_user_blogs() && bp_is_current_action( 'recent-comments' ) )
1328                return true;
1329
1330        return false;
1331}
1332
1333function bp_is_user_friends() {
1334        if ( bp_is_user() && bp_is_friends_component() )
1335                return true;
1336
1337        return false;
1338}
1339
1340function bp_is_user_friend_requests() {
1341        if ( bp_is_user_friends() && bp_is_current_action( 'requests' ) )
1342                return true;
1343
1344        return false;
1345}
1346
1347/**
1348 * Is this a user's settings page?
1349 *
1350 * @package BuddyPress
1351 *
1352 * @return bool
1353 */
1354function bp_is_user_settings() {
1355        if ( bp_is_user() && bp_is_settings_component() )
1356                return true;
1357
1358        return false;
1359}
1360
1361/**
1362 * Is this a user's General Settings page?
1363 *
1364 * @package BuddyPress
1365 * @since BuddyPress (1.5)
1366 *
1367 * @return bool
1368 */
1369function bp_is_user_settings_general() {
1370        if ( bp_is_user_settings() && bp_is_current_action( 'general' ) )
1371                return true;
1372
1373        return false;
1374}
1375
1376/**
1377 * Is this a user's Notification Settings page?
1378 *
1379 * @package BuddyPress
1380 * @since BuddyPress (1.5)
1381 *
1382 * @return bool
1383 */
1384function bp_is_user_settings_notifications() {
1385        if ( bp_is_user_settings() && bp_is_current_action( 'notifications' ) )
1386                return true;
1387
1388        return false;
1389}
1390
1391/**
1392 * Is this a user's Account Deletion page?
1393 *
1394 * @package BuddyPress
1395 * @since BuddyPress (1.5)
1396 *
1397 * @return bool
1398 */
1399function bp_is_user_settings_account_delete() {
1400        if ( bp_is_user_settings() && bp_is_current_action( 'delete-account' ) )
1401                return true;
1402
1403        return false;
1404}
1405
1406
1407/** Groups ******************************************************************/
1408
1409function bp_is_group() {
1410        global $bp;
1411
1412        if ( bp_is_groups_component() && isset( $bp->groups->current_group ) && $bp->groups->current_group )
1413                return true;
1414
1415        return false;
1416}
1417
1418function bp_is_group_home() {
1419        if ( bp_is_single_item() && bp_is_groups_component() && ( !bp_current_action() || bp_is_current_action( 'home' ) ) )
1420                return true;
1421
1422        return false;
1423}
1424
1425function bp_is_group_create() {
1426        if ( bp_is_groups_component() && bp_is_current_action( 'create' ) )
1427                return true;
1428
1429        return false;
1430}
1431
1432function bp_is_group_admin_page() {
1433        if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'admin' ) )
1434                return true;
1435
1436        return false;
1437}
1438
1439function bp_is_group_forum() {
1440        $retval = false;
1441
1442        // At a forum URL
1443        if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'forum' ) ) {
1444                $retval = true;
1445
1446                // If at a forum URL, set back to false if forums are inactive, or not
1447                // installed correctly.
1448                if ( ! bp_is_active( 'forums' ) || ! bp_forums_is_installed_correctly() ) {
1449                        $retval = false;
1450                }
1451        }
1452
1453        return $retval;
1454}
1455
1456function bp_is_group_activity() {
1457        if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'activity' ) )
1458                return true;
1459
1460        return false;
1461}
1462
1463function bp_is_group_forum_topic() {
1464        if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'forum' ) && bp_is_action_variable( 'topic', 0 ) )
1465                return true;
1466
1467        return false;
1468}
1469
1470function bp_is_group_forum_topic_edit() {
1471        if ( 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 ) )
1472                return true;
1473
1474        return false;
1475}
1476
1477function bp_is_group_members() {
1478        if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'members' ) )
1479                return true;
1480
1481        return false;
1482}
1483
1484function bp_is_group_invites() {
1485        if ( bp_is_groups_component() && bp_is_current_action( 'send-invites' ) )
1486                return true;
1487
1488        return false;
1489}
1490
1491function bp_is_group_membership_request() {
1492        if ( bp_is_groups_component() && bp_is_current_action( 'request-membership' ) )
1493                return true;
1494
1495        return false;
1496}
1497
1498function bp_is_group_leave() {
1499
1500        if ( bp_is_groups_component() && bp_is_single_item() && bp_is_current_action( 'leave-group' ) )
1501                return true;
1502
1503        return false;
1504}
1505
1506function bp_is_group_single() {
1507        if ( bp_is_groups_component() && bp_is_single_item() )
1508                return true;
1509
1510        return false;
1511}
1512
1513function bp_is_create_blog() {
1514        if ( bp_is_blogs_component() && bp_is_current_action( 'create' ) )
1515                return true;
1516
1517        return false;
1518}
1519
1520/** Messages ******************************************************************/
1521
1522function bp_is_user_messages() {
1523        if ( bp_is_user() && bp_is_messages_component() )
1524                return true;
1525
1526        return false;
1527}
1528
1529function bp_is_messages_inbox() {
1530        if ( bp_is_user_messages() && ( !bp_current_action() || bp_is_current_action( 'inbox' ) ) )
1531                return true;
1532
1533        return false;
1534}
1535
1536function bp_is_messages_sentbox() {
1537        if ( bp_is_user_messages() && bp_is_current_action( 'sentbox' ) )
1538                return true;
1539
1540        return false;
1541}
1542
1543function bp_is_messages_compose_screen() {
1544        if ( bp_is_user_messages() && bp_is_current_action( 'compose' ) )
1545                return true;
1546
1547        return false;
1548}
1549
1550function bp_is_notices() {
1551        if ( bp_is_user_messages() && bp_is_current_action( 'notices' ) )
1552                return true;
1553
1554        return false;
1555}
1556
1557function bp_is_messages_conversation() {
1558        if ( bp_is_user_messages() && ( bp_is_current_action( 'view' ) ) )
1559                return true;
1560
1561        return false;
1562}
1563
1564function bp_is_single( $component, $callback ) {
1565        if ( bp_is_current_component( $component ) && ( true === call_user_func( $callback ) ) )
1566                return true;
1567
1568        return false;
1569}
1570
1571/** Registration **************************************************************/
1572
1573function bp_is_activation_page() {
1574        if ( bp_is_current_component( 'activate' ) )
1575                return true;
1576
1577        return false;
1578}
1579
1580function bp_is_register_page() {
1581        if ( bp_is_current_component( 'register' ) )
1582                return true;
1583
1584        return false;
1585}
1586
1587/**
1588 * Use the above is_() functions to output a body class for each scenario
1589 *
1590 * @package BuddyPress
1591 * @subpackage Core Template
1592 *
1593 * @param array $wp_classes The body classes coming from WP
1594 * @param array $custom_classes Classes that were passed to get_body_class()
1595 * @return array $classes The BP-adjusted body classes
1596 */
1597function bp_the_body_class() {
1598        echo bp_get_the_body_class();
1599}
1600        function bp_get_the_body_class( $wp_classes, $custom_classes = false ) {
1601
1602                $bp_classes = array();
1603
1604                /** Pages *************************************************************/
1605
1606                if ( is_front_page() )
1607                        $bp_classes[] = 'home-page';
1608
1609                if ( bp_is_directory() )
1610                        $bp_classes[] = 'directory';
1611
1612                if ( bp_is_single_item() )
1613                        $bp_classes[] = 'single-item';
1614
1615                /** Components ********************************************************/
1616
1617                if ( !bp_is_blog_page() ) :
1618                        if ( bp_is_user_profile() )
1619                                $bp_classes[] = 'xprofile';
1620
1621                        if ( bp_is_activity_component() )
1622                                $bp_classes[] = 'activity';
1623
1624                        if ( bp_is_blogs_component() )
1625                                $bp_classes[] = 'blogs';
1626
1627                        if ( bp_is_messages_component() )
1628                                $bp_classes[] = 'messages';
1629
1630                        if ( bp_is_friends_component() )
1631                                $bp_classes[] = 'friends';
1632
1633                        if ( bp_is_groups_component() )
1634                                $bp_classes[] = 'groups';
1635
1636                        if ( bp_is_settings_component()  )
1637                                $bp_classes[] = 'settings';
1638                endif;
1639
1640                /** User **************************************************************/
1641
1642                if ( bp_is_user() )
1643                        $bp_classes[] = 'bp-user';
1644
1645                if ( !bp_is_directory() ) :
1646                        if ( bp_is_user_blogs() )
1647                                $bp_classes[] = 'my-blogs';
1648
1649                        if ( bp_is_user_groups() )
1650                                $bp_classes[] = 'my-groups';
1651
1652                        if ( bp_is_user_activity() )
1653                                $bp_classes[] = 'my-activity';
1654                endif;
1655
1656                if ( bp_is_my_profile() )
1657                        $bp_classes[] = 'my-account';
1658
1659                if ( bp_is_user_profile() )
1660                        $bp_classes[] = 'my-profile';
1661
1662                if ( bp_is_user_friends() )
1663                        $bp_classes[] = 'my-friends';
1664
1665                if ( bp_is_user_messages() )
1666                        $bp_classes[] = 'my-messages';
1667
1668                if ( bp_is_user_recent_commments() )
1669                        $bp_classes[] = 'recent-comments';
1670
1671                if ( bp_is_user_recent_posts() )
1672                        $bp_classes[] = 'recent-posts';
1673
1674                if ( bp_is_user_change_avatar() )
1675                        $bp_classes[] = 'change-avatar';
1676
1677                if ( bp_is_user_profile_edit() )
1678                        $bp_classes[] = 'profile-edit';
1679
1680                if ( bp_is_user_friends_activity() )
1681                        $bp_classes[] = 'friends-activity';
1682
1683                if ( bp_is_user_groups_activity() )
1684                        $bp_classes[] = 'groups-activity';
1685
1686                if ( is_user_logged_in() )
1687                        $bp_classes[] = 'logged-in';
1688
1689                /** Messages **********************************************************/
1690
1691                if ( bp_is_messages_inbox() )
1692                        $bp_classes[] = 'inbox';
1693
1694                if ( bp_is_messages_sentbox() )
1695                        $bp_classes[] = 'sentbox';
1696
1697                if ( bp_is_messages_compose_screen() )
1698                        $bp_classes[] = 'compose';
1699
1700                if ( bp_is_notices() )
1701                        $bp_classes[] = 'notices';
1702
1703                if ( bp_is_user_friend_requests() )
1704                        $bp_classes[] = 'friend-requests';
1705
1706                if ( bp_is_create_blog() )
1707                        $bp_classes[] = 'create-blog';
1708
1709                /** Groups ************************************************************/
1710
1711                if ( bp_is_group_leave() )
1712                        $bp_classes[] = 'leave-group';
1713
1714                if ( bp_is_group_invites() )
1715                        $bp_classes[] = 'group-invites';
1716
1717                if ( bp_is_group_members() )
1718                        $bp_classes[] = 'group-members';
1719
1720                if ( bp_is_group_forum_topic() )
1721                        $bp_classes[] = 'group-forum-topic';
1722
1723                if ( bp_is_group_forum_topic_edit() )
1724                        $bp_classes[] = 'group-forum-topic-edit';
1725
1726                if ( bp_is_group_forum() )
1727                        $bp_classes[] = 'group-forum';
1728
1729                if ( bp_is_group_admin_page() ) {
1730                        $bp_classes[] = 'group-admin';
1731                        $bp_classes[] = bp_get_group_current_admin_tab();
1732                }
1733
1734                if ( bp_is_group_create() ) {
1735                        $bp_classes[] = 'group-create';
1736                        $bp_classes[] = bp_get_groups_current_create_step();
1737                }
1738
1739                if ( bp_is_group_home() )
1740                        $bp_classes[] = 'group-home';
1741
1742                if ( bp_is_single_activity() )
1743                        $bp_classes[] = 'activity-permalink';
1744
1745                /** Registration ******************************************************/
1746
1747                if ( bp_is_register_page() )
1748                        $bp_classes[] = 'registration';
1749
1750                if ( bp_is_activation_page() )
1751                        $bp_classes[] = 'activation';
1752
1753                /** Current Component & Action ****************************************/
1754
1755                if ( !bp_is_blog_page() ) {
1756                        $bp_classes[] = bp_current_component();
1757                        $bp_classes[] = bp_current_action();
1758                }
1759
1760                /** is_buddypress *****************************************************/
1761
1762                // Add BuddyPress class if we are within a BuddyPress page
1763                if ( ! bp_is_blog_page() ) {
1764                        $bp_classes[] = 'buddypress';
1765                }
1766
1767                /** Clean up***********************************************************/
1768
1769                // We don't want WordPress blog classes to appear on non-blog pages.
1770                if ( !bp_is_blog_page() ) {
1771
1772                        // Observe WP custom background body class
1773                        if ( in_array( 'custom-background', (array) $wp_classes ) )
1774                                $bp_classes[] = 'custom-background';
1775
1776                        // Preserve any custom classes already set
1777                        if ( !empty( $custom_classes ) ) {
1778                                $wp_classes = (array) $custom_classes;
1779                        } else {
1780                                $wp_classes = array();
1781                        }
1782                }
1783
1784                // Merge WP classes with BP classes and remove any duplicates
1785                $classes = array_unique( array_merge( (array) $bp_classes, (array) $wp_classes ) );
1786
1787                return apply_filters( 'bp_get_the_body_class', $classes, $bp_classes, $wp_classes, $custom_classes );
1788        }
1789        add_filter( 'body_class', 'bp_get_the_body_class', 10, 2 );
1790
1791/**
1792 * Sort BuddyPress nav menu items by their position property.
1793 *
1794 * This is an internal convenience function and it will probably be removed in a later release. Do not use.
1795 *
1796 * @access private
1797 * @param array $a First item
1798 * @param array $b Second item
1799 * @return int Returns an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
1800 * @since BuddyPress (1.7)
1801 */
1802function _bp_nav_menu_sort( $a, $b ) {
1803        if ( $a["position"] == $b["position"] )
1804                return 0;
1805
1806        else if ( $a["position"] < $b["position"] )
1807                return -1;
1808
1809        else
1810                return 1;
1811}
1812
1813/**
1814 * Get an array of all the items registered in the primary and secondary BuddyPress navigation menus
1815 *
1816 * @return array
1817 * @since BuddyPress (1.7)
1818 */
1819function bp_get_nav_menu_items() {
1820        $menus = $selected_menus = array();
1821
1822        // Get the second level menus
1823        foreach ( (array) buddypress()->bp_options_nav as $parent_menu => $sub_menus ) {
1824
1825                // The root menu's ID is "xprofile", but the Profile submenus are using "profile". See BP_Core::setup_nav().
1826                if ( 'profile' == $parent_menu )
1827                        $parent_menu = 'xprofile';
1828
1829                // Sort the items in this menu's navigation by their position property
1830                $second_level_menus = (array) $sub_menus;
1831                usort( $second_level_menus, '_bp_nav_menu_sort' );
1832
1833                // Iterate through the second level menus
1834                foreach( $second_level_menus as $sub_nav ) {
1835
1836                        // Skip items we don't have access to
1837                        if ( ! $sub_nav['user_has_access'] )
1838                                continue;
1839
1840                        // Add this menu
1841                        $menu         = new stdClass;
1842                        $menu->class  = array();
1843                        $menu->css_id = $sub_nav['css_id'];
1844                        $menu->link   = $sub_nav['link'];
1845                        $menu->name   = $sub_nav['name'];
1846                        $menu->parent = $parent_menu;  // Associate this sub nav with a top-level menu
1847
1848                        // If we're viewing this item's screen, record that we need to mark its parent menu to be selected
1849                        if ( $sub_nav['slug'] == bp_current_action() ) {
1850                                $menu->class      = array( 'current-menu-item' );
1851                                $selected_menus[] = $parent_menu;
1852                        }
1853
1854                        $menus[] = $menu;
1855                }
1856        }
1857
1858        // Get the top-level menu parts (Friends, Groups, etc) and sort by their position property
1859        $top_level_menus = (array) buddypress()->bp_nav;
1860        usort( $top_level_menus, '_bp_nav_menu_sort' );
1861
1862        // Iterate through the top-level menus
1863        foreach ( $top_level_menus as $nav ) {
1864
1865                // Skip items marked as user-specific if you're not on your own profile
1866                if ( ! $nav['show_for_displayed_user'] && ! bp_core_can_edit_settings()  )
1867                        continue;
1868
1869                // Get the correct menu link. See http://buddypress.trac.wordpress.org/ticket/4624
1870                $link = bp_loggedin_user_domain() ? str_replace( bp_loggedin_user_domain(), bp_displayed_user_domain(), $nav['link'] ) : trailingslashit( bp_displayed_user_domain() . $nav['link'] );
1871
1872                // Add this menu
1873                $menu         = new stdClass;
1874                $menu->class  = array();
1875                $menu->css_id = $nav['css_id'];
1876                $menu->link   = $link;
1877                $menu->name   = $nav['name'];
1878                $menu->parent = 0;
1879
1880                // Check if we need to mark this menu as selected
1881                if ( in_array( $nav['css_id'], $selected_menus ) )
1882                        $menu->class = array( 'current-menu-parent' );
1883
1884                $menus[] = $menu;
1885        }
1886
1887        return apply_filters( 'bp_get_nav_menu_items', $menus );
1888}
1889
1890/**
1891 * Displays a navigation menu.
1892 *
1893 * @param string|array $args Optional arguments:
1894 *  - before           Text before the link text.
1895 *  - container        Whether to wrap the ul, and what to wrap it with.
1896 *                     Defaults to div.
1897 *  - container_class  The class that is applied to the container. Defaults to
1898 *                     'menu-bp-container'.
1899 *  - container_id     The ID that is applied to the container. Defaults to
1900 *                     blank.
1901 *  - depth            How many levels of the hierarchy are to be included. 0
1902 *                     means all. Defaults to 0.
1903 *  - echo             Whether to echo the menu or return it. Defaults to echo.
1904 *  - fallback_cb      If the menu doesn't exists, a callback function will
1905 *                     fire. Defaults to false (no fallback).
1906 *  - items_wrap       How the list items should be wrapped. Defaults to a ul
1907 *                     with an id and class. Uses printf() format with numbered
1908 *                     placeholders.
1909 *  - link_after       Text after the link.
1910 *  - link_before      Text before the link.
1911 *  - menu_class       CSS class to use for the ul element which forms the menu.
1912 *                     Defaults to 'menu'.
1913 *  - menu_id          The ID that is applied to the ul element which forms the
1914 *                     menu. Defaults to 'menu-bp', incremented.
1915 *  - walker           Allows a custom walker to be specified. Defaults to
1916 *                     'BP_Walker_Nav_Menu'.
1917 *
1918 * @since BuddyPress (1.7)
1919 */
1920function bp_nav_menu( $args = array() ) {
1921        static $menu_id_slugs = array();
1922
1923        $defaults = array(
1924                'after'           => '',
1925                'before'          => '',
1926                'container'       => 'div',
1927                'container_class' => '',
1928                'container_id'    => '',
1929                'depth'           => 0,
1930                'echo'            => true,
1931                'fallback_cb'     => false,
1932                'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>',
1933                'link_after'      => '',
1934                'link_before'     => '',
1935                'menu_class'      => 'menu',
1936                'menu_id'         => '',
1937                'walker'          => '',
1938        );
1939        $args = wp_parse_args( $args, $defaults );
1940        $args = apply_filters( 'bp_nav_menu_args', $args );
1941        $args = (object) $args;
1942
1943        $items = $nav_menu = '';
1944        $show_container = false;
1945
1946        // Create custom walker if one wasn't set
1947        if ( empty( $args->walker ) )
1948                $args->walker = new BP_Walker_Nav_Menu;
1949
1950        // Sanitise values for class and ID
1951        $args->container_class = sanitize_html_class( $args->container_class );
1952        $args->container_id    = sanitize_html_class( $args->container_id );
1953
1954        // Whether to wrap the ul, and what to wrap it with
1955        if ( $args->container ) {
1956                $allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav', ) );
1957
1958                if ( in_array( $args->container, $allowed_tags ) ) {
1959                        $show_container = true;
1960
1961                        $class     = $args->container_class ? ' class="' . esc_attr( $args->container_class ) . '"' : ' class="menu-bp-container"';
1962                        $id        = $args->container_id    ? ' id="' . esc_attr( $args->container_id ) . '"'       : '';
1963                        $nav_menu .= '<' . $args->container . $id . $class . '>';
1964                }
1965        }
1966
1967        // Get the BuddyPress menu items
1968        $menu_items = apply_filters( 'bp_nav_menu_objects', bp_get_nav_menu_items(), $args );
1969        $items      = walk_nav_menu_tree( $menu_items, $args->depth, $args );
1970        unset( $menu_items );
1971
1972        // Set the ID that is applied to the ul element which forms the menu.
1973        if ( ! empty( $args->menu_id ) ) {
1974                $wrap_id = $args->menu_id;
1975
1976        } else {
1977                $wrap_id = 'menu-bp';
1978
1979                // If a specific ID wasn't requested, and there are multiple menus on the same screen, make sure the autogenerated ID is unique
1980                while ( in_array( $wrap_id, $menu_id_slugs ) ) {
1981                        if ( preg_match( '#-(\d+)$#', $wrap_id, $matches ) )
1982                                $wrap_id = preg_replace('#-(\d+)$#', '-' . ++$matches[1], $wrap_id );
1983                        else
1984                                $wrap_id = $wrap_id . '-1';
1985                }
1986        }
1987        $menu_id_slugs[] = $wrap_id;
1988
1989        // Allow plugins to hook into the menu to add their own <li>'s
1990        $items = apply_filters( 'bp_nav_menu_items', $items, $args );
1991
1992        // Build the output
1993        $wrap_class  = $args->menu_class ? $args->menu_class : '';
1994        $nav_menu   .= sprintf( $args->items_wrap, esc_attr( $wrap_id ), esc_attr( $wrap_class ), $items );
1995        unset( $items );
1996
1997        // If we've wrapped the ul, close it
1998        if ( $show_container )
1999                $nav_menu .= '</' . $args->container . '>';
2000
2001        // Final chance to modify output
2002        $nav_menu = apply_filters( 'bp_nav_menu', $nav_menu, $args );
2003
2004        if ( $args->echo )
2005                echo $nav_menu;
2006        else
2007                return $nav_menu;
2008}
Note: See TracBrowser for help on using the repository browser.