[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

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

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


Generated: Sun May 31 01:01:27 2020 Cross-referenced by PHPXref 0.7.1