[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-core/ -> bp-core-template.php (source)

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


Generated: Tue Mar 19 01:01:09 2024 Cross-referenced by PHPXref 0.7.1