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


Generated: Fri Jul 30 01:01:42 2021 Cross-referenced by PHPXref 0.7.1