[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
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. 11 defined( '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 */ 34 function 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 */ 116 function 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 */ 137 function 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 */ 173 function 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 */ 184 function 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 */ 193 function 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 */ 212 function 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 */ 231 function 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 */ 263 function 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 */ 294 function 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 */ 327 function 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 */ 338 function 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 */ 386 function 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 */ 460 function 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 */ 505 function 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 */ 519 function 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 */ 538 function 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 */ 591 function 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 */ 603 function 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 */ 625 function 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 */ 637 function 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 */ 658 function 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 */ 713 function 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 */ 724 function 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 */ 736 function 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 */ 818 function 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: ' […]'. 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 */ 878 function 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( $options, array( 884 'ending' => __( ' […]', 'buddypress' ), 885 'exact' => false, 886 'html' => true, 887 'filter_shortcodes' => $filter_shortcodes_default, 888 'strip_tags' => false, 889 'remove_links' => false, 890 ), 'create_excerpt' ); 891 892 // Save the original text, to be passed along to the filter. 893 $original_text = $text; 894 895 /** 896 * Filters the excerpt length to trim text to. 897 * 898 * @since 1.5.0 899 * 900 * @param int $length Length of returned string, including ellipsis. 901 */ 902 $length = apply_filters( 'bp_excerpt_length', $length ); 903 904 /** 905 * Filters the excerpt appended text value. 906 * 907 * @since 1.5.0 908 * 909 * @param string $value Text to append to the end of the excerpt. 910 */ 911 $ending = apply_filters( 'bp_excerpt_append_text', $r['ending'] ); 912 913 // Remove shortcodes if necessary. 914 if ( ! empty( $r['filter_shortcodes'] ) ) { 915 $text = strip_shortcodes( $text ); 916 } 917 918 // When $html is true, the excerpt should be created without including HTML tags in the 919 // excerpt length. 920 if ( ! empty( $r['html'] ) ) { 921 922 // The text is short enough. No need to truncate. 923 if ( mb_strlen( preg_replace( '/<.*?>/', '', $text ) ) <= $length ) { 924 return $text; 925 } 926 927 $totalLength = mb_strlen( strip_tags( $ending ) ); 928 $openTags = array(); 929 $truncate = ''; 930 931 // Find all the tags and HTML comments and put them in a stack for later use. 932 preg_match_all( '/(<\/?([\w+!]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER ); 933 934 foreach ( $tags as $tag ) { 935 // Process tags that need to be closed. 936 if ( !preg_match( '/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2] ) ) { 937 if ( preg_match( '/<[\w]+[^>]*>/s', $tag[0] ) ) { 938 array_unshift( $openTags, $tag[2] ); 939 } elseif ( preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag ) ) { 940 $pos = array_search( $closeTag[1], $openTags ); 941 if ( $pos !== false ) { 942 array_splice( $openTags, $pos, 1 ); 943 } 944 } 945 } 946 947 $truncate .= $tag[1]; 948 $contentLength = mb_strlen( preg_replace( '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3] ) ); 949 950 if ( $contentLength + $totalLength > $length ) { 951 $left = $length - $totalLength; 952 $entitiesLength = 0; 953 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 ) ) { 954 foreach ( $entities[0] as $entity ) { 955 if ( $entity[1] + 1 - $entitiesLength <= $left ) { 956 $left--; 957 $entitiesLength += mb_strlen( $entity[0] ); 958 } else { 959 break; 960 } 961 } 962 } 963 964 $truncate .= mb_substr( $tag[3], 0 , $left + $entitiesLength ); 965 break; 966 } else { 967 $truncate .= $tag[3]; 968 $totalLength += $contentLength; 969 } 970 if ( $totalLength >= $length ) { 971 break; 972 } 973 } 974 } else { 975 // Strip HTML tags if necessary. 976 if ( ! empty( $r['strip_tags'] ) ) { 977 $text = strip_tags( $text ); 978 } 979 980 // Remove links if necessary. 981 if ( ! empty( $r['remove_links'] ) ) { 982 $text = preg_replace( '#^\s*(https?://[^\s"]+)\s*$#im', '', $text ); 983 } 984 985 if ( mb_strlen( $text ) <= $length ) { 986 /** 987 * Filters the final generated excerpt. 988 * 989 * @since 1.1.0 990 * 991 * @param string $text Generated excerpt. 992 * @param string $original_text Original text provided. 993 * @param int $length Length of returned string, including ellipsis. 994 * @param array $options Array of HTML attributes and options. 995 */ 996 return apply_filters( 'bp_create_excerpt', $text, $original_text, $length, $options ); 997 } else { 998 $truncate = mb_substr( $text, 0, $length - mb_strlen( $ending ) ); 999 } 1000 } 1001 1002 // If $exact is false, we can't break on words. 1003 if ( empty( $r['exact'] ) ) { 1004 // Find the position of the last space character not part of a tag. 1005 preg_match_all( '/<[a-z\!\/][^>]*>/', $truncate, $_truncate_tags, PREG_OFFSET_CAPTURE ); 1006 1007 // Rekey tags by the string index of their last character. 1008 $truncate_tags = array(); 1009 if ( ! empty( $_truncate_tags[0] ) ) { 1010 foreach ( $_truncate_tags[0] as $_tt ) { 1011 $_tt['start'] = $_tt[1]; 1012 $_tt['end'] = $_tt[1] + strlen( $_tt[0] ); 1013 $truncate_tags[ $_tt['end'] ] = $_tt; 1014 } 1015 } 1016 1017 $truncate_length = mb_strlen( $truncate ); 1018 $spacepos = $truncate_length + 1; 1019 for ( $pos = $truncate_length - 1; $pos >= 0; $pos-- ) { 1020 // Word boundaries are spaces and the close of HTML tags, when the tag is preceded by a space. 1021 $is_word_boundary = ' ' === $truncate[ $pos ]; 1022 if ( ! $is_word_boundary && isset( $truncate_tags[ $pos - 1 ] ) ) { 1023 $preceding_tag = $truncate_tags[ $pos - 1 ]; 1024 if ( ' ' === $truncate[ $preceding_tag['start'] - 1 ] ) { 1025 $is_word_boundary = true; 1026 break; 1027 } 1028 } 1029 1030 if ( ! $is_word_boundary ) { 1031 continue; 1032 } 1033 1034 // If there are no tags in the string, the first space found is the right one. 1035 if ( empty( $truncate_tags ) ) { 1036 $spacepos = $pos; 1037 break; 1038 } 1039 1040 // Look at each tag to see if the space is inside of it. 1041 $intag = false; 1042 foreach ( $truncate_tags as $tt ) { 1043 if ( $pos > $tt['start'] && $pos < $tt['end'] ) { 1044 $intag = true; 1045 break; 1046 } 1047 } 1048 1049 if ( ! $intag ) { 1050 $spacepos = $pos; 1051 break; 1052 } 1053 } 1054 1055 if ( $r['html'] ) { 1056 $bits = mb_substr( $truncate, $spacepos ); 1057 preg_match_all( '/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER ); 1058 if ( !empty( $droppedTags ) ) { 1059 foreach ( $droppedTags as $closingTag ) { 1060 if ( !in_array( $closingTag[1], $openTags ) ) { 1061 array_unshift( $openTags, $closingTag[1] ); 1062 } 1063 } 1064 } 1065 } 1066 1067 $truncate = rtrim( mb_substr( $truncate, 0, $spacepos ) ); 1068 } 1069 $truncate .= $ending; 1070 1071 if ( !empty( $r['html'] ) ) { 1072 foreach ( $openTags as $tag ) { 1073 $truncate .= '</' . $tag . '>'; 1074 } 1075 } 1076 1077 /** This filter is documented in /bp-core/bp-core-template.php */ 1078 return apply_filters( 'bp_create_excerpt', $truncate, $original_text, $length, $options ); 1079 } 1080 add_filter( 'bp_create_excerpt', 'stripslashes_deep' ); 1081 add_filter( 'bp_create_excerpt', 'force_balance_tags' ); 1082 1083 /** 1084 * Output the total member count for the site. 1085 * 1086 * @since 1.2.0 1087 */ 1088 function bp_total_member_count() { 1089 echo bp_get_total_member_count(); 1090 } 1091 /** 1092 * Return the total member count in your BP instance. 1093 * 1094 * Since BuddyPress 1.6, this function has used bp_core_get_active_member_count(), 1095 * which counts non-spam, non-deleted users who have last_activity. 1096 * This value will correctly match the total member count number used 1097 * for pagination on member directories. 1098 * 1099 * Before BuddyPress 1.6, this function used bp_core_get_total_member_count(), 1100 * which did not take into account last_activity, and thus often 1101 * resulted in higher counts than shown by member directory pagination. 1102 * 1103 * @since 1.2.0 1104 * 1105 * @return int Member count. 1106 */ 1107 function bp_get_total_member_count() { 1108 1109 /** 1110 * Filters the total member count in your BP instance. 1111 * 1112 * @since 1.2.0 1113 * 1114 * @param int $value Member count. 1115 */ 1116 return apply_filters( 'bp_get_total_member_count', bp_core_get_active_member_count() ); 1117 } 1118 add_filter( 'bp_get_total_member_count', 'bp_core_number_format' ); 1119 1120 /** 1121 * Output whether blog signup is allowed. 1122 * 1123 * @todo Deprecate. It doesn't make any sense to echo a boolean. 1124 */ 1125 function bp_blog_signup_allowed() { 1126 echo bp_get_blog_signup_allowed(); 1127 } 1128 /** 1129 * Is blog signup allowed? 1130 * 1131 * Returns true if is_multisite() and blog creation is enabled at 1132 * Network Admin > Settings. 1133 * 1134 * @since 1.2.0 1135 * 1136 * @return bool True if blog signup is allowed, otherwise false. 1137 */ 1138 function bp_get_blog_signup_allowed() { 1139 1140 if ( ! is_multisite() ) { 1141 return false; 1142 } 1143 1144 $status = bp_core_get_root_option( 'registration' ); 1145 if ( ( 'none' !== $status ) && ( 'user' !== $status ) ) { 1146 return true; 1147 } 1148 1149 return false; 1150 } 1151 1152 /** 1153 * Check whether an activation has just been completed. 1154 * 1155 * @since 1.1.0 1156 * 1157 * @return bool True if the activation_complete global flag has been set, 1158 * otherwise false. 1159 */ 1160 function bp_account_was_activated() { 1161 $bp = buddypress(); 1162 1163 $activation_complete = ! empty( $bp->activation_complete ) || ( bp_is_current_component( 'activate' ) && ! empty( $_GET['activated'] ) ); 1164 1165 return $activation_complete; 1166 } 1167 1168 /** 1169 * Check whether registrations require activation on this installation. 1170 * 1171 * On a normal BuddyPress installation, all registrations require email 1172 * activation. This filter exists so that customizations that omit activation 1173 * can remove certain notification text from the registration screen. 1174 * 1175 * @since 1.2.0 1176 * 1177 * @return bool True by default. 1178 */ 1179 function bp_registration_needs_activation() { 1180 1181 /** 1182 * Filters whether registrations require activation on this installation. 1183 * 1184 * @since 1.2.0 1185 * 1186 * @param bool $value Whether registrations require activation. Default true. 1187 */ 1188 return apply_filters( 'bp_registration_needs_activation', true ); 1189 } 1190 1191 /** 1192 * Retrieve a client friendly version of the root blog name. 1193 * 1194 * The blogname option is escaped with esc_html on the way into the database in 1195 * sanitize_option, we want to reverse this for the plain text arena of emails. 1196 * 1197 * @since 1.7.0 1198 * @since 2.5.0 No longer used by BuddyPress, but not deprecated in case any existing plugins use it. 1199 * 1200 * @see https://buddypress.trac.wordpress.org/ticket/4401 1201 * 1202 * @param array $args { 1203 * Array of optional parameters. 1204 * @type string $before String to appear before the site name in the 1205 * email subject. Default: '['. 1206 * @type string $after String to appear after the site name in the 1207 * email subject. Default: ']'. 1208 * @type string $default The default site name, to be used when none is 1209 * found in the database. Default: 'Community'. 1210 * @type string $text Text to append to the site name (ie, the main text of 1211 * the email subject). 1212 * } 1213 * @return string Sanitized email subject. 1214 */ 1215 function bp_get_email_subject( $args = array() ) { 1216 1217 $r = bp_parse_args( $args, array( 1218 'before' => '[', 1219 'after' => ']', 1220 'default' => __( 'Community', 'buddypress' ), 1221 'text' => '' 1222 ), 'get_email_subject' ); 1223 1224 $subject = $r['before'] . wp_specialchars_decode( bp_get_option( 'blogname', $r['default'] ), ENT_QUOTES ) . $r['after'] . ' ' . $r['text']; 1225 1226 /** 1227 * Filters a client friendly version of the root blog name. 1228 * 1229 * @since 1.7.0 1230 * 1231 * @param string $subject Client friendly version of the root blog name. 1232 * @param array $r Array of arguments for the email subject. 1233 */ 1234 return apply_filters( 'bp_get_email_subject', $subject, $r ); 1235 } 1236 1237 /** 1238 * Allow templates to pass parameters directly into the template loops via AJAX. 1239 * 1240 * For the most part this will be filtered in a theme's functions.php for 1241 * example in the default theme it is filtered via bp_dtheme_ajax_querystring(). 1242 * 1243 * By using this template tag in the templates it will stop them from showing 1244 * errors if someone copies the templates from the default theme into another 1245 * WordPress theme without coping the functions from functions.php. 1246 * 1247 * @since 1.2.0 1248 * 1249 * @param string|bool $object Current template component. 1250 * @return string The AJAX querystring. 1251 */ 1252 function bp_ajax_querystring( $object = false ) { 1253 $bp = buddypress(); 1254 1255 if ( ! isset( $bp->ajax_querystring ) ) { 1256 $bp->ajax_querystring = ''; 1257 } 1258 1259 /** 1260 * Filters the template parameters to be used in the query string. 1261 * 1262 * Allows templates to pass parameters into the template loops via AJAX. 1263 * 1264 * @since 1.2.0 1265 * 1266 * @param string $ajax_querystring Current query string. 1267 * @param string $object Current template component. 1268 */ 1269 return apply_filters( 'bp_ajax_querystring', $bp->ajax_querystring, $object ); 1270 } 1271 1272 /** Template Classes and _is functions ****************************************/ 1273 1274 /** 1275 * Return the name of the current component. 1276 * 1277 * @since 1.0.0 1278 * 1279 * @return string Component name. 1280 */ 1281 function bp_current_component() { 1282 $bp = buddypress(); 1283 $current_component = !empty( $bp->current_component ) 1284 ? $bp->current_component 1285 : false; 1286 1287 /** 1288 * Filters the name of the current component. 1289 * 1290 * @since 1.0.0 1291 * 1292 * @param string|bool $current_component Current component if available or false. 1293 */ 1294 return apply_filters( 'bp_current_component', $current_component ); 1295 } 1296 1297 /** 1298 * Return the name of the current action. 1299 * 1300 * @since 1.0.0 1301 * 1302 * @return string Action name. 1303 */ 1304 function bp_current_action() { 1305 $bp = buddypress(); 1306 $current_action = !empty( $bp->current_action ) 1307 ? $bp->current_action 1308 : ''; 1309 1310 /** 1311 * Filters the name of the current action. 1312 * 1313 * @since 1.0.0 1314 * 1315 * @param string $current_action Current action. 1316 */ 1317 return apply_filters( 'bp_current_action', $current_action ); 1318 } 1319 1320 /** 1321 * Return the name of the current item. 1322 * 1323 * @since 1.1.0 1324 * 1325 * @return string|bool 1326 */ 1327 function bp_current_item() { 1328 $bp = buddypress(); 1329 $current_item = !empty( $bp->current_item ) 1330 ? $bp->current_item 1331 : false; 1332 1333 /** 1334 * Filters the name of the current item. 1335 * 1336 * @since 1.1.0 1337 * 1338 * @param string|bool $current_item Current item if available or false. 1339 */ 1340 return apply_filters( 'bp_current_item', $current_item ); 1341 } 1342 1343 /** 1344 * Return the value of $bp->action_variables. 1345 * 1346 * @since 1.0.0 1347 * 1348 * @return array|bool $action_variables The action variables array, or false 1349 * if the array is empty. 1350 */ 1351 function bp_action_variables() { 1352 $bp = buddypress(); 1353 $action_variables = !empty( $bp->action_variables ) 1354 ? $bp->action_variables 1355 : false; 1356 1357 /** 1358 * Filters the value of $bp->action_variables. 1359 * 1360 * @since 1.0.0 1361 * 1362 * @param array|bool $action_variables Available action variables. 1363 */ 1364 return apply_filters( 'bp_action_variables', $action_variables ); 1365 } 1366 1367 /** 1368 * Return the value of a given action variable. 1369 * 1370 * @since 1.5.0 1371 * 1372 * @param int $position The key of the action_variables array that you want. 1373 * @return string|bool $action_variable The value of that position in the 1374 * array, or false if not found. 1375 */ 1376 function bp_action_variable( $position = 0 ) { 1377 $action_variables = bp_action_variables(); 1378 $action_variable = isset( $action_variables[ $position ] ) 1379 ? $action_variables[ $position ] 1380 : false; 1381 1382 /** 1383 * Filters the value of a given action variable. 1384 * 1385 * @since 1.5.0 1386 * 1387 * @param string|bool $action_variable Requested action variable based on position. 1388 * @param int $position The key of the action variable requested. 1389 */ 1390 return apply_filters( 'bp_action_variable', $action_variable, $position ); 1391 } 1392 1393 /** 1394 * Output the "root domain", the URL of the BP root blog. 1395 * 1396 * @since 1.1.0 1397 */ 1398 function bp_root_domain() { 1399 echo bp_get_root_domain(); 1400 } 1401 /** 1402 * Return the "root domain", the URL of the BP root blog. 1403 * 1404 * @since 1.1.0 1405 * 1406 * @return string URL of the BP root blog. 1407 */ 1408 function bp_get_root_domain() { 1409 $bp = buddypress(); 1410 1411 if ( ! empty( $bp->root_domain ) ) { 1412 $domain = $bp->root_domain; 1413 } else { 1414 $domain = bp_core_get_root_domain(); 1415 $bp->root_domain = $domain; 1416 } 1417 1418 /** 1419 * Filters the "root domain", the URL of the BP root blog. 1420 * 1421 * @since 1.2.4 1422 * 1423 * @param string $domain URL of the BP root blog. 1424 */ 1425 return apply_filters( 'bp_get_root_domain', $domain ); 1426 } 1427 1428 /** 1429 * Output the root slug for a given component. 1430 * 1431 * @since 1.5.0 1432 * 1433 * @param string $component The component name. 1434 */ 1435 function bp_root_slug( $component = '' ) { 1436 echo bp_get_root_slug( $component ); 1437 } 1438 /** 1439 * Get the root slug for given component. 1440 * 1441 * The "root slug" is the string used when concatenating component 1442 * directory URLs. For example, on an installation where the Groups 1443 * component's directory is located at http://example.com/groups/, the 1444 * root slug for the Groups component is 'groups'. This string 1445 * generally corresponds to page_name of the component's directory 1446 * page. 1447 * 1448 * In order to maintain backward compatibility, the following procedure 1449 * is used: 1450 * 1) Use the short slug to get the canonical component name from the 1451 * active component array. 1452 * 2) Use the component name to get the root slug out of the 1453 * appropriate part of the $bp global. 1454 * 3) If nothing turns up, it probably means that $component is itself 1455 * a root slug. 1456 * 1457 * Example: If your groups directory is at /community/companies, this 1458 * function first uses the short slug 'companies' (ie the current 1459 * component) to look up the canonical name 'groups' in 1460 * $bp->active_components. Then it uses 'groups' to get the root slug, 1461 * from $bp->groups->root_slug. 1462 * 1463 * @since 1.5.0 1464 * 1465 * @param string $component Optional. Defaults to the current component. 1466 * @return string $root_slug The root slug. 1467 */ 1468 function bp_get_root_slug( $component = '' ) { 1469 $bp = buddypress(); 1470 $root_slug = ''; 1471 1472 // Use current global component if none passed. 1473 if ( empty( $component ) ) { 1474 $component = bp_current_component(); 1475 } 1476 1477 // Component is active. 1478 if ( ! empty( $bp->active_components[ $component ] ) ) { 1479 1480 // Backward compatibility: in legacy plugins, the canonical component id 1481 // was stored as an array value in $bp->active_components. 1482 $component_name = ( '1' == $bp->active_components[ $component ] ) 1483 ? $component 1484 : $bp->active_components[$component]; 1485 1486 // Component has specific root slug. 1487 if ( ! empty( $bp->{$component_name}->root_slug ) ) { 1488 $root_slug = $bp->{$component_name}->root_slug; 1489 } 1490 } 1491 1492 // No specific root slug, so fall back to component slug. 1493 if ( empty( $root_slug ) ) { 1494 $root_slug = $component; 1495 } 1496 1497 /** 1498 * Filters the root slug for given component. 1499 * 1500 * @since 1.5.0 1501 * 1502 * @param string $root_slug Root slug for given component. 1503 * @param string $component Current component. 1504 */ 1505 return apply_filters( 'bp_get_root_slug', $root_slug, $component ); 1506 } 1507 1508 /** 1509 * Return the component name based on a root slug. 1510 * 1511 * @since 1.5.0 1512 * 1513 * @param string $root_slug Needle to our active component haystack. 1514 * @return mixed False if none found, component name if found. 1515 */ 1516 function bp_get_name_from_root_slug( $root_slug = '' ) { 1517 $bp = buddypress(); 1518 1519 // If no slug is passed, look at current_component. 1520 if ( empty( $root_slug ) ) { 1521 $root_slug = bp_current_component(); 1522 } 1523 1524 // No current component or root slug, so flee. 1525 if ( empty( $root_slug ) ) { 1526 return false; 1527 } 1528 1529 // Loop through active components and look for a match. 1530 foreach ( array_keys( $bp->active_components ) as $component ) { 1531 if ( ( ! empty( $bp->{$component}->slug ) && ( $bp->{$component}->slug == $root_slug ) ) || ( ! empty( $bp->{$component}->root_slug ) && ( $bp->{$component}->root_slug === $root_slug ) ) ) { 1532 return $bp->{$component}->name; 1533 } 1534 } 1535 1536 return false; 1537 } 1538 1539 /** 1540 * Returns whether or not a user has access. 1541 * 1542 * @since 1.2.4 1543 * 1544 * @return bool 1545 */ 1546 function bp_user_has_access() { 1547 $has_access = bp_current_user_can( 'bp_moderate' ) || bp_is_my_profile(); 1548 1549 /** 1550 * Filters whether or not a user has access. 1551 * 1552 * @since 1.2.4 1553 * 1554 * @param bool $has_access Whether or not user has access. 1555 */ 1556 return (bool) apply_filters( 'bp_user_has_access', $has_access ); 1557 } 1558 1559 /** 1560 * Output the search slug. 1561 * 1562 * @since 1.5.0 1563 * 1564 */ 1565 function bp_search_slug() { 1566 echo bp_get_search_slug(); 1567 } 1568 /** 1569 * Return the search slug. 1570 * 1571 * @since 1.5.0 1572 * 1573 * @return string The search slug. Default: 'search'. 1574 */ 1575 function bp_get_search_slug() { 1576 1577 /** 1578 * Filters the search slug. 1579 * 1580 * @since 1.5.0 1581 * 1582 * @const string BP_SEARCH_SLUG The search slug. Default "search". 1583 */ 1584 return apply_filters( 'bp_get_search_slug', BP_SEARCH_SLUG ); 1585 } 1586 1587 /** 1588 * Get the ID of the currently displayed user. 1589 * 1590 * @since 1.0.0 1591 * 1592 * @return int $id ID of the currently displayed user. 1593 */ 1594 function bp_displayed_user_id() { 1595 $bp = buddypress(); 1596 $id = !empty( $bp->displayed_user->id ) 1597 ? $bp->displayed_user->id 1598 : 0; 1599 1600 /** 1601 * Filters the ID of the currently displayed user. 1602 * 1603 * @since 1.0.0 1604 * 1605 * @param int $id ID of the currently displayed user. 1606 */ 1607 return (int) apply_filters( 'bp_displayed_user_id', $id ); 1608 } 1609 1610 /** 1611 * Get the ID of the currently logged-in user. 1612 * 1613 * @since 1.0.0 1614 * 1615 * @return int ID of the logged-in user. 1616 */ 1617 function bp_loggedin_user_id() { 1618 $bp = buddypress(); 1619 $id = !empty( $bp->loggedin_user->id ) 1620 ? $bp->loggedin_user->id 1621 : 0; 1622 1623 /** 1624 * Filters the ID of the currently logged-in user. 1625 * 1626 * @since 1.0.0 1627 * 1628 * @param int $id ID of the currently logged-in user. 1629 */ 1630 return (int) apply_filters( 'bp_loggedin_user_id', $id ); 1631 } 1632 1633 /** The is_() functions to determine the current page *****************************/ 1634 1635 /** 1636 * Check to see whether the current page belongs to the specified component. 1637 * 1638 * This function is designed to be generous, accepting several different kinds 1639 * of value for the $component parameter. It checks $component_name against: 1640 * - the component's root_slug, which matches the page slug in $bp->pages. 1641 * - the component's regular slug. 1642 * - the component's id, or 'canonical' name. 1643 * 1644 * @since 1.5.0 1645 * 1646 * @param string $component Name of the component being checked. 1647 * @return bool Returns true if the component matches, or else false. 1648 */ 1649 function bp_is_current_component( $component = '' ) { 1650 1651 // Default is no match. We'll check a few places for matches. 1652 $is_current_component = false; 1653 1654 // Always return false if a null value is passed to the function. 1655 if ( empty( $component ) ) { 1656 return false; 1657 } 1658 1659 // Backward compatibility: 'xprofile' should be read as 'profile'. 1660 if ( 'xprofile' === $component ) { 1661 $component = 'profile'; 1662 } 1663 1664 $bp = buddypress(); 1665 1666 // Only check if BuddyPress found a current_component. 1667 if ( ! empty( $bp->current_component ) ) { 1668 1669 // First, check to see whether $component_name and the current 1670 // component are a simple match. 1671 if ( $bp->current_component == $component ) { 1672 $is_current_component = true; 1673 1674 // Since the current component is based on the visible URL slug let's 1675 // check the component being passed and see if its root_slug matches. 1676 } elseif ( isset( $bp->{$component}->root_slug ) && $bp->{$component}->root_slug == $bp->current_component ) { 1677 $is_current_component = true; 1678 1679 // Because slugs can differ from root_slugs, we should check them too. 1680 } elseif ( isset( $bp->{$component}->slug ) && $bp->{$component}->slug == $bp->current_component ) { 1681 $is_current_component = true; 1682 1683 // Next, check to see whether $component is a canonical, 1684 // non-translatable component name. If so, we can return its 1685 // corresponding slug from $bp->active_components. 1686 } elseif ( $key = array_search( $component, $bp->active_components ) ) { 1687 if ( strstr( $bp->current_component, $key ) ) { 1688 $is_current_component = true; 1689 } 1690 1691 // If we haven't found a match yet, check against the root_slugs 1692 // created by $bp->pages, as well as the regular slugs. 1693 } else { 1694 foreach ( $bp->active_components as $id ) { 1695 // If the $component parameter does not match the current_component, 1696 // then move along, these are not the droids you are looking for. 1697 if ( empty( $bp->{$id}->root_slug ) || $bp->{$id}->root_slug != $bp->current_component ) { 1698 continue; 1699 } 1700 1701 if ( $id == $component ) { 1702 $is_current_component = true; 1703 break; 1704 } 1705 } 1706 } 1707 } 1708 1709 /** 1710 * Filters whether the current page belongs to the specified component. 1711 * 1712 * @since 1.5.0 1713 * 1714 * @param bool $is_current_component Whether or not the current page belongs to specified component. 1715 * @param string $component Name of the component being checked. 1716 */ 1717 return apply_filters( 'bp_is_current_component', $is_current_component, $component ); 1718 } 1719 1720 /** 1721 * Check to see whether the current page matches a given action. 1722 * 1723 * Along with bp_is_current_component() and bp_is_action_variable(), this 1724 * function is mostly used to help determine when to use a given screen 1725 * function. 1726 * 1727 * In BP parlance, the current_action is the URL chunk that comes directly 1728 * after the current item slug. E.g., in 1729 * http://example.com/groups/my-group/members 1730 * the current_action is 'members'. 1731 * 1732 * @since 1.5.0 1733 * 1734 * @param string $action The action being tested against. 1735 * @return bool True if the current action matches $action. 1736 */ 1737 function bp_is_current_action( $action = '' ) { 1738 return (bool) ( $action === bp_current_action() ); 1739 } 1740 1741 /** 1742 * Check to see whether the current page matches a given action_variable. 1743 * 1744 * Along with bp_is_current_component() and bp_is_current_action(), this 1745 * function is mostly used to help determine when to use a given screen 1746 * function. 1747 * 1748 * In BP parlance, action_variables are an array made up of the URL chunks 1749 * appearing after the current_action in a URL. For example, 1750 * http://example.com/groups/my-group/admin/group-settings 1751 * $action_variables[0] is 'group-settings'. 1752 * 1753 * @since 1.5.0 1754 * 1755 * @param string $action_variable The action_variable being tested against. 1756 * @param int|bool $position Optional. The array key you're testing against. If you 1757 * don't provide a $position, the function will return true if the 1758 * $action_variable is found *anywhere* in the action variables array. 1759 * @return bool True if $action_variable matches at the $position provided. 1760 */ 1761 function bp_is_action_variable( $action_variable = '', $position = false ) { 1762 $is_action_variable = false; 1763 1764 if ( false !== $position ) { 1765 // When a $position is specified, check that slot in the action_variables array. 1766 if ( $action_variable ) { 1767 $is_action_variable = $action_variable == bp_action_variable( $position ); 1768 } else { 1769 // If no $action_variable is provided, we are essentially checking to see 1770 // whether the slot is empty. 1771 $is_action_variable = !bp_action_variable( $position ); 1772 } 1773 } else { 1774 // When no $position is specified, check the entire array. 1775 $is_action_variable = in_array( $action_variable, (array)bp_action_variables() ); 1776 } 1777 1778 /** 1779 * Filters whether the current page matches a given action_variable. 1780 * 1781 * @since 1.5.0 1782 * 1783 * @param bool $is_action_variable Whether the current page matches a given action_variable. 1784 * @param string $action_variable The action_variable being tested against. 1785 * @param int $position The array key tested against. 1786 */ 1787 return apply_filters( 'bp_is_action_variable', $is_action_variable, $action_variable, $position ); 1788 } 1789 1790 /** 1791 * Check against the current_item. 1792 * 1793 * @since 1.5.0 1794 * 1795 * @param string $item The item being checked. 1796 * @return bool True if $item is the current item. 1797 */ 1798 function bp_is_current_item( $item = '' ) { 1799 $retval = ( $item === bp_current_item() ); 1800 1801 /** 1802 * Filters whether or not an item is the current item. 1803 * 1804 * @since 2.1.0 1805 * 1806 * @param bool $retval Whether or not an item is the current item. 1807 * @param string $item The item being checked. 1808 */ 1809 return (bool) apply_filters( 'bp_is_current_item', $retval, $item ); 1810 } 1811 1812 /** 1813 * Are we looking at a single item? (group, user, etc). 1814 * 1815 * @since 1.1.0 1816 * 1817 * @return bool True if looking at a single item, otherwise false. 1818 */ 1819 function bp_is_single_item() { 1820 $bp = buddypress(); 1821 $retval = false; 1822 1823 if ( isset( $bp->is_single_item ) ) { 1824 $retval = $bp->is_single_item; 1825 } 1826 1827 /** 1828 * Filters whether or not an item is the a single item. (group, user, etc) 1829 * 1830 * @since 2.1.0 1831 * 1832 * @param bool $retval Whether or not an item is a single item. 1833 */ 1834 return (bool) apply_filters( 'bp_is_single_item', $retval ); 1835 } 1836 1837 /** 1838 * Is the logged-in user an admin for the current item? 1839 * 1840 * @since 1.5.0 1841 * 1842 * @return bool True if the current user is an admin for the current item, 1843 * otherwise false. 1844 */ 1845 function bp_is_item_admin() { 1846 $bp = buddypress(); 1847 $retval = false; 1848 1849 if ( isset( $bp->is_item_admin ) ) { 1850 $retval = $bp->is_item_admin; 1851 } 1852 1853 /** 1854 * Filters whether or not the logged-in user is an admin for the current item. 1855 * 1856 * @since 2.1.0 1857 * 1858 * @param bool $retval Whether or not the logged-in user is an admin. 1859 */ 1860 return (bool) apply_filters( 'bp_is_item_admin', $retval ); 1861 } 1862 1863 /** 1864 * Is the logged-in user a mod for the current item? 1865 * 1866 * @since 1.5.0 1867 * 1868 * @return bool True if the current user is a mod for the current item, 1869 * otherwise false. 1870 */ 1871 function bp_is_item_mod() { 1872 $bp = buddypress(); 1873 $retval = false; 1874 1875 if ( isset( $bp->is_item_mod ) ) { 1876 $retval = $bp->is_item_mod; 1877 } 1878 1879 /** 1880 * Filters whether or not the logged-in user is a mod for the current item. 1881 * 1882 * @since 2.1.0 1883 * 1884 * @param bool $retval Whether or not the logged-in user is a mod. 1885 */ 1886 return (bool) apply_filters( 'bp_is_item_mod', $retval ); 1887 } 1888 1889 /** 1890 * Is this a component directory page? 1891 * 1892 * @since 1.0.0 1893 * 1894 * @return bool True if the current page is a component directory, otherwise false. 1895 */ 1896 function bp_is_directory() { 1897 $bp = buddypress(); 1898 $retval = false; 1899 1900 if ( isset( $bp->is_directory ) ) { 1901 $retval = $bp->is_directory; 1902 } 1903 1904 /** 1905 * Filters whether or not user is on a component directory page. 1906 * 1907 * @since 2.1.0 1908 * 1909 * @param bool $retval Whether or not user is on a component directory page. 1910 */ 1911 return (bool) apply_filters( 'bp_is_directory', $retval ); 1912 } 1913 1914 /** 1915 * Check to see if a component's URL should be in the root, not under a member page. 1916 * 1917 * - Yes ('groups' is root) : http://example.com/groups/the-group 1918 * - No ('groups' is not-root): http://example.com/members/andy/groups/the-group 1919 * 1920 * This function is on the chopping block. It's currently only used by a few 1921 * already deprecated functions. 1922 * 1923 * @since 1.5.0 1924 * 1925 * @param string $component_name Component name to check. 1926 * 1927 * @return bool True if root component, else false. 1928 */ 1929 function bp_is_root_component( $component_name = '' ) { 1930 $bp = buddypress(); 1931 $retval = false; 1932 1933 // Default to the current component if none is passed. 1934 if ( empty( $component_name ) ) { 1935 $component_name = bp_current_component(); 1936 } 1937 1938 // Loop through active components and check for key/slug matches. 1939 if ( ! empty( $bp->active_components ) ) { 1940 foreach ( (array) $bp->active_components as $key => $slug ) { 1941 if ( ( $key === $component_name ) || ( $slug === $component_name ) ) { 1942 $retval = true; 1943 break; 1944 } 1945 } 1946 } 1947 1948 /** 1949 * Filters whether or not a component's URL should be in the root, not under a member page. 1950 * 1951 * @since 2.1.0 1952 * 1953 * @param bool $retval Whether or not URL should be in the root. 1954 */ 1955 return (bool) apply_filters( 'bp_is_root_component', $retval ); 1956 } 1957 1958 /** 1959 * Check if the specified BuddyPress component directory is set to be the front page. 1960 * 1961 * Corresponds to the setting in wp-admin's Settings > Reading screen. 1962 * 1963 * @since 1.5.0 1964 * 1965 * @global int $current_blog WordPress global for the current blog. 1966 * 1967 * @param string $component Optional. Name of the component to check for. 1968 * Default: current component. 1969 * @return bool True if the specified component is set to be the site's front 1970 * page, otherwise false. 1971 */ 1972 function bp_is_component_front_page( $component = '' ) { 1973 global $current_blog; 1974 1975 $bp = buddypress(); 1976 1977 // Default to the current component if none is passed. 1978 if ( empty( $component ) ) { 1979 $component = bp_current_component(); 1980 } 1981 1982 // Get the path for the current blog/site. 1983 $path = is_main_site() 1984 ? bp_core_get_site_path() 1985 : $current_blog->path; 1986 1987 // Get the front page variables. 1988 $show_on_front = get_option( 'show_on_front' ); 1989 $page_on_front = get_option( 'page_on_front' ); 1990 1991 if ( ( 'page' !== $show_on_front ) || empty( $component ) || empty( $bp->pages->{$component} ) || ( $_SERVER['REQUEST_URI'] !== $path ) ) { 1992 return false; 1993 } 1994 1995 /** 1996 * Filters whether or not the specified BuddyPress component directory is set to be the front page. 1997 * 1998 * @since 1.5.0 1999 * 2000 * @param bool $value Whether or not the specified component directory is set as front page. 2001 * @param string $component Current component being checked. 2002 */ 2003 return (bool) apply_filters( 'bp_is_component_front_page', ( $bp->pages->{$component}->id == $page_on_front ), $component ); 2004 } 2005 2006 /** 2007 * Is this a blog page, ie a non-BP page? 2008 * 2009 * You can tell if a page is displaying BP content by whether the 2010 * current_component has been defined. 2011 * 2012 * @since 1.0.0 2013 * 2014 * @return bool True if it's a non-BP page, false otherwise. 2015 */ 2016 function bp_is_blog_page() { 2017 2018 $is_blog_page = false; 2019 2020 // Generally, we can just check to see that there's no current component. 2021 // The one exception is single user home tabs, where $bp->current_component 2022 // is unset. Thus the addition of the bp_is_user() check. 2023 if ( ! bp_current_component() && ! bp_is_user() ) { 2024 $is_blog_page = true; 2025 } 2026 2027 /** 2028 * Filters whether or not current page is a blog page or not. 2029 * 2030 * @since 1.5.0 2031 * 2032 * @param bool $is_blog_page Whether or not current page is a blog page. 2033 */ 2034 return (bool) apply_filters( 'bp_is_blog_page', $is_blog_page ); 2035 } 2036 2037 /** 2038 * Is this a BuddyPress component? 2039 * 2040 * You can tell if a page is displaying BP content by whether the 2041 * current_component has been defined. 2042 * 2043 * Generally, we can just check to see that there's no current component. 2044 * The one exception is single user home tabs, where $bp->current_component 2045 * is unset. Thus the addition of the bp_is_user() check. 2046 * 2047 * @since 1.7.0 2048 * 2049 * @return bool True if it's a BuddyPress page, false otherwise. 2050 */ 2051 function is_buddypress() { 2052 $retval = (bool) ( bp_current_component() || bp_is_user() ); 2053 2054 /** 2055 * Filters whether or not this is a BuddyPress component. 2056 * 2057 * @since 1.7.0 2058 * 2059 * @param bool $retval Whether or not this is a BuddyPress component. 2060 */ 2061 return apply_filters( 'is_buddypress', $retval ); 2062 } 2063 2064 /** Components ****************************************************************/ 2065 2066 /** 2067 * Check whether a given component (or feature of a component) is active. 2068 * 2069 * @since 1.2.0 See r2539. 2070 * @since 2.3.0 Added $feature as a parameter. 2071 * 2072 * @param string $component The component name. 2073 * @param string $feature The feature name. 2074 * @return bool 2075 */ 2076 function bp_is_active( $component = '', $feature = '' ) { 2077 $retval = false; 2078 2079 // Default to the current component if none is passed. 2080 if ( empty( $component ) ) { 2081 $component = bp_current_component(); 2082 } 2083 2084 // Is component in either the active or required components arrays. 2085 if ( isset( buddypress()->active_components[ $component ] ) || in_array( $component, buddypress()->required_components, true ) ) { 2086 $retval = true; 2087 2088 // Is feature active? 2089 if ( ! empty( $feature ) ) { 2090 // The xProfile component is specific. 2091 if ( 'xprofile' === $component ) { 2092 $component = 'profile'; 2093 2094 // The Cover Image feature has been moved to the Members component in 6.0.0. 2095 if ( 'cover_image' === $feature && 'profile' === $component ) { 2096 _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' ); 2097 $members_component = buddypress()->members; 2098 2099 if ( ! isset( $members_component->features ) || false === in_array( $feature, $members_component->features, true ) ) { 2100 $retval = false; 2101 } 2102 2103 /** This filter is documented in wp-includes/deprecated.php */ 2104 return apply_filters_deprecated( 'bp_is_profile_cover_image_active', array( $retval ), '6.0.0', 'bp_is_members_cover_image_active' ); 2105 } 2106 } 2107 2108 $component_features = isset( buddypress()->{$component}->features ) ? buddypress()->{$component}->features : array(); 2109 2110 if ( empty( $component_features ) || false === in_array( $feature, $component_features, true ) ) { 2111 $retval = false; 2112 } 2113 2114 /** 2115 * Filters whether or not a given feature for a component is active. 2116 * 2117 * This is a variable filter that is based on the component and feature 2118 * that you are checking of active status of. 2119 * 2120 * @since 2.3.0 2121 * 2122 * @param bool $retval 2123 */ 2124 $retval = apply_filters( "bp_is_{$component}_{$feature}_active", $retval ); 2125 } 2126 } 2127 2128 /** 2129 * Filters whether or not a given component has been activated by the admin. 2130 * 2131 * @since 2.1.0 2132 * 2133 * @param bool $retval Whether or not a given component has been activated by the admin. 2134 * @param string $component Current component being checked. 2135 */ 2136 return apply_filters( 'bp_is_active', $retval, $component ); 2137 } 2138 2139 /** 2140 * Check whether the current page is part of the Members component. 2141 * 2142 * @since 1.5.0 2143 * 2144 * @return bool True if the current page is part of the Members component. 2145 */ 2146 function bp_is_members_component() { 2147 return (bool) bp_is_current_component( 'members' ); 2148 } 2149 2150 /** 2151 * Check whether the current page is part of the Profile component. 2152 * 2153 * @since 1.1.0 2154 * 2155 * @return bool True if the current page is part of the Profile component. 2156 */ 2157 function bp_is_profile_component() { 2158 return (bool) bp_is_current_component( 'xprofile' ); 2159 } 2160 2161 /** 2162 * Check whether the current page is part of the Activity component. 2163 * 2164 * @since 1.1.0 2165 * 2166 * @return bool True if the current page is part of the Activity component. 2167 */ 2168 function bp_is_activity_component() { 2169 return (bool) bp_is_current_component( 'activity' ); 2170 } 2171 2172 /** 2173 * Check whether the current page is part of the Blogs component. 2174 * 2175 * @since 1.1.0 2176 * 2177 * @return bool True if the current page is part of the Blogs component. 2178 */ 2179 function bp_is_blogs_component() { 2180 return (bool) ( is_multisite() && bp_is_current_component( 'blogs' ) ); 2181 } 2182 2183 /** 2184 * Check whether the current page is part of the Messages component. 2185 * 2186 * @since 1.1.0 2187 * 2188 * @return bool True if the current page is part of the Messages component. 2189 */ 2190 function bp_is_messages_component() { 2191 return (bool) bp_is_current_component( 'messages' ); 2192 } 2193 2194 /** 2195 * Check whether the current page is part of the Friends component. 2196 * 2197 * @since 1.1.0 2198 * 2199 * @return bool True if the current page is part of the Friends component. 2200 */ 2201 function bp_is_friends_component() { 2202 return (bool) bp_is_current_component( 'friends' ); 2203 } 2204 2205 /** 2206 * Check whether the current page is part of the Groups component. 2207 * 2208 * @since 1.1.0 2209 * 2210 * @return bool True if the current page is part of the Groups component. 2211 */ 2212 function bp_is_groups_component() { 2213 return (bool) bp_is_current_component( 'groups' ); 2214 } 2215 2216 /** 2217 * Check whether the current page is part of the Forums component. 2218 * 2219 * @since 1.5.0 2220 * @since 3.0.0 Required for bbPress 2 integration. 2221 * 2222 * @return bool True if the current page is part of the Forums component. 2223 */ 2224 function bp_is_forums_component() { 2225 return (bool) bp_is_current_component( 'forums' ); 2226 } 2227 2228 /** 2229 * Check whether the current page is part of the Notifications component. 2230 * 2231 * @since 1.9.0 2232 * 2233 * @return bool True if the current page is part of the Notifications component. 2234 */ 2235 function bp_is_notifications_component() { 2236 return (bool) bp_is_current_component( 'notifications' ); 2237 } 2238 2239 /** 2240 * Check whether the current page is part of the Settings component. 2241 * 2242 * @since 1.1.0 2243 * 2244 * @return bool True if the current page is part of the Settings component. 2245 */ 2246 function bp_is_settings_component() { 2247 return (bool) bp_is_current_component( 'settings' ); 2248 } 2249 2250 /** 2251 * Is the current component an active core component? 2252 * 2253 * Use this function when you need to check if the current component is an 2254 * active core component of BuddyPress. If the current component is inactive, it 2255 * will return false. If the current component is not part of BuddyPress core, 2256 * it will return false. If the current component is active, and is part of 2257 * BuddyPress core, it will return true. 2258 * 2259 * @since 1.7.0 2260 * 2261 * @return bool True if the current component is active and is one of BP's 2262 * packaged components. 2263 */ 2264 function bp_is_current_component_core() { 2265 $retval = false; 2266 2267 foreach ( bp_core_get_packaged_component_ids() as $active_component ) { 2268 if ( bp_is_current_component( $active_component ) ) { 2269 $retval = true; 2270 break; 2271 } 2272 } 2273 2274 return $retval; 2275 } 2276 2277 /** Activity ******************************************************************/ 2278 2279 /** 2280 * Is the current page the activity directory? 2281 * 2282 * @since 2.0.0 2283 * 2284 * @return bool True if the current page is the activity directory. 2285 */ 2286 function bp_is_activity_directory() { 2287 if ( ! bp_displayed_user_id() && bp_is_activity_component() && ! bp_current_action() ) { 2288 return true; 2289 } 2290 2291 return false; 2292 } 2293 2294 /** 2295 * Is the current page a single activity item permalink? 2296 * 2297 * @since 1.5.0 2298 * 2299 * @return bool True if the current page is a single activity item permalink. 2300 */ 2301 function bp_is_single_activity() { 2302 return (bool) ( bp_is_activity_component() && is_numeric( bp_current_action() ) ); 2303 } 2304 2305 /** User **********************************************************************/ 2306 2307 /** 2308 * Is the current page the members directory? 2309 * 2310 * @since 2.0.0 2311 * 2312 * @return bool True if the current page is the members directory. 2313 */ 2314 function bp_is_members_directory() { 2315 if ( ! bp_is_user() && bp_is_members_component() ) { 2316 return true; 2317 } 2318 2319 return false; 2320 } 2321 2322 /** 2323 * Is the current page part of the profile of the logged-in user? 2324 * 2325 * Will return true for any subpage of the logged-in user's profile, eg 2326 * http://example.com/members/joe/friends/. 2327 * 2328 * @since 1.2.0 2329 * 2330 * @return bool True if the current page is part of the profile of the logged-in user. 2331 */ 2332 function bp_is_my_profile() { 2333 if ( is_user_logged_in() && bp_loggedin_user_id() == bp_displayed_user_id() ) { 2334 $my_profile = true; 2335 } else { 2336 $my_profile = false; 2337 } 2338 2339 /** 2340 * Filters whether or not current page is part of the profile for the logged-in user. 2341 * 2342 * @since 1.2.4 2343 * 2344 * @param bool $my_profile Whether or not current page is part of the profile for the logged-in user. 2345 */ 2346 return apply_filters( 'bp_is_my_profile', $my_profile ); 2347 } 2348 2349 /** 2350 * Is the current page a user page? 2351 * 2352 * Will return true anytime there is a displayed user. 2353 * 2354 * @since 1.5.0 2355 * 2356 * @return bool True if the current page is a user page. 2357 */ 2358 function bp_is_user() { 2359 return (bool) bp_displayed_user_id(); 2360 } 2361 2362 /** 2363 * Is the current page a user custom front page? 2364 * 2365 * Will return true anytime there is a custom front page for the displayed user. 2366 * 2367 * @since 2.6.0 2368 * 2369 * @return bool True if the current page is a user custom front page. 2370 */ 2371 function bp_is_user_front() { 2372 return (bool) ( bp_is_user() && bp_is_current_component( 'front' ) ); 2373 } 2374 2375 /** 2376 * Is the current page a user's activity stream page? 2377 * 2378 * Eg http://example.com/members/joe/activity/ (or any subpages thereof). 2379 * 2380 * @since 1.1.0 2381 * 2382 * @return bool True if the current page is a user's activity stream page. 2383 */ 2384 function bp_is_user_activity() { 2385 return (bool) ( bp_is_user() && bp_is_activity_component() ); 2386 } 2387 2388 /** 2389 * Is the current page a user's Friends activity stream? 2390 * 2391 * Eg http://example.com/members/joe/friends/ 2392 * 2393 * @since 1.1.0 2394 * 2395 * @return bool True if the current page is a user's Friends activity stream. 2396 */ 2397 function bp_is_user_friends_activity() { 2398 2399 if ( ! bp_is_active( 'friends' ) ) { 2400 return false; 2401 } 2402 2403 $slug = bp_get_friends_slug(); 2404 2405 if ( empty( $slug ) ) { 2406 $slug = 'friends'; 2407 } 2408 2409 if ( bp_is_user_activity() && bp_is_current_action( $slug ) ) { 2410 return true; 2411 } 2412 2413 return false; 2414 } 2415 2416 /** 2417 * Is the current page a user's Groups activity stream? 2418 * 2419 * Eg http://example.com/members/joe/groups/ 2420 * 2421 * @since 1.5.0 2422 * 2423 * @return bool True if the current page is a user's Groups activity stream. 2424 */ 2425 function bp_is_user_groups_activity() { 2426 2427 if ( ! bp_is_active( 'groups' ) ) { 2428 return false; 2429 } 2430 2431 $slug = ( bp_get_groups_slug() ) 2432 ? bp_get_groups_slug() 2433 : 'groups'; 2434 2435 if ( bp_is_user_activity() && bp_is_current_action( $slug ) ) { 2436 return true; 2437 } 2438 2439 return false; 2440 } 2441 2442 /** 2443 * Is the current page part of a user's extended profile? 2444 * 2445 * Eg http://example.com/members/joe/profile/ (or a subpage thereof). 2446 * 2447 * @since 1.1.0 2448 * 2449 * @return bool True if the current page is part of a user's extended profile. 2450 */ 2451 function bp_is_user_profile() { 2452 return (bool) ( bp_is_profile_component() || bp_is_current_component( 'profile' ) ); 2453 } 2454 2455 /** 2456 * Is the current page part of a user's profile editing section? 2457 * 2458 * Eg http://example.com/members/joe/profile/edit/ (or a subpage thereof). 2459 * 2460 * @since 1.5.0 2461 * 2462 * @return bool True if the current page is a user's profile edit page. 2463 */ 2464 function bp_is_user_profile_edit() { 2465 return (bool) ( bp_is_profile_component() && bp_is_current_action( 'edit' ) ); 2466 } 2467 2468 /** 2469 * Is the current page part of a user's profile avatar editing section? 2470 * 2471 * Eg http://example.com/members/joe/profile/change-avatar/ (or a subpage thereof). 2472 * 2473 * @since 1.5.0 2474 * 2475 * @return bool True if the current page is the user's avatar edit page. 2476 */ 2477 function bp_is_user_change_avatar() { 2478 return (bool) ( bp_is_profile_component() && bp_is_current_action( 'change-avatar' ) ); 2479 } 2480 2481 /** 2482 * Is the current page the a user's change cover image profile page? 2483 * 2484 * Eg http://example.com/members/joe/profile/change-cover-image/ (or a subpage thereof). 2485 * 2486 * @since 2.4.0 2487 * 2488 * @return bool True if the current page is a user's profile edit cover image page. 2489 */ 2490 function bp_is_user_change_cover_image() { 2491 return (bool) ( bp_is_profile_component() && bp_is_current_action( 'change-cover-image' ) ); 2492 } 2493 2494 /** 2495 * Is the current page part of a user's Groups page? 2496 * 2497 * Eg http://example.com/members/joe/groups/ (or a subpage thereof). 2498 * 2499 * @since 1.1.0 2500 * 2501 * @return bool True if the current page is a user's Groups page. 2502 */ 2503 function bp_is_user_groups() { 2504 return (bool) ( bp_is_user() && bp_is_groups_component() ); 2505 } 2506 2507 /** 2508 * Is the current page part of a user's Blogs page? 2509 * 2510 * Eg http://example.com/members/joe/blogs/ (or a subpage thereof). 2511 * 2512 * @since 1.1.0 2513 * 2514 * @return bool True if the current page is a user's Blogs page. 2515 */ 2516 function bp_is_user_blogs() { 2517 return (bool) ( bp_is_user() && bp_is_blogs_component() ); 2518 } 2519 2520 /** 2521 * Is the current page a user's Recent Blog Posts page? 2522 * 2523 * Eg http://example.com/members/joe/blogs/recent-posts/. 2524 * 2525 * @since 1.1.0 2526 * 2527 * @return bool True if the current page is a user's Recent Blog Posts page. 2528 */ 2529 function bp_is_user_recent_posts() { 2530 return (bool) ( bp_is_user_blogs() && bp_is_current_action( 'recent-posts' ) ); 2531 } 2532 2533 /** 2534 * Is the current page a user's Recent Blog Comments page? 2535 * 2536 * Eg http://example.com/members/joe/blogs/recent-comments/. 2537 * 2538 * @since 1.1.0 2539 * 2540 * @return bool True if the current page is a user's Recent Blog Comments page. 2541 */ 2542 function bp_is_user_recent_commments() { 2543 return (bool) ( bp_is_user_blogs() && bp_is_current_action( 'recent-comments' ) ); 2544 } 2545 2546 /** 2547 * Is the current page a user's Friends page? 2548 * 2549 * Eg http://example.com/members/joe/blogs/friends/ (or a subpage thereof). 2550 * 2551 * @since 1.1.0 2552 * 2553 * @return bool True if the current page is a user's Friends page. 2554 */ 2555 function bp_is_user_friends() { 2556 return (bool) ( bp_is_user() && bp_is_friends_component() ); 2557 } 2558 2559 /** 2560 * Is the current page a user's Friend Requests page? 2561 * 2562 * Eg http://example.com/members/joe/friends/requests/. 2563 * 2564 * @since 1.5.0 2565 * 2566 * @return bool True if the current page is a user's Friends Requests page. 2567 */ 2568 function bp_is_user_friend_requests() { 2569 return (bool) ( bp_is_user_friends() && bp_is_current_action( 'requests' ) ); 2570 } 2571 2572 /** 2573 * Is this a user's notifications page? 2574 * 2575 * Eg http://example.com/members/joe/notifications/ (or a subpage thereof). 2576 * 2577 * @since 1.9.0 2578 * 2579 * @return bool True if the current page is a user's Notifications page. 2580 */ 2581 function bp_is_user_notifications() { 2582 return (bool) ( bp_is_user() && bp_is_notifications_component() ); 2583 } 2584 2585 /** 2586 * Is this a user's settings page? 2587 * 2588 * Eg http://example.com/members/joe/settings/ (or a subpage thereof). 2589 * 2590 * @since 1.5.0 2591 * 2592 * @return bool True if the current page is a user's Settings page. 2593 */ 2594 function bp_is_user_settings() { 2595 return (bool) ( bp_is_user() && bp_is_settings_component() ); 2596 } 2597 2598 /** 2599 * Is this a user's General Settings page? 2600 * 2601 * Eg http://example.com/members/joe/settings/general/. 2602 * 2603 * @since 1.5.0 2604 * 2605 * @return bool True if the current page is a user's General Settings page. 2606 */ 2607 function bp_is_user_settings_general() { 2608 return (bool) ( bp_is_user_settings() && bp_is_current_action( 'general' ) ); 2609 } 2610 2611 /** 2612 * Is this a user's Notification Settings page? 2613 * 2614 * Eg http://example.com/members/joe/settings/notifications/. 2615 * 2616 * @since 1.5.0 2617 * 2618 * @return bool True if the current page is a user's Notification Settings page. 2619 */ 2620 function bp_is_user_settings_notifications() { 2621 return (bool) ( bp_is_user_settings() && bp_is_current_action( 'notifications' ) ); 2622 } 2623 2624 /** 2625 * Is this a user's Account Deletion page? 2626 * 2627 * Eg http://example.com/members/joe/settings/delete-account/. 2628 * 2629 * @since 1.5.0 2630 * 2631 * @return bool True if the current page is a user's Delete Account page. 2632 */ 2633 function bp_is_user_settings_account_delete() { 2634 return (bool) ( bp_is_user_settings() && bp_is_current_action( 'delete-account' ) ); 2635 } 2636 2637 /** 2638 * Is this a user's profile settings? 2639 * 2640 * Eg http://example.com/members/joe/settings/profile/. 2641 * 2642 * @since 2.0.0 2643 * 2644 * @return bool True if the current page is a user's Profile Settings page. 2645 */ 2646 function bp_is_user_settings_profile() { 2647 return (bool) ( bp_is_user_settings() && bp_is_current_action( 'profile' ) ); 2648 } 2649 2650 /** Groups ********************************************************************/ 2651 2652 /** 2653 * Is the current page the groups directory? 2654 * 2655 * @since 2.0.0 2656 * 2657 * @return bool True if the current page is the groups directory. 2658 */ 2659 function bp_is_groups_directory() { 2660 if ( bp_is_groups_component() && ! bp_is_group() && ( ! bp_current_action() || ( bp_action_variable() && bp_is_current_action( bp_get_groups_group_type_base() ) ) ) ) { 2661 return true; 2662 } 2663 2664 return false; 2665 } 2666 2667 /** 2668 * Does the current page belong to a single group? 2669 * 2670 * Will return true for any subpage of a single group. 2671 * 2672 * @since 1.2.0 2673 * 2674 * @return bool True if the current page is part of a single group. 2675 */ 2676 function bp_is_group() { 2677 $retval = bp_is_active( 'groups' ); 2678 2679 if ( ! empty( $retval ) ) { 2680 $retval = bp_is_groups_component() && groups_get_current_group(); 2681 } 2682 2683 return (bool) $retval; 2684 } 2685 2686 /** 2687 * Is the current page a single group's home page? 2688 * 2689 * URL will vary depending on which group tab is set to be the "home". By 2690 * default, it's the group's recent activity. 2691 * 2692 * @since 1.1.0 2693 * 2694 * @return bool True if the current page is a single group's home page. 2695 */ 2696 function bp_is_group_home() { 2697 if ( bp_is_single_item() && bp_is_groups_component() && ( ! bp_current_action() || bp_is_current_action( 'home' ) ) ) { 2698 return true; 2699 } 2700 2701 return false; 2702 } 2703 2704 /** 2705 * Is the current page part of the group creation process? 2706 * 2707 * @since 1.1.0 2708 * 2709 * @return bool True if the current page is part of the group creation process. 2710 */ 2711 function bp_is_group_create() { 2712 return (bool) ( bp_is_groups_component() && bp_is_current_action( 'create' ) ); 2713 } 2714 2715 /** 2716 * Is the current page part of a single group's admin screens? 2717 * 2718 * Eg http://example.com/groups/mygroup/admin/settings/. 2719 * 2720 * @since 1.1.0 2721 * 2722 * @return bool True if the current page is part of a single group's admin. 2723 */ 2724 function bp_is_group_admin_page() { 2725 return (bool) ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'admin' ) ); 2726 } 2727 2728 /** 2729 * Is the current page a group's activity page? 2730 * 2731 * @since 1.2.1 2732 * 2733 * @return bool True if the current page is a group's activity page. 2734 */ 2735 function bp_is_group_activity() { 2736 $retval = false; 2737 2738 if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'activity' ) ) { 2739 $retval = true; 2740 } 2741 2742 if ( bp_is_group_home() && bp_is_active( 'activity' ) && ! bp_is_group_custom_front() ) { 2743 $retval = true; 2744 } 2745 2746 return $retval; 2747 } 2748 2749 /** 2750 * Is the current page a group forum topic? 2751 * 2752 * @since 1.1.0 2753 * @since 3.0.0 Required for bbPress 2 integration. 2754 * 2755 * @return bool True if the current page is part of a group forum topic. 2756 */ 2757 function bp_is_group_forum_topic() { 2758 return (bool) ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'forum' ) && bp_is_action_variable( 'topic', 0 ) ); 2759 } 2760 2761 /** 2762 * Is the current page a group forum topic edit page? 2763 * 2764 * @since 1.2.0 2765 * @since 3.0.0 Required for bbPress 2 integration. 2766 * 2767 * @return bool True if the current page is part of a group forum topic edit page. 2768 */ 2769 function bp_is_group_forum_topic_edit() { 2770 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 ) ); 2771 } 2772 2773 /** 2774 * Is the current page a group's Members page? 2775 * 2776 * Eg http://example.com/groups/mygroup/members/. 2777 * 2778 * @since 1.1.0 2779 * 2780 * @return bool True if the current page is part of a group's Members page. 2781 */ 2782 function bp_is_group_members() { 2783 $retval = false; 2784 2785 if ( bp_is_single_item() && bp_is_groups_component() && bp_is_current_action( 'members' ) ) { 2786 $retval = true; 2787 } 2788 2789 if ( bp_is_group_home() && ! bp_is_active( 'activity' ) && ! bp_is_group_custom_front() ) { 2790 $retval = true; 2791 } 2792 2793 return $retval; 2794 } 2795 2796 /** 2797 * Is the current page a group's Invites page? 2798 * 2799 * Eg http://example.com/groups/mygroup/send-invites/. 2800 * 2801 * @since 1.1.0 2802 * 2803 * @return bool True if the current page is a group's Send Invites page. 2804 */ 2805 function bp_is_group_invites() { 2806 return (bool) ( bp_is_groups_component() && bp_is_current_action( 'send-invites' ) ); 2807 } 2808 2809 /** 2810 * Is the current page a group's Request Membership page? 2811 * 2812 * Eg http://example.com/groups/mygroup/request-membership/. 2813 * 2814 * @since 1.2.0 2815 * 2816 * @return bool True if the current page is a group's Request Membership page. 2817 */ 2818 function bp_is_group_membership_request() { 2819 return (bool) ( bp_is_groups_component() && bp_is_current_action( 'request-membership' ) ); 2820 } 2821 2822 /** 2823 * Is the current page a leave group attempt? 2824 * 2825 * @since 1.1.0 2826 * 2827 * @return bool True if the current page is a Leave Group attempt. 2828 */ 2829 function bp_is_group_leave() { 2830 return (bool) ( bp_is_groups_component() && bp_is_single_item() && bp_is_current_action( 'leave-group' ) ); 2831 } 2832 2833 /** 2834 * Is the current page part of a single group? 2835 * 2836 * Not currently used by BuddyPress. 2837 * 2838 * @todo How is this functionally different from bp_is_group()? 2839 * 2840 * @return bool True if the current page is part of a single group. 2841 */ 2842 function bp_is_group_single() { 2843 return (bool) ( bp_is_groups_component() && bp_is_single_item() ); 2844 } 2845 2846 /** 2847 * Is the current group page a custom front? 2848 * 2849 * @since 2.4.0 2850 * 2851 * @return bool True if the current group page is a custom front. 2852 */ 2853 function bp_is_group_custom_front() { 2854 $bp = buddypress(); 2855 return (bool) bp_is_group_home() && ! empty( $bp->groups->current_group->front_template ); 2856 } 2857 2858 /** 2859 * Is the current page the Create a Blog page? 2860 * 2861 * Eg http://example.com/sites/create/. 2862 * 2863 * @since 1.1.0 2864 * 2865 * @return bool True if the current page is the Create a Blog page. 2866 */ 2867 function bp_is_create_blog() { 2868 return (bool) ( bp_is_blogs_component() && bp_is_current_action( 'create' ) ); 2869 } 2870 2871 /** 2872 * Is the current page the blogs directory ? 2873 * 2874 * @since 2.0.0 2875 * 2876 * @return bool True if the current page is the blogs directory. 2877 */ 2878 function bp_is_blogs_directory() { 2879 if ( is_multisite() && bp_is_blogs_component() && ! bp_current_action() ) { 2880 return true; 2881 } 2882 2883 return false; 2884 } 2885 2886 /** Messages ******************************************************************/ 2887 2888 /** 2889 * Is the current page part of a user's Messages pages? 2890 * 2891 * Eg http://example.com/members/joe/messages/ (or a subpage thereof). 2892 * 2893 * @since 1.2.0 2894 * 2895 * @return bool True if the current page is part of a user's Messages pages. 2896 */ 2897 function bp_is_user_messages() { 2898 return (bool) ( bp_is_user() && bp_is_messages_component() ); 2899 } 2900 2901 /** 2902 * Is the current page a user's Messages Inbox? 2903 * 2904 * Eg http://example.com/members/joe/messages/inbox/. 2905 * 2906 * @since 1.1.0 2907 * 2908 * @return bool True if the current page is a user's Messages Inbox. 2909 */ 2910 function bp_is_messages_inbox() { 2911 if ( bp_is_user_messages() && ( ! bp_current_action() || bp_is_current_action( 'inbox' ) ) ) { 2912 return true; 2913 } 2914 2915 return false; 2916 } 2917 2918 /** 2919 * Is the current page a user's Messages Sentbox? 2920 * 2921 * Eg http://example.com/members/joe/messages/sentbox/. 2922 * 2923 * @since 1.1.0 2924 * 2925 * @return bool True if the current page is a user's Messages Sentbox. 2926 */ 2927 function bp_is_messages_sentbox() { 2928 return (bool) ( bp_is_user_messages() && bp_is_current_action( 'sentbox' ) ); 2929 } 2930 2931 /** 2932 * Is the current page a user's Messages Compose screen?? 2933 * 2934 * Eg http://example.com/members/joe/messages/compose/. 2935 * 2936 * @since 1.1.0 2937 * 2938 * @return bool True if the current page is a user's Messages Compose screen. 2939 */ 2940 function bp_is_messages_compose_screen() { 2941 return (bool) ( bp_is_user_messages() && bp_is_current_action( 'compose' ) ); 2942 } 2943 2944 /** 2945 * Is the current page the Notices screen? 2946 * 2947 * Eg http://example.com/members/joe/messages/notices/. 2948 * 2949 * @since 1.1.0 2950 * 2951 * @return bool True if the current page is the Notices screen. 2952 */ 2953 function bp_is_notices() { 2954 return (bool) ( bp_is_user_messages() && bp_is_current_action( 'notices' ) ); 2955 } 2956 2957 /** 2958 * Is the current page a single Messages conversation thread? 2959 * 2960 * @since 1.6.0 2961 * 2962 * @return bool True if the current page a single Messages conversation thread? 2963 */ 2964 function bp_is_messages_conversation() { 2965 return (bool) ( bp_is_user_messages() && ( bp_is_current_action( 'view' ) ) ); 2966 } 2967 2968 /** 2969 * Not currently used by BuddyPress. 2970 * 2971 * @param string $component Current component to check for. 2972 * @param string $callback Callback to invoke. 2973 * @return bool 2974 */ 2975 function bp_is_single( $component, $callback ) { 2976 return (bool) ( bp_is_current_component( $component ) && ( true === call_user_func( $callback ) ) ); 2977 } 2978 2979 /** Registration **************************************************************/ 2980 2981 /** 2982 * Is the current page the Activate page? 2983 * 2984 * Eg http://example.com/activate/. 2985 * 2986 * @since 1.1.0 2987 * 2988 * @return bool True if the current page is the Activate page. 2989 */ 2990 function bp_is_activation_page() { 2991 return (bool) bp_is_current_component( 'activate' ); 2992 } 2993 2994 /** 2995 * Is the current page the Register page? 2996 * 2997 * Eg http://example.com/register/. 2998 * 2999 * @since 1.1.0 3000 * 3001 * @return bool True if the current page is the Register page. 3002 */ 3003 function bp_is_register_page() { 3004 return (bool) bp_is_current_component( 'register' ); 3005 } 3006 3007 /** 3008 * Get the title parts of the BuddyPress displayed page 3009 * 3010 * @since 2.4.3 3011 * 3012 * @param string $seplocation Location for the separator. 3013 * @return array the title parts 3014 */ 3015 function bp_get_title_parts( $seplocation = 'right' ) { 3016 $bp = buddypress(); 3017 3018 // Defaults to an empty array. 3019 $bp_title_parts = array(); 3020 3021 // If this is not a BP page, return the empty array. 3022 if ( bp_is_blog_page() ) { 3023 return $bp_title_parts; 3024 } 3025 3026 // If this is a 404, return the empty array. 3027 if ( is_404() ) { 3028 return $bp_title_parts; 3029 } 3030 3031 // If this is the front page of the site, return the empty array. 3032 if ( is_front_page() || is_home() ) { 3033 return $bp_title_parts; 3034 } 3035 3036 // Return the empty array if not a BuddyPress page. 3037 if ( ! is_buddypress() ) { 3038 return $bp_title_parts; 3039 } 3040 3041 // Now we can build the BP Title Parts. 3042 // Is there a displayed user, and do they have a name? 3043 $displayed_user_name = bp_get_displayed_user_fullname(); 3044 3045 // Displayed user. 3046 if ( ! empty( $displayed_user_name ) && ! is_404() ) { 3047 3048 // Get the component's ID to try and get its name. 3049 $component_id = $component_name = bp_current_component(); 3050 3051 // Set empty subnav name. 3052 $component_subnav_name = ''; 3053 3054 if ( ! empty( $bp->members->nav ) ) { 3055 $primary_nav_item = (array) $bp->members->nav->get_primary( array( 'slug' => $component_id ), false ); 3056 $primary_nav_item = reset( $primary_nav_item ); 3057 } 3058 3059 // Use the component nav name. 3060 if ( ! empty( $primary_nav_item->name ) ) { 3061 $component_name = _bp_strip_spans_from_title( $primary_nav_item->name ); 3062 3063 // Fall back on the component ID. 3064 } elseif ( ! empty( $bp->{$component_id}->id ) ) { 3065 $component_name = ucwords( $bp->{$component_id}->id ); 3066 } 3067 3068 if ( ! empty( $bp->members->nav ) ) { 3069 $secondary_nav_item = $bp->members->nav->get_secondary( array( 3070 'parent_slug' => $component_id, 3071 'slug' => bp_current_action() 3072 ), false ); 3073 3074 if ( $secondary_nav_item ) { 3075 $secondary_nav_item = reset( $secondary_nav_item ); 3076 } 3077 } 3078 3079 // Append action name if we're on a member component sub-page. 3080 if ( ! empty( $secondary_nav_item->name ) && ! empty( $bp->canonical_stack['action'] ) ) { 3081 $component_subnav_name = $secondary_nav_item->name; 3082 } 3083 3084 // If on the user profile's landing page, just use the fullname. 3085 if ( bp_is_current_component( $bp->default_component ) && ( bp_get_requested_url() === bp_displayed_user_domain() ) ) { 3086 $bp_title_parts[] = $displayed_user_name; 3087 3088 // Use component name on member pages. 3089 } else { 3090 $bp_title_parts = array_merge( $bp_title_parts, array_map( 'strip_tags', array( 3091 $displayed_user_name, 3092 $component_name, 3093 ) ) ); 3094 3095 // If we have a subnav name, add it separately for localization. 3096 if ( ! empty( $component_subnav_name ) ) { 3097 $bp_title_parts[] = strip_tags( $component_subnav_name ); 3098 } 3099 } 3100 3101 // A single item from a component other than Members. 3102 } elseif ( bp_is_single_item() ) { 3103 $component_id = bp_current_component(); 3104 3105 if ( ! empty( $bp->{$component_id}->nav ) ) { 3106 $secondary_nav_item = $bp->{$component_id}->nav->get_secondary( array( 3107 'parent_slug' => bp_current_item(), 3108 'slug' => bp_current_action() 3109 ), false ); 3110 3111 if ( $secondary_nav_item ) { 3112 $secondary_nav_item = reset( $secondary_nav_item ); 3113 } 3114 } 3115 3116 $single_item_subnav = ''; 3117 3118 if ( ! empty( $secondary_nav_item->name ) ) { 3119 $single_item_subnav = $secondary_nav_item->name; 3120 } 3121 3122 $bp_title_parts = array( $bp->bp_options_title, $single_item_subnav ); 3123 3124 // An index or directory. 3125 } elseif ( bp_is_directory() ) { 3126 $current_component = bp_current_component(); 3127 3128 // No current component (when does this happen?). 3129 $bp_title_parts = array( _x( 'Directory', 'component directory title', 'buddypress' ) ); 3130 3131 if ( ! empty( $current_component ) ) { 3132 $bp_title_parts = array( bp_get_directory_title( $current_component ) ); 3133 } 3134 3135 // Sign up page. 3136 } elseif ( bp_is_register_page() ) { 3137 $bp_title_parts = array( __( 'Create an Account', 'buddypress' ) ); 3138 3139 // Activation page. 3140 } elseif ( bp_is_activation_page() ) { 3141 $bp_title_parts = array( __( 'Activate Your Account', 'buddypress' ) ); 3142 3143 // Group creation page. 3144 } elseif ( bp_is_group_create() ) { 3145 $bp_title_parts = array( __( 'Create a Group', 'buddypress' ) ); 3146 3147 // Blog creation page. 3148 } elseif ( bp_is_create_blog() ) { 3149 $bp_title_parts = array( __( 'Create a Site', 'buddypress' ) ); 3150 } 3151 3152 // Strip spans. 3153 $bp_title_parts = array_map( '_bp_strip_spans_from_title', $bp_title_parts ); 3154 3155 // Sep on right, so reverse the order. 3156 if ( 'right' === $seplocation ) { 3157 $bp_title_parts = array_reverse( $bp_title_parts ); 3158 } 3159 3160 /** 3161 * Filter BuddyPress title parts before joining. 3162 * 3163 * @since 2.4.3 3164 * 3165 * @param array $bp_title_parts Current BuddyPress title parts. 3166 * @return array 3167 */ 3168 return (array) apply_filters( 'bp_get_title_parts', $bp_title_parts ); 3169 } 3170 3171 /** 3172 * Customize the body class, according to the currently displayed BP content. 3173 * 3174 * @since 1.1.0 3175 */ 3176 function bp_the_body_class() { 3177 echo bp_get_the_body_class(); 3178 } 3179 /** 3180 * Customize the body class, according to the currently displayed BP content. 3181 * 3182 * Uses the above is_() functions to output a body class for each scenario. 3183 * 3184 * @since 1.1.0 3185 * 3186 * @param array $wp_classes The body classes coming from WP. 3187 * @param array|bool $custom_classes Classes that were passed to get_body_class(). 3188 * @return array $classes The BP-adjusted body classes. 3189 */ 3190 function bp_get_the_body_class( $wp_classes = array(), $custom_classes = false ) { 3191 3192 $bp_classes = array(); 3193 3194 /* Pages *************************************************************/ 3195 3196 if ( is_front_page() ) { 3197 $bp_classes[] = 'home-page'; 3198 } 3199 3200 if ( bp_is_directory() ) { 3201 $bp_classes[] = 'directory'; 3202 } 3203 3204 if ( bp_is_single_item() ) { 3205 $bp_classes[] = 'single-item'; 3206 } 3207 3208 /* Components ********************************************************/ 3209 3210 if ( ! bp_is_blog_page() ) { 3211 if ( bp_is_user_profile() ) { 3212 $bp_classes[] = 'xprofile'; 3213 } 3214 3215 if ( bp_is_activity_component() ) { 3216 $bp_classes[] = 'activity'; 3217 } 3218 3219 if ( bp_is_blogs_component() ) { 3220 $bp_classes[] = 'blogs'; 3221 } 3222 3223 if ( bp_is_messages_component() ) { 3224 $bp_classes[] = 'messages'; 3225 } 3226 3227 if ( bp_is_friends_component() ) { 3228 $bp_classes[] = 'friends'; 3229 } 3230 3231 if ( bp_is_groups_component() ) { 3232 $bp_classes[] = 'groups'; 3233 } 3234 3235 if ( bp_is_settings_component() ) { 3236 $bp_classes[] = 'settings'; 3237 } 3238 } 3239 3240 /* User **************************************************************/ 3241 3242 if ( bp_is_user() ) { 3243 $bp_classes[] = 'bp-user'; 3244 3245 // Add current user member types. 3246 if ( $member_types = bp_get_member_type( bp_displayed_user_id(), false ) ) { 3247 foreach( $member_types as $member_type ) { 3248 $bp_classes[] = sprintf( 'member-type-%s', esc_attr( $member_type ) ); 3249 } 3250 } 3251 } 3252 3253 if ( ! bp_is_directory() ) { 3254 if ( bp_is_user_blogs() ) { 3255 $bp_classes[] = 'my-blogs'; 3256 } 3257 3258 if ( bp_is_user_groups() ) { 3259 $bp_classes[] = 'my-groups'; 3260 } 3261 3262 if ( bp_is_user_activity() ) { 3263 $bp_classes[] = 'my-activity'; 3264 } 3265 } else { 3266 if ( bp_get_current_member_type() || ( bp_is_groups_directory() && bp_get_current_group_directory_type() ) ) { 3267 $bp_classes[] = 'type'; 3268 } 3269 } 3270 3271 if ( bp_is_my_profile() ) { 3272 $bp_classes[] = 'my-account'; 3273 } 3274 3275 if ( bp_is_user_profile() ) { 3276 $bp_classes[] = 'my-profile'; 3277 } 3278 3279 if ( bp_is_user_friends() ) { 3280 $bp_classes[] = 'my-friends'; 3281 } 3282 3283 if ( bp_is_user_messages() ) { 3284 $bp_classes[] = 'my-messages'; 3285 } 3286 3287 if ( bp_is_user_recent_commments() ) { 3288 $bp_classes[] = 'recent-comments'; 3289 } 3290 3291 if ( bp_is_user_recent_posts() ) { 3292 $bp_classes[] = 'recent-posts'; 3293 } 3294 3295 if ( bp_is_user_change_avatar() ) { 3296 $bp_classes[] = 'change-avatar'; 3297 } 3298 3299 if ( bp_is_user_profile_edit() ) { 3300 $bp_classes[] = 'profile-edit'; 3301 } 3302 3303 if ( bp_is_user_friends_activity() ) { 3304 $bp_classes[] = 'friends-activity'; 3305 } 3306 3307 if ( bp_is_user_groups_activity() ) { 3308 $bp_classes[] = 'groups-activity'; 3309 } 3310 3311 /* Messages **********************************************************/ 3312 3313 if ( bp_is_messages_inbox() ) { 3314 $bp_classes[] = 'inbox'; 3315 } 3316 3317 if ( bp_is_messages_sentbox() ) { 3318 $bp_classes[] = 'sentbox'; 3319 } 3320 3321 if ( bp_is_messages_compose_screen() ) { 3322 $bp_classes[] = 'compose'; 3323 } 3324 3325 if ( bp_is_notices() ) { 3326 $bp_classes[] = 'notices'; 3327 } 3328 3329 if ( bp_is_user_friend_requests() ) { 3330 $bp_classes[] = 'friend-requests'; 3331 } 3332 3333 if ( bp_is_create_blog() ) { 3334 $bp_classes[] = 'create-blog'; 3335 } 3336 3337 /* Groups ************************************************************/ 3338 3339 if ( bp_is_group() ) { 3340 $bp_classes[] = 'group-' . groups_get_current_group()->slug; 3341 3342 // Add current group types. 3343 if ( $group_types = bp_groups_get_group_type( bp_get_current_group_id(), false ) ) { 3344 foreach ( $group_types as $group_type ) { 3345 $bp_classes[] = sprintf( 'group-type-%s', esc_attr( $group_type ) ); 3346 } 3347 } 3348 } 3349 3350 if ( bp_is_group_leave() ) { 3351 $bp_classes[] = 'leave-group'; 3352 } 3353 3354 if ( bp_is_group_invites() ) { 3355 $bp_classes[] = 'group-invites'; 3356 } 3357 3358 if ( bp_is_group_members() ) { 3359 $bp_classes[] = 'group-members'; 3360 } 3361 3362 if ( bp_is_group_admin_page() ) { 3363 $bp_classes[] = 'group-admin'; 3364 $bp_classes[] = bp_get_group_current_admin_tab(); 3365 } 3366 3367 if ( bp_is_group_create() ) { 3368 $bp_classes[] = 'group-create'; 3369 $bp_classes[] = bp_get_groups_current_create_step(); 3370 } 3371 3372 if ( bp_is_group_home() ) { 3373 $bp_classes[] = 'group-home'; 3374 } 3375 3376 if ( bp_is_single_activity() ) { 3377 $bp_classes[] = 'activity-permalink'; 3378 } 3379 3380 /* Registration ******************************************************/ 3381 3382 if ( bp_is_register_page() ) { 3383 $bp_classes[] = 'registration'; 3384 } 3385 3386 if ( bp_is_activation_page() ) { 3387 $bp_classes[] = 'activation'; 3388 } 3389 3390 /* Current Component & Action ****************************************/ 3391 3392 if ( ! bp_is_blog_page() ) { 3393 $bp_classes[] = bp_current_component(); 3394 $bp_classes[] = bp_current_action(); 3395 } 3396 3397 /* Clean up ***********************************************************/ 3398 3399 // Add BuddyPress class if we are within a BuddyPress page. 3400 if ( ! bp_is_blog_page() ) { 3401 $bp_classes[] = 'buddypress'; 3402 } 3403 3404 // Add the theme name/id to the body classes 3405 $bp_classes[] = 'bp-' . bp_get_theme_compat_id(); 3406 3407 // Merge WP classes with BuddyPress classes and remove any duplicates. 3408 $classes = array_unique( array_merge( (array) $bp_classes, (array) $wp_classes ) ); 3409 3410 /** 3411 * Filters the BuddyPress classes to be added to body_class() 3412 * 3413 * @since 1.1.0 3414 * 3415 * @param array $classes Array of body classes to add. 3416 * @param array $bp_classes Array of BuddyPress-based classes. 3417 * @param array $wp_classes Array of WordPress-based classes. 3418 * @param array $custom_classes Array of classes that were passed to get_body_class(). 3419 */ 3420 return apply_filters( 'bp_get_the_body_class', $classes, $bp_classes, $wp_classes, $custom_classes ); 3421 } 3422 add_filter( 'body_class', 'bp_get_the_body_class', 10, 2 ); 3423 3424 /** 3425 * Customizes the post CSS class according to BuddyPress content. 3426 * 3427 * Hooked to the 'post_class' filter. 3428 * 3429 * @since 2.1.0 3430 * 3431 * @param array $wp_classes The post classes coming from WordPress. 3432 * @return array 3433 */ 3434 function bp_get_the_post_class( $wp_classes = array() ) { 3435 // Don't do anything if we're not on a BP page. 3436 if ( ! is_buddypress() ) { 3437 return $wp_classes; 3438 } 3439 3440 $bp_classes = array(); 3441 3442 if ( bp_is_user() || bp_is_single_activity() ) { 3443 $bp_classes[] = 'bp_members'; 3444 3445 } elseif ( bp_is_group() ) { 3446 $bp_classes[] = 'bp_group'; 3447 3448 } elseif ( bp_is_activity_component() ) { 3449 $bp_classes[] = 'bp_activity'; 3450 3451 } elseif ( bp_is_blogs_component() ) { 3452 $bp_classes[] = 'bp_blogs'; 3453 3454 } elseif ( bp_is_register_page() ) { 3455 $bp_classes[] = 'bp_register'; 3456 3457 } elseif ( bp_is_activation_page() ) { 3458 $bp_classes[] = 'bp_activate'; 3459 } 3460 3461 if ( empty( $bp_classes ) ) { 3462 return $wp_classes; 3463 } 3464 3465 // Emulate post type css class. 3466 foreach ( $bp_classes as $bp_class ) { 3467 $bp_classes[] = "type-{$bp_class}"; 3468 } 3469 3470 // Okay let's merge! 3471 return array_unique( array_merge( $bp_classes, $wp_classes ) ); 3472 } 3473 add_filter( 'post_class', 'bp_get_the_post_class' ); 3474 3475 /** 3476 * Sort BuddyPress nav menu items by their position property. 3477 * 3478 * This is an internal convenience function and it will probably be removed in 3479 * a later release. Do not use. 3480 * 3481 * @access private 3482 * @since 1.7.0 3483 * 3484 * @param array $a First item. 3485 * @param array $b Second item. 3486 * @return int Returns an integer less than, equal to, or greater than zero if 3487 * the first argument is considered to be respectively less than, 3488 * equal to, or greater than the second. 3489 */ 3490 function _bp_nav_menu_sort( $a, $b ) { 3491 if ( $a['position'] == $b['position'] ) { 3492 return 0; 3493 } elseif ( $a['position'] < $b['position'] ) { 3494 return -1; 3495 } else { 3496 return 1; 3497 } 3498 } 3499 3500 /** 3501 * Get the items registered in the primary and secondary BuddyPress navigation menus. 3502 * 3503 * @since 1.7.0 3504 * @since 2.6.0 Introduced the `$component` parameter. 3505 * 3506 * @param string $component Optional. Component whose nav items are being fetched. 3507 * @return array A multidimensional array of all navigation items. 3508 */ 3509 function bp_get_nav_menu_items( $component = 'members' ) { 3510 $bp = buddypress(); 3511 $menus = array(); 3512 3513 if ( ! isset( $bp->{$component}->nav ) ) { 3514 return $menus; 3515 } 3516 3517 // Get the item nav and build the menus. 3518 foreach ( $bp->{$component}->nav->get_item_nav() as $nav_menu ) { 3519 // Get the correct menu link. See https://buddypress.trac.wordpress.org/ticket/4624. 3520 $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 ); 3521 3522 // Add this menu. 3523 $menu = new stdClass; 3524 $menu->class = array( 'menu-parent' ); 3525 $menu->css_id = $nav_menu->css_id; 3526 $menu->link = $link; 3527 $menu->name = $nav_menu->name; 3528 $menu->parent = 0; 3529 3530 if ( ! empty( $nav_menu->children ) ) { 3531 $submenus = array(); 3532 3533 foreach( $nav_menu->children as $sub_menu ) { 3534 $submenu = new stdClass; 3535 $submenu->class = array( 'menu-child' ); 3536 $submenu->css_id = $sub_menu->css_id; 3537 $submenu->link = $sub_menu->link; 3538 $submenu->name = $sub_menu->name; 3539 $submenu->parent = $nav_menu->slug; 3540 3541 // If we're viewing this item's screen, record that we need to mark its parent menu to be selected. 3542 if ( bp_is_current_action( $sub_menu->slug ) && bp_is_current_component( $nav_menu->slug ) ) { 3543 $menu->class[] = 'current-menu-parent'; 3544 $submenu->class[] = 'current-menu-item'; 3545 } 3546 3547 $submenus[] = $submenu; 3548 } 3549 } 3550 3551 $menus[] = $menu; 3552 3553 if ( ! empty( $submenus ) ) { 3554 $menus = array_merge( $menus, $submenus ); 3555 } 3556 } 3557 3558 /** 3559 * Filters the items registered in the primary and secondary BuddyPress navigation menus. 3560 * 3561 * @since 1.7.0 3562 * 3563 * @param array $menus Array of items registered in the primary and secondary BuddyPress navigation. 3564 */ 3565 return apply_filters( 'bp_get_nav_menu_items', $menus ); 3566 } 3567 3568 /** 3569 * Display a navigation menu. 3570 * 3571 * @since 1.7.0 3572 * 3573 * @param string|array $args { 3574 * An array of optional arguments. 3575 * 3576 * @type string $after Text after the link text. Default: ''. 3577 * @type string $before Text before the link text. Default: ''. 3578 * @type string $container The name of the element to wrap the navigation 3579 * with. 'div' or 'nav'. Default: 'div'. 3580 * @type string $container_class The class that is applied to the container. 3581 * Default: 'menu-bp-container'. 3582 * @type string $container_id The ID that is applied to the container. 3583 * Default: ''. 3584 * @type int $depth How many levels of the hierarchy are to be included. 3585 * 0 means all. Default: 0. 3586 * @type bool $echo True to echo the menu, false to return it. 3587 * Default: true. 3588 * @type bool $fallback_cb If the menu doesn't exist, should a callback 3589 * function be fired? Default: false (no fallback). 3590 * @type string $items_wrap How the list items should be wrapped. Should be 3591 * in the form of a printf()-friendly string, using numbered 3592 * placeholders. Default: '<ul id="%1$s" class="%2$s">%3$s</ul>'. 3593 * @type string $link_after Text after the link. Default: ''. 3594 * @type string $link_before Text before the link. Default: ''. 3595 * @type string $menu_class CSS class to use for the <ul> element which 3596 * forms the menu. Default: 'menu'. 3597 * @type string $menu_id The ID that is applied to the <ul> element which 3598 * forms the menu. Default: 'menu-bp', incremented. 3599 * @type string $walker Allows a custom walker class to be specified. 3600 * Default: 'BP_Walker_Nav_Menu'. 3601 * } 3602 * @return string|null If $echo is false, returns a string containing the nav 3603 * menu markup. 3604 */ 3605 function bp_nav_menu( $args = array() ) { 3606 static $menu_id_slugs = array(); 3607 3608 $defaults = array( 3609 'after' => '', 3610 'before' => '', 3611 'container' => 'div', 3612 'container_class' => '', 3613 'container_id' => '', 3614 'depth' => 0, 3615 'echo' => true, 3616 'fallback_cb' => false, 3617 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 3618 'link_after' => '', 3619 'link_before' => '', 3620 'menu_class' => 'menu', 3621 'menu_id' => '', 3622 'walker' => '', 3623 ); 3624 $args = wp_parse_args( $args, $defaults ); 3625 3626 /** 3627 * Filters the parsed bp_nav_menu arguments. 3628 * 3629 * @since 1.7.0 3630 * 3631 * @param array $args Array of parsed arguments. 3632 */ 3633 $args = apply_filters( 'bp_nav_menu_args', $args ); 3634 $args = (object) $args; 3635 3636 $items = $nav_menu = ''; 3637 $show_container = false; 3638 3639 // Create custom walker if one wasn't set. 3640 if ( empty( $args->walker ) ) { 3641 $args->walker = new BP_Walker_Nav_Menu; 3642 } 3643 3644 // Sanitize values for class and ID. 3645 $args->container_class = sanitize_html_class( $args->container_class ); 3646 $args->container_id = sanitize_html_class( $args->container_id ); 3647 3648 // Whether to wrap the ul, and what to wrap it with. 3649 if ( $args->container ) { 3650 3651 /** 3652 * Filters the allowed tags for the wp_nav_menu_container. 3653 * 3654 * @since 1.7.0 3655 * 3656 * @param array $value Array of allowed tags. Default 'div' and 'nav'. 3657 */ 3658 $allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav', ) ); 3659 3660 if ( in_array( $args->container, $allowed_tags ) ) { 3661 $show_container = true; 3662 3663 $class = $args->container_class ? ' class="' . esc_attr( $args->container_class ) . '"' : ' class="menu-bp-container"'; 3664 $id = $args->container_id ? ' id="' . esc_attr( $args->container_id ) . '"' : ''; 3665 $nav_menu .= '<' . $args->container . $id . $class . '>'; 3666 } 3667 } 3668 3669 /** 3670 * Filters the BuddyPress menu objects. 3671 * 3672 * @since 1.7.0 3673 * 3674 * @param array $value Array of nav menu objects. 3675 * @param array $args Array of arguments for the menu. 3676 */ 3677 $menu_items = apply_filters( 'bp_nav_menu_objects', bp_get_nav_menu_items(), $args ); 3678 $items = walk_nav_menu_tree( $menu_items, $args->depth, $args ); 3679 unset( $menu_items ); 3680 3681 // Set the ID that is applied to the ul element which forms the menu. 3682 if ( ! empty( $args->menu_id ) ) { 3683 $wrap_id = $args->menu_id; 3684 3685 } else { 3686 $wrap_id = 'menu-bp'; 3687 3688 // If a specific ID wasn't requested, and there are multiple menus on the same screen, make sure the autogenerated ID is unique. 3689 while ( in_array( $wrap_id, $menu_id_slugs ) ) { 3690 if ( preg_match( '#-(\d+)$#', $wrap_id, $matches ) ) { 3691 $wrap_id = preg_replace('#-(\d+)$#', '-' . ++$matches[1], $wrap_id ); 3692 } else { 3693 $wrap_id = $wrap_id . '-1'; 3694 } 3695 } 3696 } 3697 $menu_id_slugs[] = $wrap_id; 3698 3699 /** 3700 * Filters the BuddyPress menu items. 3701 * 3702 * Allow plugins to hook into the menu to add their own <li>'s 3703 * 3704 * @since 1.7.0 3705 * 3706 * @param array $items Array of nav menu items. 3707 * @param array $args Array of arguments for the menu. 3708 */ 3709 $items = apply_filters( 'bp_nav_menu_items', $items, $args ); 3710 3711 // Build the output. 3712 $wrap_class = $args->menu_class ? $args->menu_class : ''; 3713 $nav_menu .= sprintf( $args->items_wrap, esc_attr( $wrap_id ), esc_attr( $wrap_class ), $items ); 3714 unset( $items ); 3715 3716 // If we've wrapped the ul, close it. 3717 if ( ! empty( $show_container ) ) { 3718 $nav_menu .= '</' . $args->container . '>'; 3719 } 3720 3721 /** 3722 * Filters the final BuddyPress menu output. 3723 * 3724 * @since 1.7.0 3725 * 3726 * @param string $nav_menu Final nav menu output. 3727 * @param array $args Array of arguments for the menu. 3728 */ 3729 $nav_menu = apply_filters( 'bp_nav_menu', $nav_menu, $args ); 3730 3731 if ( ! empty( $args->echo ) ) { 3732 echo $nav_menu; 3733 } else { 3734 return $nav_menu; 3735 } 3736 } 3737 3738 /** 3739 * Prints the Recipient Salutation. 3740 * 3741 * @since 2.5.0 3742 * 3743 * @param array $settings Email Settings. 3744 */ 3745 function bp_email_the_salutation( $settings = array() ) { 3746 echo bp_email_get_salutation( $settings ); 3747 } 3748 3749 /** 3750 * Gets the Recipient Salutation. 3751 * 3752 * @since 2.5.0 3753 * 3754 * @param array $settings Email Settings. 3755 * @return string The Recipient Salutation. 3756 */ 3757 function bp_email_get_salutation( $settings = array() ) { 3758 $token = '{{recipient.name}}'; 3759 3760 /** 3761 * Filters The Recipient Salutation inside the Email Template. 3762 * 3763 * @since 2.5.0 3764 * 3765 * @param string $value The Recipient Salutation. 3766 * @param array $settings Email Settings. 3767 * @param string $token The Recipient token. 3768 */ 3769 return apply_filters( 3770 'bp_email_get_salutation', 3771 sprintf( 3772 /* translators: %s: the email token for the recipient name */ 3773 _x( 'Hi %s,', 'recipient salutation', 'buddypress' ), 3774 $token 3775 ), 3776 $settings, 3777 $token 3778 ); 3779 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 28 01:01:36 2021 | Cross-referenced by PHPXref 0.7.1 |