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


Generated: Sat Sep 21 01:01:46 2019 Cross-referenced by PHPXref 0.7.1