[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-templates/bp-nouveau/includes/ -> template-tags.php (source)

   1  <?php
   2  /**
   3   * Common template tags
   4   *
   5   * @since 3.0.0
   6   * @version 6.0.0
   7   */
   8  
   9  // Exit if accessed directly.
  10  defined( 'ABSPATH' ) || exit;
  11  
  12  /**
  13   * Fire specific hooks at various places of templates
  14   *
  15   * @since 3.0.0
  16   *
  17   * @param array $pieces The list of terms of the hook to join.
  18   */
  19  function bp_nouveau_hook( $pieces = array() ) {
  20      if ( ! $pieces ) {
  21          return;
  22      }
  23  
  24      $bp_prefix = reset( $pieces );
  25      if ( 'bp' !== $bp_prefix ) {
  26          array_unshift( $pieces, 'bp' );
  27      }
  28  
  29      $hook = join( '_', $pieces );
  30  
  31      /**
  32       * Fires inside the `bp_nouveau_hook()` function.
  33       *
  34       * @since 3.0.0
  35       */
  36      do_action( $hook );
  37  }
  38  
  39  /**
  40   * Fire plugin hooks in the plugins.php template (Groups and Members single items)
  41   *
  42   * @since 3.0.0
  43   *
  44   * @param string The suffix of the hook.
  45   */
  46  function bp_nouveau_plugin_hook( $suffix = '' ) {
  47      if ( ! $suffix ) {
  48          return;
  49      }
  50  
  51      bp_nouveau_hook(
  52          array(
  53              'bp',
  54              'template',
  55              $suffix,
  56          )
  57      );
  58  }
  59  
  60  /**
  61   * Fire friend hooks
  62   *
  63   * @todo Move this into bp-nouveau/includes/friends/template-tags.php
  64   *       once we'll need other friends template tags.
  65   *
  66   * @since 3.0.0
  67   *
  68   * @param string The suffix of the hook.
  69   */
  70  function bp_nouveau_friend_hook( $suffix = '' ) {
  71      if ( ! $suffix ) {
  72          return;
  73      }
  74  
  75      bp_nouveau_hook(
  76          array(
  77              'bp',
  78              'friend',
  79              $suffix,
  80          )
  81      );
  82  }
  83  
  84  /**
  85   * Add classes to style the template notice/feedback message
  86   *
  87   * @since 3.0.0
  88   */
  89  function bp_nouveau_template_message_classes() {
  90      $bp_nouveau = bp_nouveau();
  91      $classes    = array( 'bp-feedback', 'bp-messages' );
  92  
  93      if ( ! empty( $bp_nouveau->template_message['message'] ) ) {
  94          $classes[] = 'bp-template-notice';
  95      }
  96  
  97      $classes[] = bp_nouveau_get_template_message_type();
  98      echo join( ' ', array_map( 'sanitize_html_class', $classes ) );
  99  }
 100  
 101      /**
 102       * Get the template notice/feedback message type
 103       *
 104       * @since 3.0.0
 105       *
 106       * @return string The type of the notice. Defaults to error.
 107       */
 108  	function bp_nouveau_get_template_message_type() {
 109          $bp_nouveau = bp_nouveau();
 110          $type       = 'error';
 111  
 112          if ( ! empty( $bp_nouveau->template_message['type'] ) ) {
 113              $type = $bp_nouveau->template_message['type'];
 114          } elseif ( ! empty( $bp_nouveau->user_feedback['type'] ) ) {
 115              $type = $bp_nouveau->user_feedback['type'];
 116          }
 117  
 118          return $type;
 119      }
 120  
 121  /**
 122   * Checks if a template notice/feedback message is set
 123   *
 124   * @since 3.0.0
 125   *
 126   * @return bool True if a template notice is set. False otherwise.
 127   */
 128  function bp_nouveau_has_template_message() {
 129      $bp_nouveau = bp_nouveau();
 130  
 131      if ( empty( $bp_nouveau->template_message['message'] ) && empty( $bp_nouveau->user_feedback ) ) {
 132          return false;
 133      }
 134  
 135      return true;
 136  }
 137  
 138  /**
 139   * Checks if the template notice/feedback message needs a dismiss button
 140   *
 141   * @todo Dismiss button re-worked to try and prevent buttons on general
 142   *       BP template notices - Nouveau user_feedback key needs review.
 143   *
 144   * @since 3.0.0
 145   *
 146   * @return bool True if a template notice needs a dismiss button. False otherwise.
 147   */
 148  function bp_nouveau_has_dismiss_button() {
 149      $bp_nouveau = bp_nouveau();
 150  
 151      // BP template notices - set 'dismiss' true for a type in `bp_nouveau_template_notices()`
 152      if ( ! empty( $bp_nouveau->template_message['message'] ) && true === $bp_nouveau->template_message['dismiss'] ) {
 153          return true;
 154      }
 155  
 156      // Test for isset as value can be falsey.
 157      if ( isset( $bp_nouveau->user_feedback['dismiss'] ) ) {
 158          return true;
 159      }
 160  
 161      return false;
 162  }
 163  
 164  /**
 165   * Ouptut the dismiss type.
 166   *
 167   * $type is used to set the data-attr for the button.
 168   * 'clear' is tested for & used to remove cookies, if set, in buddypress-nouveau.js.
 169   * Currently template_notices(BP) will take $type = 'clear' if button set to true.
 170   *
 171   * @since 3.0.0
 172   */
 173  function bp_nouveau_dismiss_button_type() {
 174      $bp_nouveau = bp_nouveau();
 175      $type       = 'clear';
 176  
 177      if ( ! empty( $bp_nouveau->user_feedback['dismiss'] ) ) {
 178          $type = $bp_nouveau->user_feedback['dismiss'];
 179      }
 180  
 181      echo esc_attr( $type );
 182  }
 183  
 184  /**
 185   * Displays a template notice/feedback message.
 186   *
 187   * @since 3.0.0
 188   */
 189  function bp_nouveau_template_message() {
 190      echo bp_nouveau_get_template_message();
 191  }
 192  
 193      /**
 194       * Get the template notice/feedback message and make sure core filter is applied.
 195       *
 196       * @since 3.0.0
 197       *
 198       * @return string HTML Output.
 199       */
 200  	function bp_nouveau_get_template_message() {
 201          $bp_nouveau = bp_nouveau();
 202  
 203          if ( ! empty( $bp_nouveau->user_feedback['message'] ) ) {
 204              $user_feedback = $bp_nouveau->user_feedback['message'];
 205  
 206              // @TODO: why is this treated differently?
 207              foreach ( array( 'wp_kses_data', 'wp_unslash', 'wptexturize', 'convert_smilies', 'convert_chars' ) as $filter ) {
 208                  $user_feedback = call_user_func( $filter, $user_feedback );
 209              }
 210  
 211              return '<p>' . $user_feedback . '</p>';
 212  
 213          } elseif ( ! empty( $bp_nouveau->template_message['message'] ) ) {
 214              /**
 215               * Filters the 'template_notices' feedback message content.
 216               *
 217               * @since 1.5.5
 218               *
 219               * @param string $template_message Feedback message content.
 220               * @param string $type             The type of message being displayed.
 221               *                                 Either 'updated' or 'error'.
 222               */
 223              return apply_filters( 'bp_core_render_message_content', $bp_nouveau->template_message['message'], bp_nouveau_get_template_message_type() );
 224          }
 225      }
 226  
 227  /**
 228   * Template tag to display feedback notices to users, if there are to display
 229   *
 230   * @since 3.0.0
 231   */
 232  function bp_nouveau_template_notices() {
 233      $bp         = buddypress();
 234      $bp_nouveau = bp_nouveau();
 235  
 236      if ( ! empty( $bp->template_message ) ) {
 237          // Clone BuddyPress template message to avoid altering it.
 238          $template_message = array( 'message' => $bp->template_message );
 239  
 240          if ( ! empty( $bp->template_message_type ) ) {
 241              $template_message['type'] = $bp->template_message_type;
 242          }
 243  
 244          // Adds a 'dimiss' (button) key to array - set true/false.
 245          $template_message['dismiss'] = false;
 246  
 247          // Set dismiss button true for sitewide notices
 248          if ( 'bp-sitewide-notice' == $template_message['type'] ) {
 249              $template_message['dismiss'] = true;
 250          }
 251  
 252          $bp_nouveau->template_message = $template_message;
 253          bp_get_template_part( 'common/notices/template-notices' );
 254  
 255          // Reset just after rendering it.
 256          $bp_nouveau->template_message = array();
 257  
 258          /**
 259           * Fires after the display of any template_notices feedback messages.
 260           *
 261           * @since 3.0.0
 262           */
 263          do_action( 'bp_core_render_message' );
 264      }
 265  
 266      /**
 267       * Fires towards the top of template pages for notice display.
 268       *
 269       * @since 3.0.0
 270       */
 271      do_action( 'template_notices' );
 272  }
 273  
 274  /**
 275   * Displays a feedback message to the user.
 276   *
 277   * @since 3.0.0
 278   *
 279   * @param string $feedback_id The ID of the message to display
 280   */
 281  function bp_nouveau_user_feedback( $feedback_id = '' ) {
 282      if ( ! isset( $feedback_id ) ) {
 283          return;
 284      }
 285  
 286      $bp_nouveau = bp_nouveau();
 287      $feedback   = bp_nouveau_get_user_feedback( $feedback_id );
 288  
 289      if ( ! $feedback ) {
 290          return;
 291      }
 292  
 293      if ( ! empty( $feedback['before'] ) ) {
 294  
 295          /**
 296           * Fires before display of a feedback message to the user.
 297           *
 298           * This is a dynamic filter that is dependent on the "before" value provided by bp_nouveau_get_user_feedback().
 299           *
 300           * @since 3.0.0
 301           */
 302          do_action( $feedback['before'] );
 303      }
 304  
 305      $bp_nouveau->user_feedback = $feedback;
 306  
 307      bp_get_template_part(
 308  
 309          /**
 310           * Filter here if you wish to use a different templates than the notice one.
 311           *
 312           * @since 3.0.0
 313           *
 314           * @param string path to your template part.
 315           */
 316          apply_filters( 'bp_nouveau_user_feedback_template', 'common/notices/template-notices' )
 317      );
 318  
 319      if ( ! empty( $feedback['after'] ) ) {
 320  
 321          /**
 322           * Fires before display of a feedback message to the user.
 323           *
 324           * This is a dynamic filter that is dependent on the "after" value provided by bp_nouveau_get_user_feedback().
 325           *
 326           * @since 3.0.0
 327           */
 328          do_action( $feedback['after'] );
 329      }
 330  
 331      // Reset the feedback message.
 332      $bp_nouveau->user_feedback = array();
 333  }
 334  
 335  /**
 336   * Template tag to wrap the before component loop
 337   *
 338   * @since 3.0.0
 339   */
 340  function bp_nouveau_before_loop() {
 341      $component = bp_current_component();
 342  
 343      if ( bp_is_group() ) {
 344          $component = bp_current_action();
 345      }
 346  
 347      /**
 348       * Fires before the start of the component loop.
 349       *
 350       * This is a variable hook that is dependent on the current component.
 351       *
 352       * @since 1.2.0
 353       */
 354      do_action( "bp_before_{$component}_loop" );
 355  }
 356  
 357  /**
 358   * Template tag to wrap the after component loop
 359   *
 360   * @since 3.0.0
 361   */
 362  function bp_nouveau_after_loop() {
 363      $component = bp_current_component();
 364  
 365      if ( bp_is_group() ) {
 366          $component = bp_current_action();
 367      }
 368  
 369      /**
 370       * Fires after the finish of the component loop.
 371       *
 372       * This is a variable hook that is dependent on the current component.
 373       *
 374       * @since 1.2.0
 375       */
 376      do_action( "bp_after_{$component}_loop" );
 377  }
 378  
 379  /**
 380   * Pagination for loops
 381   *
 382   * @param string $position
 383   *
 384   * @since 3.0.0
 385   */
 386  function bp_nouveau_pagination( $position ) {
 387      $screen          = 'dir';
 388      $pagination_type = bp_current_component();
 389  
 390      if ( bp_is_user() ) {
 391          $screen = 'user';
 392  
 393      } elseif ( bp_is_group() ) {
 394          $screen          = 'group';
 395          $pagination_type = bp_current_action();
 396  
 397          if ( bp_is_group_admin_page() ) {
 398              $pagination_type = bp_action_variable( 0 );
 399          }
 400      }
 401  
 402      switch ( $pagination_type ) {
 403          case 'blogs':
 404              $pag_count   = bp_get_blogs_pagination_count();
 405              $pag_links   = bp_get_blogs_pagination_links();
 406              $top_hook    = 'bp_before_directory_blogs_list';
 407              $bottom_hook = 'bp_after_directory_blogs_list';
 408              $page_arg    = $GLOBALS['blogs_template']->pag_arg;
 409              break;
 410  
 411          case 'members':
 412          case 'friends':
 413          case 'manage-members':
 414              $pag_count = bp_get_members_pagination_count();
 415              $pag_links = bp_get_members_pagination_links();
 416  
 417              // Groups single items are not using these hooks
 418              if ( ! bp_is_group() ) {
 419                  $top_hook    = 'bp_before_directory_members_list';
 420                  $bottom_hook = 'bp_after_directory_members_list';
 421              }
 422  
 423              $page_arg = $GLOBALS['members_template']->pag_arg;
 424              break;
 425  
 426          case 'groups':
 427              $pag_count   = bp_get_groups_pagination_count();
 428              $pag_links   = bp_get_groups_pagination_links();
 429              $top_hook    = 'bp_before_directory_groups_list';
 430              $bottom_hook = 'bp_after_directory_groups_list';
 431              $page_arg    = $GLOBALS['groups_template']->pag_arg;
 432              break;
 433  
 434          case 'notifications':
 435              $pag_count   = bp_get_notifications_pagination_count();
 436              $pag_links   = bp_get_notifications_pagination_links();
 437              $top_hook    = '';
 438              $bottom_hook = '';
 439              $page_arg    = buddypress()->notifications->query_loop->pag_arg;
 440              break;
 441  
 442          case 'membership-requests':
 443              $pag_count   = bp_get_group_requests_pagination_count();
 444              $pag_links   = bp_get_group_requests_pagination_links();
 445              $top_hook    = '';
 446              $bottom_hook = '';
 447              $page_arg    = $GLOBALS['requests_template']->pag_arg;
 448              break;
 449  
 450          default:
 451              /**
 452               * Use this filter to define your custom pagination parameters.
 453               *
 454               * @since 6.0.0
 455               *
 456               * @param array $value {
 457               *     An associative array of pagination parameters.
 458               *     @type string   $pag_count Information about the pagination count.
 459               *                               eg: "Viewing 1 - 10 of 20 items".
 460               *     @type string   $pag_links The Pagination links.
 461               *     @type string   $page_arg  The argument to use to pass the page number.
 462               * }
 463               * @param string $pagination_type Information about the pagination type.
 464               */
 465              $pagination_params = apply_filters( 'bp_nouveau_pagination_params',
 466                  array(
 467                      'pag_count' => '',
 468                      'pag_links' => '',
 469                      'page_arg'  => '',
 470                  ),
 471                  $pagination_type
 472              );
 473  
 474              list( $pag_count, $pag_links, $page_arg ) = array_values( $pagination_params );
 475              break;
 476      }
 477  
 478      $count_class = sprintf( '%1$s-%2$s-count-%3$s', $pagination_type, $screen, $position );
 479      $links_class = sprintf( '%1$s-%2$s-links-%3$s', $pagination_type, $screen, $position );
 480      ?>
 481  
 482      <?php
 483      if ( 'bottom' === $position && isset( $bottom_hook ) ) {
 484          /**
 485           * Fires after the component directory list.
 486           *
 487           * @since 3.0.0
 488           */
 489          do_action( $bottom_hook );
 490      };
 491      ?>
 492  
 493      <div class="<?php echo esc_attr( 'bp-pagination ' . sanitize_html_class( $position ) ); ?>" data-bp-pagination="<?php echo esc_attr( $page_arg ); ?>">
 494  
 495          <?php if ( $pag_count ) : ?>
 496              <div class="<?php echo esc_attr( 'pag-count ' . sanitize_html_class( $position ) ); ?>">
 497  
 498                  <p class="pag-data">
 499                      <?php echo esc_html( $pag_count ); ?>
 500                  </p>
 501  
 502              </div>
 503          <?php endif; ?>
 504  
 505          <?php if ( $pag_links ) : ?>
 506              <div class="<?php echo esc_attr( 'bp-pagination-links ' . sanitize_html_class( $position ) ); ?>">
 507  
 508                  <p class="pag-data">
 509                      <?php echo wp_kses_post( $pag_links ); ?>
 510                  </p>
 511  
 512              </div>
 513          <?php endif; ?>
 514  
 515      </div>
 516  
 517      <?php
 518      if ( 'top' === $position && isset( $top_hook ) ) {
 519          /**
 520           * Fires before the component directory list.
 521           *
 522           * @since 3.0.0
 523           */
 524          do_action( $top_hook );
 525      };
 526  }
 527  
 528  /**
 529   * Display the component's loop classes
 530   *
 531   * @since 3.0.0
 532   *
 533   * @return string CSS class attributes (escaped).
 534   */
 535  function bp_nouveau_loop_classes() {
 536      echo esc_attr( bp_nouveau_get_loop_classes() );
 537  }
 538  
 539      /**
 540       * Get the component's loop classes
 541       *
 542       * @since 3.0.0
 543       *
 544       * @return string space separated value of classes.
 545       */
 546  	function bp_nouveau_get_loop_classes() {
 547          $bp_nouveau = bp_nouveau();
 548  
 549          // @todo: this function could do with passing args so we can pass simple strings in or array of strings
 550  
 551          // The $component is faked if it's the single group member loop
 552          if ( ! bp_is_directory() && ( bp_is_group() && 'members' === bp_current_action() ) ) {
 553              $component = 'members_group';
 554          } elseif ( ! bp_is_directory() && ( bp_is_user() && 'my-friends' === bp_current_action() ) ) {
 555              $component = 'members_friends';
 556          } else {
 557              $component = sanitize_key( bp_current_component() );
 558          }
 559  
 560          $classes = array(
 561              'item-list',
 562              sprintf( '%s-list', str_replace( '_', '-', $component ) ),
 563              'bp-list',
 564          );
 565  
 566          if ( bp_is_user() && 'my-friends' === bp_current_action() ) {
 567              $classes[] = 'members-list';
 568          }
 569  
 570          if ( bp_is_user() && 'requests' === bp_current_action() ) {
 571              $classes[] = 'friends-request-list';
 572          }
 573  
 574          $available_components = array(
 575              'members' => true,
 576              'groups'  => true,
 577              'blogs'   => true,
 578  
 579              /*
 580               * Technically not a component but allows us to check the single group members loop as a seperate loop.
 581               */
 582              'members_group'   => true,
 583              'members_friends' => true,
 584          );
 585  
 586          // Only the available components supports custom layouts.
 587          if ( ! empty( $available_components[ $component ] ) && ( bp_is_directory() || bp_is_group() || bp_is_user() ) ) {
 588              $customizer_option = sprintf( '%s_layout', $component );
 589              $layout_prefs      = bp_nouveau_get_temporary_setting(
 590                  $customizer_option,
 591                  bp_nouveau_get_appearance_settings( $customizer_option )
 592              );
 593  
 594              if ( $layout_prefs && (int) $layout_prefs > 1 ) {
 595                  $grid_classes = bp_nouveau_customizer_grid_choices( 'classes' );
 596  
 597                  if ( isset( $grid_classes[ $layout_prefs ] ) ) {
 598                      $classes = array_merge( $classes, array(
 599                          'grid',
 600                          $grid_classes[ $layout_prefs ],
 601                      ) );
 602                  }
 603  
 604                  if ( ! isset( $bp_nouveau->{$component} ) ) {
 605                      $bp_nouveau->{$component} = new stdClass;
 606                  }
 607  
 608                  // Set the global for a later use.
 609                  $bp_nouveau->{$component}->loop_layout = $layout_prefs;
 610              }
 611          }
 612  
 613          /**
 614           * Filter to edit/add classes.
 615           *
 616           * NB: you can also directly add classes into the template parts.
 617           *
 618           * @since 3.0.0
 619           *
 620           * @param array  $classes   The list of classes.
 621           * @param string $component The current component's loop.
 622           */
 623          $class_list = (array) apply_filters( 'bp_nouveau_get_loop_classes', $classes, $component );
 624  
 625          return join( ' ', array_map( 'sanitize_html_class', $class_list ) );
 626      }
 627  
 628  
 629  /**
 630   * Checks if the layout preferences is set to grid (2 or more columns).
 631   *
 632   * @since 3.0.0
 633   *
 634   * @return bool True if loop is displayed in grid mod. False otherwise.
 635   */
 636  function bp_nouveau_loop_is_grid() {
 637      $bp_nouveau = bp_nouveau();
 638      $component  = sanitize_key( bp_current_component() );
 639  
 640      return ! empty( $bp_nouveau->{$component}->loop_layout ) && $bp_nouveau->{$component}->loop_layout > 1;
 641  }
 642  
 643  /**
 644   * Returns the number of columns of the layout preferences.
 645   *
 646   * @since 3.0.0
 647   *
 648   * @return int The number of columns.
 649   */
 650  function bp_nouveau_loop_get_grid_columns() {
 651      $bp_nouveau = bp_nouveau();
 652      $component  = sanitize_key( bp_current_component() );
 653  
 654      $columns = 1;
 655  
 656      if ( ! empty( $bp_nouveau->{$component}->loop_layout ) ) {
 657          $columns = (int) $bp_nouveau->{$component}->loop_layout;
 658      }
 659  
 660      /**
 661       * Filter number of columns for this grid.
 662       *
 663       * @since 3.0.0
 664       *
 665       * @param int $columns The number of columns.
 666       */
 667      return (int) apply_filters( 'bp_nouveau_loop_get_grid_columns', $columns );
 668  }
 669  
 670  /**
 671   * Return a bool check for component directory layout.
 672   *
 673   * Checks if activity, members, groups, blogs has the vert nav layout selected.
 674   *
 675   * @since 3.0.0
 676   *
 677   * @return bool
 678   */
 679  function bp_dir_is_vert_layout() {
 680      $bp_nouveau = bp_nouveau();
 681      $component  = sanitize_key( bp_current_component() );
 682  
 683      return (bool) $bp_nouveau->{$component}->directory_vertical_layout;
 684  }
 685  
 686  /**
 687   * Template tag to wrap the Legacy actions that was used
 688   * after the components directory page.
 689   *
 690   * @since 6.0.0
 691   */
 692  function bp_nouveau_after_directory_page() {
 693      $component = bp_current_component();
 694  
 695      /**
 696       * Fires at the bottom of the activity, members, groups and blogs directory template file.
 697       *
 698       * @since 1.5.0 Added to the members, groups directory template file.
 699       * @since 2.3.0 Added to the blogs directory template file.
 700       * @since 6.0.0 Added to the activity directory template file.
 701       */
 702      do_action( "bp_after_directory_{$component}_page" );
 703  }
 704  
 705  /**
 706   * Get the full size avatar args.
 707   *
 708   * @since 3.0.0
 709   *
 710   * @return array The avatar arguments.
 711   */
 712  function bp_nouveau_avatar_args() {
 713      /**
 714       * Filter arguments for full-size avatars.
 715       *
 716       * @since 3.0.0
 717       *
 718       * @param array $args {
 719       *     @param string $type   Avatar type.
 720       *     @param int    $width  Avatar width value.
 721       *     @param int    $height Avatar height value.
 722       * }
 723       */
 724      return apply_filters( 'bp_nouveau_avatar_args', array(
 725          'type'   => 'full',
 726          'width'  => bp_core_avatar_full_width(),
 727          'height' => bp_core_avatar_full_height(),
 728      ) );
 729  }
 730  
 731  
 732  /** Template Tags for BuddyPress navigations **********************************/
 733  
 734  /*
 735   * This is the BP Nouveau Navigation Loop.
 736   *
 737   * It can be used by any object using the
 738   * BP_Core_Nav API introduced in BuddyPress 2.6.0.
 739   */
 740  
 741  /**
 742   * Init the Navigation Loop and check it has items.
 743   *
 744   * @since 3.0.0
 745   *
 746   * @param array $args {
 747   *     Array of arguments.
 748   *
 749   *     @type string $type                    The type of Nav to get (primary or secondary)
 750   *                                           Default 'primary'. Required.
 751   *     @type string $object                  The object to get the nav for (eg: 'directory', 'group_manage',
 752   *                                           or any custom object). Default ''. Optional
 753   *     @type bool   $user_has_access         Used by the secondary member's & group's nav. Default true. Optional.
 754   *     @type bool   $show_for_displayed_user Used by the primary member's nav. Default true. Optional.
 755   * }
 756   *
 757   * @return bool True if the Nav contains items. False otherwise.
 758   */
 759  function bp_nouveau_has_nav( $args = array() ) {
 760      $bp_nouveau = bp_nouveau();
 761  
 762      $n = bp_parse_args(
 763          $args,
 764          array(
 765              'type'                    => 'primary',
 766              'object'                  => '',
 767              'user_has_access'         => true,
 768              'show_for_displayed_user' => true,
 769          ),
 770          'nouveau_has_nav'
 771      );
 772  
 773      if ( empty( $n['type'] ) ) {
 774          return false;
 775      }
 776  
 777      $nav                       = array();
 778      $bp_nouveau->displayed_nav = '';
 779      $bp_nouveau->object_nav    = $n['object'];
 780  
 781      if ( bp_is_directory() || 'directory' === $bp_nouveau->object_nav ) {
 782          $bp_nouveau->displayed_nav = 'directory';
 783          $nav                       = $bp_nouveau->directory_nav->get_primary();
 784  
 785      // So far it's only possible to build a Group nav when displaying it.
 786      } elseif ( bp_is_group() ) {
 787          $bp_nouveau->displayed_nav = 'groups';
 788          $parent_slug               = bp_get_current_group_slug();
 789          $group_nav                 = buddypress()->groups->nav;
 790  
 791          if ( 'group_manage' === $bp_nouveau->object_nav && bp_is_group_admin_page() ) {
 792              $parent_slug .= '_manage';
 793  
 794          /**
 795           * If it's not the Admin tabs, reorder the Group's nav according to the
 796           * customizer setting.
 797           */
 798          } else {
 799              bp_nouveau_set_nav_item_order( $group_nav, bp_nouveau_get_appearance_settings( 'group_nav_order' ), $parent_slug );
 800          }
 801  
 802          $nav = $group_nav->get_secondary(
 803              array(
 804                  'parent_slug'     => $parent_slug,
 805                  'user_has_access' => (bool) $n['user_has_access'],
 806              )
 807          );
 808  
 809      // Build the nav for the displayed user
 810      } elseif ( bp_is_user() ) {
 811          $bp_nouveau->displayed_nav = 'personal';
 812          $user_nav                  = buddypress()->members->nav;
 813  
 814          if ( 'secondary' === $n['type'] ) {
 815              $nav = $user_nav->get_secondary(
 816                  array(
 817                      'parent_slug'     => bp_current_component(),
 818                      'user_has_access' => (bool) $n['user_has_access'],
 819                  )
 820              );
 821  
 822          } else {
 823              $args = array();
 824  
 825              if ( true === (bool) $n['show_for_displayed_user'] && ! bp_is_my_profile() ) {
 826                  $args = array( 'show_for_displayed_user' => true );
 827              }
 828  
 829              // Reorder the user's primary nav according to the customizer setting.
 830              bp_nouveau_set_nav_item_order( $user_nav, bp_nouveau_get_appearance_settings( 'user_nav_order' ) );
 831  
 832              $nav = $user_nav->get_primary( $args );
 833          }
 834  
 835      } elseif ( ! empty( $bp_nouveau->object_nav ) ) {
 836          $bp_nouveau->displayed_nav = $bp_nouveau->object_nav;
 837  
 838          /**
 839           * Use the filter to use your specific Navigation.
 840           * Use the $n param to check for your custom object.
 841           *
 842           * @since 3.0.0
 843           *
 844           * @param array $nav The list of item navigations generated by the BP_Core_Nav API.
 845           * @param array $n   The arguments of the Navigation loop.
 846           */
 847          $nav = apply_filters( 'bp_nouveau_get_nav', $nav, $n );
 848  
 849      }
 850  
 851      // The navigation can be empty.
 852      if ( $nav === false ) {
 853          $nav = array();
 854      }
 855  
 856      $bp_nouveau->sorted_nav = array_values( $nav );
 857  
 858      if ( 0 === count( $bp_nouveau->sorted_nav ) || ! $bp_nouveau->displayed_nav ) {
 859          unset( $bp_nouveau->sorted_nav, $bp_nouveau->displayed_nav, $bp_nouveau->object_nav );
 860  
 861          return false;
 862      }
 863  
 864      $bp_nouveau->current_nav_index = 0;
 865      return true;
 866  }
 867  
 868  /**
 869   * Checks there are still nav items to display.
 870   *
 871   * @since 3.0.0
 872   *
 873   * @return bool True if there are still items to display. False otherwise.
 874   */
 875  function bp_nouveau_nav_items() {
 876      $bp_nouveau = bp_nouveau();
 877  
 878      if ( isset( $bp_nouveau->sorted_nav[ $bp_nouveau->current_nav_index ] ) ) {
 879          return true;
 880      }
 881  
 882      $bp_nouveau->current_nav_index = 0;
 883      unset( $bp_nouveau->current_nav_item );
 884  
 885      return false;
 886  }
 887  
 888  /**
 889   * Sets the current nav item and prepare the navigation loop to iterate to next one.
 890   *
 891   * @since 3.0.0
 892   */
 893  function bp_nouveau_nav_item() {
 894      $bp_nouveau = bp_nouveau();
 895  
 896      $bp_nouveau->current_nav_item   = $bp_nouveau->sorted_nav[ $bp_nouveau->current_nav_index ];
 897      $bp_nouveau->current_nav_index += 1;
 898  }
 899  
 900  /**
 901   * Displays the nav item ID.
 902   *
 903   * @since 3.0.0
 904   */
 905  function bp_nouveau_nav_id() {
 906      echo esc_attr( bp_nouveau_get_nav_id() );
 907  }
 908  
 909      /**
 910       * Retrieve the ID attribute of the current nav item.
 911       *
 912       * @since 3.0.0
 913       *
 914       * @return string the ID attribute.
 915       */
 916  	function bp_nouveau_get_nav_id() {
 917          $bp_nouveau = bp_nouveau();
 918          $nav_item   = $bp_nouveau->current_nav_item;
 919  
 920          if ( 'directory' === $bp_nouveau->displayed_nav ) {
 921              $id = sprintf( '%1$s-%2$s', $nav_item->component, $nav_item->slug );
 922          } elseif ( 'groups' === $bp_nouveau->displayed_nav || 'personal' ===  $bp_nouveau->displayed_nav ) {
 923              $id = sprintf( '%1$s-%2$s-li', $nav_item->css_id, $bp_nouveau->displayed_nav );
 924          } else {
 925              $id = $nav_item->slug;
 926          }
 927  
 928          /**
 929           * Filter to edit the ID attribute of the nav.
 930           *
 931           * @since 3.0.0
 932           *
 933           * @param string $id       The ID attribute of the nav.
 934           * @param object $nav_item The current nav item object.
 935           * @param string $value    The current nav in use (eg: 'directory', 'groups', 'personal', etc..).
 936           */
 937          return apply_filters( 'bp_nouveau_get_nav_id', $id, $nav_item, $bp_nouveau->displayed_nav );
 938      }
 939  
 940  /**
 941   * Displays the nav item classes.
 942   *
 943   * @since 3.0.0
 944   */
 945  function bp_nouveau_nav_classes() {
 946      echo esc_attr( bp_nouveau_get_nav_classes() );
 947  }
 948  
 949      /**
 950       * Retrieve a space separated list of classes for the current nav item.
 951       *
 952       * @since 3.0.0
 953       *
 954       * @return string List of classes.
 955       */
 956  	function bp_nouveau_get_nav_classes() {
 957          $bp_nouveau = bp_nouveau();
 958          $nav_item   = $bp_nouveau->current_nav_item;
 959          $classes    = array();
 960  
 961          if ( 'directory' === $bp_nouveau->displayed_nav ) {
 962              if ( ! empty( $nav_item->li_class ) ) {
 963                  $classes = (array) $nav_item->li_class;
 964              }
 965  
 966              if ( bp_get_current_member_type() || ( bp_is_groups_directory() && bp_get_current_group_directory_type() ) ) {
 967                  $classes[] = 'no-ajax';
 968              }
 969          } elseif ( 'groups' === $bp_nouveau->displayed_nav || 'personal' === $bp_nouveau->displayed_nav ) {
 970              $classes  = array( 'bp-' . $bp_nouveau->displayed_nav . '-tab' );
 971              $selected = bp_current_action();
 972  
 973              // User's primary nav
 974              if ( ! empty( $nav_item->primary ) ) {
 975                  $selected = bp_current_component();
 976  
 977              // Group Admin Tabs.
 978              } elseif ( 'group_manage' === $bp_nouveau->object_nav ) {
 979                  $selected = bp_action_variable( 0 );
 980                  $classes  = array( 'bp-' . $bp_nouveau->displayed_nav . '-admin-tab' );
 981  
 982              // If we are here, it's the member's subnav
 983              } elseif ( 'personal' === $bp_nouveau->displayed_nav ) {
 984                  $classes  = array( 'bp-' . $bp_nouveau->displayed_nav . '-sub-tab' );
 985              }
 986  
 987              if ( $nav_item->slug === $selected ) {
 988                  $classes = array_merge( $classes, array( 'current', 'selected' ) );
 989              }
 990          }
 991  
 992          if ( ! empty( $classes ) ) {
 993              $classes = array_map( 'sanitize_html_class', $classes );
 994          }
 995  
 996          /**
 997           * Filter to edit/add classes.
 998           *
 999           * NB: you can also directly add classes into the template parts.
1000           *
1001           * @since 3.0.0
1002           *
1003           * @param string $value    A space separated list of classes.
1004           * @param array  $classes  The list of classes.
1005           * @param object $nav_item The current nav item object.
1006           * @param string $value    The current nav in use (eg: 'directory', 'groups', 'personal', etc..).
1007           */
1008          $classes_list = apply_filters( 'bp_nouveau_get_classes', join( ' ', $classes ), $classes, $nav_item, $bp_nouveau->displayed_nav );
1009          if ( ! $classes_list ) {
1010              $classes_list = '';
1011          }
1012  
1013          return $classes_list;
1014      }
1015  
1016  /**
1017   * Displays the nav item scope.
1018   *
1019   * @since 3.0.0
1020   */
1021  function bp_nouveau_nav_scope() {
1022      echo bp_nouveau_get_nav_scope();  // Escaped by bp_get_form_field_attributes().
1023  }
1024  
1025      /**
1026       * Retrieve the specific scope for the current nav item.
1027       *
1028       * @since 3.0.0
1029       *
1030       * @return string the specific scope of the nav.
1031       */
1032  	function bp_nouveau_get_nav_scope() {
1033          $bp_nouveau = bp_nouveau();
1034          $nav_item   = $bp_nouveau->current_nav_item;
1035          $scope      = array();
1036  
1037          if ( 'directory' === $bp_nouveau->displayed_nav ) {
1038              $scope = array( 'data-bp-scope' => $nav_item->slug );
1039  
1040          } elseif ( 'personal' === $bp_nouveau->displayed_nav && ! empty( $nav_item->secondary ) ) {
1041              $scope = array( 'data-bp-user-scope' => $nav_item->slug );
1042  
1043          } else {
1044              /**
1045               * Filter to add your own scope.
1046               *
1047               * @since 3.0.0
1048               *
1049               * @param array $scope     Contains the key and the value for your scope.
1050               * @param object $nav_item The current nav item object.
1051               * @param string $value    The current nav in use (eg: 'directory', 'groups', 'personal', etc..).
1052               */
1053              $scope = apply_filters( 'bp_nouveau_set_nav_scope', $scope, $nav_item, $bp_nouveau->displayed_nav );
1054          }
1055  
1056          if ( ! $scope ) {
1057              return '';
1058          }
1059  
1060          return bp_get_form_field_attributes( 'scope', $scope );
1061      }
1062  
1063  /**
1064   * Displays the nav item URL.
1065   *
1066   * @since 3.0.0
1067   */
1068  function bp_nouveau_nav_link() {
1069      echo esc_url( bp_nouveau_get_nav_link() );
1070  }
1071  
1072      /**
1073       * Retrieve the URL for the current nav item.
1074       *
1075       * @since 3.0.0
1076       *
1077       * @return string The URL for the nav item.
1078       */
1079  	function bp_nouveau_get_nav_link() {
1080          $bp_nouveau = bp_nouveau();
1081          $nav_item   = $bp_nouveau->current_nav_item;
1082  
1083          $link = '#';
1084          if ( ! empty( $nav_item->link ) ) {
1085              $link = $nav_item->link;
1086          }
1087  
1088          if ( 'personal' === $bp_nouveau->displayed_nav && ! empty( $nav_item->primary ) ) {
1089              if ( bp_loggedin_user_domain() ) {
1090                  $link = str_replace( bp_loggedin_user_domain(), bp_displayed_user_domain(), $link );
1091              } else {
1092                  $link = trailingslashit( bp_displayed_user_domain() . $link );
1093              }
1094          }
1095  
1096          /**
1097           * Filter to edit the URL of the nav item.
1098           *
1099           * @since 3.0.0
1100           *
1101           * @param string $link     The URL for the nav item.
1102           * @param object $nav_item The current nav item object.
1103           * @param string $value    The current nav in use (eg: 'directory', 'groups', 'personal', etc..).
1104           */
1105          return apply_filters( 'bp_nouveau_get_nav_link', $link, $nav_item, $bp_nouveau->displayed_nav );
1106      }
1107  
1108  /**
1109   * Displays the nav item link ID.
1110   *
1111   * @since 3.0.0
1112   */
1113  function bp_nouveau_nav_link_id() {
1114      echo esc_attr( bp_nouveau_get_nav_link_id() );
1115  }
1116  
1117      /**
1118       * Retrieve the id attribute of the link for the current nav item.
1119       *
1120       * @since 3.0.0
1121       *
1122       * @return string The link id for the nav item.
1123       */
1124  	function bp_nouveau_get_nav_link_id() {
1125          $bp_nouveau = bp_nouveau();
1126          $nav_item   = $bp_nouveau->current_nav_item;
1127          $link_id   = '';
1128  
1129          if ( ( 'groups' === $bp_nouveau->displayed_nav || 'personal' === $bp_nouveau->displayed_nav ) && ! empty( $nav_item->css_id ) ) {
1130              $link_id = $nav_item->css_id;
1131  
1132              if ( ! empty( $nav_item->primary ) && 'personal' === $bp_nouveau->displayed_nav ) {
1133                  $link_id = 'user-' . $link_id;
1134              }
1135          } else {
1136              $link_id = $nav_item->slug;
1137          }
1138  
1139          /**
1140           * Filter to edit the link id attribute of the nav.
1141           *
1142           * @since 3.0.0
1143           *
1144           * @param string $link_id  The link id attribute for the nav item.
1145           * @param object $nav_item The current nav item object.
1146           * @param string $value    The current nav in use (eg: 'directory', 'groups', 'personal', etc..).
1147           */
1148          return apply_filters( 'bp_nouveau_get_nav_link_id', $link_id, $nav_item, $bp_nouveau->displayed_nav );
1149      }
1150  
1151  /**
1152   * Displays the nav item link title.
1153   *
1154   * @since 3.0.0
1155   */
1156  function bp_nouveau_nav_link_title() {
1157      echo esc_attr( bp_nouveau_get_nav_link_title() );
1158  }
1159  
1160      /**
1161       * Retrieve the title attribute of the link for the current nav item.
1162       *
1163       * @since 3.0.0
1164       *
1165       * @return string The link title for the nav item.
1166       */
1167  	function bp_nouveau_get_nav_link_title() {
1168          $bp_nouveau = bp_nouveau();
1169          $nav_item   = $bp_nouveau->current_nav_item;
1170          $title      = '';
1171  
1172          if ( 'directory' === $bp_nouveau->displayed_nav && ! empty( $nav_item->title ) ) {
1173              $title = $nav_item->title;
1174  
1175          } elseif (
1176              ( 'groups' === $bp_nouveau->displayed_nav || 'personal' === $bp_nouveau->displayed_nav )
1177              &&
1178              ! empty( $nav_item->name )
1179          ) {
1180              $title = $nav_item->name;
1181          }
1182  
1183          /**
1184           * Filter to edit the link title attribute of the nav.
1185           *
1186           * @since 3.0.0
1187           *
1188           * @param string $title    The link title attribute for the nav item.
1189           * @param object $nav_item The current nav item object.
1190           * @param string $value    The current nav in use (eg: 'directory', 'groups', 'personal', etc..).
1191           */
1192          return apply_filters( 'bp_nouveau_get_nav_link_title', $title, $nav_item, $bp_nouveau->displayed_nav );
1193      }
1194  
1195  /**
1196   * Displays the nav item link html text.
1197   *
1198   * @since 3.0.0
1199   */
1200  function bp_nouveau_nav_link_text() {
1201      echo esc_html( bp_nouveau_get_nav_link_text() );
1202  }
1203  
1204      /**
1205       * Retrieve the html text of the link for the current nav item.
1206       *
1207       * @since 3.0.0
1208       *
1209       * @return string The html text for the nav item.
1210       */
1211  	function bp_nouveau_get_nav_link_text() {
1212          $bp_nouveau = bp_nouveau();
1213          $nav_item   = $bp_nouveau->current_nav_item;
1214          $link_text  = '';
1215  
1216          if ( 'directory' === $bp_nouveau->displayed_nav && ! empty( $nav_item->text ) ) {
1217              $link_text = _bp_strip_spans_from_title( $nav_item->text );
1218  
1219          } elseif (
1220              ( 'groups' === $bp_nouveau->displayed_nav || 'personal' === $bp_nouveau->displayed_nav )
1221              &&
1222              ! empty( $nav_item->name )
1223          ) {
1224              $link_text = _bp_strip_spans_from_title( $nav_item->name );
1225          }
1226  
1227          /**
1228           * Filter to edit the html text of the nav.
1229           *
1230           * @since 3.0.0
1231           *
1232           * @param string $link_text The html text of the nav item.
1233           * @param object $nav_item  The current nav item object.
1234           * @param string $value     The current nav in use (eg: 'directory', 'groups', 'personal', etc..).
1235           */
1236          return apply_filters( 'bp_nouveau_get_nav_link_text', $link_text, $nav_item, $bp_nouveau->displayed_nav );
1237      }
1238  
1239  /**
1240   * Checks if the nav item has a count attribute.
1241   *
1242   * @since 3.0.0
1243   *
1244   * @return bool
1245   */
1246  function bp_nouveau_nav_has_count() {
1247      $bp_nouveau = bp_nouveau();
1248      $nav_item   = $bp_nouveau->current_nav_item;
1249      $count      = false;
1250  
1251      if ( 'directory' === $bp_nouveau->displayed_nav ) {
1252          $count = $nav_item->count;
1253      } elseif ( 'groups' === $bp_nouveau->displayed_nav && 'members' === $nav_item->slug ) {
1254          $count = 0 !== (int) groups_get_current_group()->total_member_count;
1255      } elseif ( 'personal' === $bp_nouveau->displayed_nav && ! empty( $nav_item->primary ) ) {
1256          $count = (bool) strpos( $nav_item->name, '="count"' );
1257      }
1258  
1259      /**
1260       * Filter to edit whether the nav has a count attribute.
1261       *
1262       * @since 3.0.0
1263       *
1264       * @param bool   $value     True if the nav has a count attribute. False otherwise
1265       * @param object $nav_item  The current nav item object.
1266       * @param string $value     The current nav in use (eg: 'directory', 'groups', 'personal', etc..).
1267       */
1268      return (bool) apply_filters( 'bp_nouveau_nav_has_count', false !== $count, $nav_item, $bp_nouveau->displayed_nav );
1269  }
1270  
1271  /**
1272   * Displays the nav item count attribute.
1273   *
1274   * @since 3.0.0
1275   */
1276  function bp_nouveau_nav_count() {
1277      echo esc_html( number_format_i18n( bp_nouveau_get_nav_count() ) );
1278  }
1279  
1280      /**
1281       * Retrieve the count attribute for the current nav item.
1282       *
1283       * @since 3.0.0
1284       *
1285       * @return int The count attribute for the nav item.
1286       */
1287  	function bp_nouveau_get_nav_count() {
1288          $bp_nouveau = bp_nouveau();
1289          $nav_item   = $bp_nouveau->current_nav_item;
1290          $count      = 0;
1291  
1292          if ( 'directory' === $bp_nouveau->displayed_nav ) {
1293              $count = (int) $nav_item->count;
1294  
1295          } elseif ( 'groups' === $bp_nouveau->displayed_nav && 'members' === $nav_item->slug ) {
1296              $count = groups_get_current_group()->total_member_count;
1297  
1298          // @todo imho BuddyPress shouldn't add html tags inside Nav attributes...
1299          } elseif ( 'personal' === $bp_nouveau->displayed_nav && ! empty( $nav_item->primary ) ) {
1300              $span = strpos( $nav_item->name, '<span' );
1301  
1302              // Grab count out of the <span> element.
1303              if ( false !== $span ) {
1304                  $count_start = strpos( $nav_item->name, '>', $span ) + 1;
1305                  $count_end   = strpos( $nav_item->name, '<', $count_start );
1306                  $count       = (int) substr( $nav_item->name, $count_start, $count_end - $count_start );
1307              }
1308          }
1309  
1310          /**
1311           * Filter to edit the count attribute for the nav item.
1312           *
1313           * @since 3.0.0
1314           *
1315           * @param int $count    The count attribute for the nav item.
1316           * @param object $nav_item The current nav item object.
1317           * @param string $value    The current nav in use (eg: 'directory', 'groups', 'personal', etc..).
1318           */
1319          return (int) apply_filters( 'bp_nouveau_get_nav_count', $count, $nav_item, $bp_nouveau->displayed_nav );
1320      }
1321  
1322  /** Template tags specific to the Directory navs ******************************/
1323  
1324  /**
1325   * Displays the directory nav class.
1326   *
1327   * @since 3.0.0
1328   */
1329  function bp_nouveau_directory_type_navs_class() {
1330      echo esc_attr( bp_nouveau_get_directory_type_navs_class() );
1331  }
1332  
1333      /**
1334       * Provides default nav wrapper classes.
1335       *
1336       * Gets the directory component nav class.
1337       * Gets user selection Customizer options.
1338       *
1339       * @since 3.0.0
1340       *
1341       * @return string
1342       */
1343  	function bp_nouveau_get_directory_type_navs_class() {
1344          $component  = sanitize_key( bp_current_component() );
1345  
1346          // If component is 'blogs' we need to access options as 'Sites'.
1347          if ('blogs' === $component) {
1348              $component = 'sites';
1349          };
1350  
1351          $customizer_option = sprintf( '%s_dir_tabs', $component );
1352          $nav_style  = bp_nouveau_get_temporary_setting( $customizer_option, bp_nouveau_get_appearance_settings( $customizer_option ) );
1353          $tab_style = '';
1354  
1355          if ( 1 === $nav_style ) {
1356              $tab_style = $component . '-nav-tabs';
1357          }
1358  
1359          $nav_wrapper_classes = array(
1360              sprintf( '%s-type-navs', $component ),
1361              'main-navs',
1362              'bp-navs',
1363              'dir-navs',
1364              $tab_style
1365          );
1366  
1367          /**
1368           * Filter to edit/add classes.
1369           *
1370           * NB: you can also directly add classes to the class attr.
1371           *
1372           * @since 3.0.0
1373           *
1374           * @param array $nav_wrapper_classes The list of classes.
1375           */
1376          $nav_wrapper_classes = (array) apply_filters( 'bp_nouveau_get_directory_type_navs_class', $nav_wrapper_classes );
1377  
1378          return join( ' ', array_map( 'sanitize_html_class', $nav_wrapper_classes ) );
1379      }
1380  
1381  /**
1382   * Displays the directory nav item list class.
1383   *
1384   * @since 3.0.0
1385   */
1386  function bp_nouveau_directory_list_class() {
1387      echo esc_attr( bp_nouveau_get_directory_list_class() );
1388  }
1389  
1390      /**
1391       * Gets the directory nav item list class.
1392       *
1393       * @since 3.0.0
1394       *
1395       * @return string
1396       */
1397  	function bp_nouveau_get_directory_list_class() {
1398          return sanitize_html_class( sprintf( '%s-nav', bp_current_component() ) );
1399      }
1400  
1401  /**
1402   * Displays the directory nav item object (data-bp attribute).
1403   *
1404   * @since 3.0.0
1405   */
1406  function bp_nouveau_directory_nav_object() {
1407      $obj = bp_nouveau_get_directory_nav_object();
1408  
1409      if ( ! is_null( $obj ) ) {
1410          echo esc_attr( $obj );
1411      }
1412  }
1413  
1414      /**
1415       * Gets the directory nav item object.
1416       *
1417       * @see BP_Component::setup_nav().
1418       *
1419       * @since 3.0.0
1420       *
1421       * @return array
1422       */
1423  	function bp_nouveau_get_directory_nav_object() {
1424          $nav_item = bp_nouveau()->current_nav_item;
1425  
1426          if ( ! $nav_item->component ) {
1427              return null;
1428          }
1429  
1430          return $nav_item->component;
1431      }
1432  
1433  
1434  // Template tags for the single item navs.
1435  
1436  /**
1437   * Output main BuddyPress container classes.
1438   *
1439   * @since 3.0.0
1440   *
1441   * @return string CSS classes
1442   */
1443  function bp_nouveau_container_classes() {
1444      echo esc_attr( bp_nouveau_get_container_classes() );
1445  }
1446  
1447      /**
1448       * Returns the main BuddyPress container classes.
1449       *
1450       * @since 3.0.0
1451       *
1452       * @return string CSS classes
1453       */
1454  	function bp_nouveau_get_container_classes() {
1455          $classes           = array( 'buddypress-wrap' );
1456          $component         = bp_current_component();
1457          $bp_nouveau        = bp_nouveau();
1458          $member_type_class = '';
1459  
1460          if ( bp_is_user() ) {
1461              $customizer_option = 'user_nav_display';
1462              $component         = 'members';
1463              $user_type         = bp_get_member_type( bp_displayed_user_id() );
1464              $member_type_class = ( $user_type )? $user_type : '';
1465  
1466          } elseif ( bp_is_group() ) {
1467              $customizer_option = 'group_nav_display';
1468  
1469          } elseif ( bp_is_directory() ) {
1470              switch ( $component ) {
1471                  case 'activity':
1472                      $customizer_option = 'activity_dir_layout';
1473                      break;
1474  
1475                  case 'members':
1476                      $customizer_option = 'members_dir_layout';
1477                      break;
1478  
1479                  case 'groups':
1480                      $customizer_option = 'groups_dir_layout';
1481                      break;
1482  
1483                  case 'blogs':
1484                      $customizer_option = 'sites_dir_layout';
1485                      break;
1486  
1487                  default:
1488                      $customizer_option = '';
1489                      break;
1490              }
1491  
1492          } else {
1493              /**
1494               * Filters the BuddyPress Nouveau single item setting ID.
1495               *
1496               * @since 3.0.0
1497               *
1498               * @param string $value Setting ID.
1499               */
1500              $customizer_option = apply_filters( 'bp_nouveau_single_item_display_settings_id', '' );
1501          }
1502  
1503          if ( $member_type_class ) {
1504              $classes[] = $member_type_class;
1505          }
1506  
1507          // Provide a class token to acknowledge additional extended profile fields added to default account reg screen
1508          if ( 'register' === bp_current_component() && bp_is_active( 'xprofile' ) && bp_nouveau_base_account_has_xprofile()) {
1509              $classes[] = 'extended-default-reg';
1510          }
1511  
1512          // Add classes according to site owners preferences. These are options set via Customizer.
1513  
1514          // These are general site wide Cust options falling outside component checks
1515          $general_settings = bp_nouveau_get_temporary_setting( 'avatar_style', bp_nouveau_get_appearance_settings( 'avatar_style' ) );
1516          if ( $general_settings ) {
1517              $classes[] = 'round-avatars';
1518          }
1519  
1520          // Set via earlier switch for component check to provide correct option key.
1521          if ( $customizer_option ) {
1522              $layout_prefs  = bp_nouveau_get_temporary_setting( $customizer_option, bp_nouveau_get_appearance_settings( $customizer_option ) );
1523  
1524              if ( $layout_prefs && (int) $layout_prefs === 1 && ( bp_is_user() || bp_is_group() ) ) {
1525                  $classes[] = 'bp-single-vert-nav';
1526                  $classes[] = 'bp-vertical-navs';
1527              }
1528  
1529              if ( $layout_prefs && bp_is_directory() ) {
1530                  $classes[] = 'bp-dir-vert-nav';
1531                  $classes[] = 'bp-vertical-navs';
1532                  $bp_nouveau->{$component}->directory_vertical_layout = $layout_prefs;
1533              } else {
1534                  $classes[] = 'bp-dir-hori-nav';
1535              }
1536          }
1537  
1538          $global_alignment = bp_nouveau_get_temporary_setting( 'global_alignment', bp_nouveau_get_appearance_settings( 'global_alignment' ) );
1539          if ( $global_alignment && 'alignnone' !== $global_alignment && current_theme_supports( 'align-wide' ) ) {
1540              $classes[] = $global_alignment;
1541          }
1542  
1543          $class = array_map( 'sanitize_html_class', $classes );
1544  
1545          /**
1546           * Filters the final results for BuddyPress Nouveau container classes.
1547           *
1548           * This filter will return a single string of concatenated classes to be used.
1549           *
1550           * @since 3.0.0
1551           *
1552           * @param string $value   Concatenated classes.
1553           * @param array  $classes Array of classes that were concatenated.
1554           */
1555          return apply_filters( 'bp_nouveau_get_container_classes', join( ' ', $class ), $classes );
1556      }
1557  
1558  /**
1559   * Output single item nav container classes
1560   *
1561   * @since 3.0.0
1562   *
1563   * @return string CSS classes
1564   */
1565  function bp_nouveau_single_item_nav_classes() {
1566      echo esc_attr( bp_nouveau_get_single_item_nav_classes() );
1567  }
1568  
1569      /**
1570       * Returns the single item nav container classes
1571       *
1572       * @since 3.0.0
1573       *
1574       * @return string CSS classes
1575       */
1576  	function bp_nouveau_get_single_item_nav_classes() {
1577          $classes    = array( 'main-navs', 'no-ajax', 'bp-navs', 'single-screen-navs' );
1578          $component  = bp_current_component();
1579          $bp_nouveau = bp_nouveau();
1580  
1581          // @todo wasn't able to get $customizer_option to pass a string to get_settings
1582          // this is a temp workaround but differs from earlier dir approach- bad!
1583          if ( bp_is_group() ) {
1584              $nav_tabs = (int) bp_nouveau_get_temporary_setting( 'group_nav_tabs', bp_nouveau_get_appearance_settings( 'group_nav_tabs' ) );
1585  
1586          } elseif ( bp_is_user() ) {
1587              $nav_tabs = (int) bp_nouveau_get_temporary_setting( 'user_nav_tabs', bp_nouveau_get_appearance_settings( 'user_nav_tabs' ) );
1588          }
1589  
1590          if ( bp_is_group() && 1 === $nav_tabs) {
1591              $classes[] = 'group-nav-tabs';
1592              $classes[] = 'tabbed-links';
1593          } elseif ( bp_is_user() && 1 === $nav_tabs ) {
1594              $classes[] = 'user-nav-tabs';
1595              $classes[] = 'tabbed-links';
1596          }
1597  
1598          if ( bp_is_user() ) {
1599              $component = 'members';
1600              $menu_type = 'users-nav';
1601          } else {
1602              $menu_type = 'groups-nav';
1603          }
1604  
1605          $customizer_option = ( bp_is_user() )? 'user_nav_display' : 'group_nav_display';
1606  
1607          $layout_prefs = (int) bp_nouveau_get_temporary_setting( $customizer_option, bp_nouveau_get_appearance_settings( $customizer_option ) );
1608  
1609          // Set the global for a later use - this is moved from the `bp_nouveau_get_container_classes()
1610          // But was set as a check for this array class addition.
1611          $bp_nouveau->{$component}->single_primary_nav_layout = $layout_prefs;
1612  
1613          if ( 1 === $layout_prefs ) {
1614              $classes[] = 'vertical';
1615          } else {
1616              $classes[] = 'horizontal';
1617          }
1618  
1619          $classes[] = $menu_type;
1620          $class = array_map( 'sanitize_html_class', $classes );
1621  
1622          /**
1623           * Filters the final results for BuddyPress Nouveau single item nav classes.
1624           *
1625           * This filter will return a single string of concatenated classes to be used.
1626           *
1627           * @since 3.0.0
1628           *
1629           * @param string $value   Concatenated classes.
1630           * @param array  $classes Array of classes that were concatenated.
1631           */
1632          return apply_filters( 'bp_nouveau_get_single_item_nav_classes', join( ' ', $class ), $classes );
1633      }
1634  
1635  /**
1636   * Output single item subnav container classes.
1637   *
1638   * @since 3.0.0
1639   *
1640   * @return string CSS classes
1641   */
1642  function bp_nouveau_single_item_subnav_classes() {
1643      echo esc_attr( bp_nouveau_get_single_item_subnav_classes() );
1644  }
1645  
1646      /**
1647       * Returns the single item subnav container classes.
1648       *
1649       * @since 3.0.0
1650       *
1651       * @return string CSS classes
1652       */
1653  	function bp_nouveau_get_single_item_subnav_classes() {
1654          $classes = array( 'bp-navs', 'bp-subnavs', 'no-ajax' );
1655  
1656          // Set user or group class string
1657          if ( bp_is_user() ) {
1658              $classes[] = 'user-subnav';
1659          }
1660  
1661          if ( bp_is_group() ) {
1662              $classes[] = 'group-subnav';
1663          }
1664  
1665          if ( ( bp_is_group() && 'send-invites' === bp_current_action() ) || ( bp_is_group_create() && 'group-invites' === bp_get_groups_current_create_step() ) ) {
1666              $classes[] = 'bp-invites-nav';
1667          }
1668  
1669          $customizer_option = ( bp_is_user() )? 'user_subnav_tabs' : 'group_subnav_tabs';
1670          $nav_tabs = (int) bp_nouveau_get_temporary_setting( $customizer_option, bp_nouveau_get_appearance_settings( $customizer_option ) );
1671  
1672          if ( bp_is_user() && 1 === $nav_tabs ) {
1673              $classes[] = 'tabbed-links';
1674          }
1675  
1676          if ( bp_is_group() && 1 === $nav_tabs ) {
1677              $classes[] = 'tabbed-links';
1678          }
1679  
1680          $class = array_map( 'sanitize_html_class', $classes );
1681  
1682          /**
1683           * Filters the final results for BuddyPress Nouveau single item subnav classes.
1684           *
1685           * This filter will return a single string of concatenated classes to be used.
1686           *
1687           * @since 3.0.0
1688           *
1689           * @param string $value   Concatenated classes.
1690           * @param array  $classes Array of classes that were concatenated.
1691           */
1692          return apply_filters( 'bp_nouveau_get_single_item_subnav_classes', join( ' ', $class ), $classes );
1693      }
1694  
1695  /**
1696   * Output the groups create steps classes.
1697   *
1698   * @since 3.0.0
1699   *
1700   * @return string CSS classes
1701   */
1702  function bp_nouveau_groups_create_steps_classes() {
1703      echo esc_attr( bp_nouveau_get_group_create_steps_classes() );
1704  }
1705  
1706      /**
1707       * Returns the groups create steps customizer option choice class.
1708       *
1709       * @since 3.0.0
1710       *
1711       * @return string CSS classes
1712       */
1713  	function bp_nouveau_get_group_create_steps_classes() {
1714          $classes  = array( 'bp-navs', 'group-create-links', 'no-ajax' );
1715          $nav_tabs = (int) bp_nouveau_get_temporary_setting( 'groups_create_tabs', bp_nouveau_get_appearance_settings( 'groups_create_tabs' ) );
1716  
1717          if ( 1 === $nav_tabs ) {
1718              $classes[] = 'tabbed-links';
1719          }
1720  
1721          $class = array_map( 'sanitize_html_class', $classes );
1722  
1723          /**
1724           * Filters the final results for BuddyPress Nouveau group creation step classes.
1725           *
1726           * This filter will return a single string of concatenated classes to be used.
1727           *
1728           * @since 3.0.0
1729           *
1730           * @param string $value   Concatenated classes.
1731           * @param array  $classes Array of classes that were concatenated.
1732           */
1733          return apply_filters( 'bp_nouveau_get_group_create_steps_classes', join( ' ', $class ), $classes );
1734      }
1735  
1736  
1737  /** Template tags for the object search **************************************/
1738  
1739  /**
1740   * Get the search primary object
1741   *
1742   * @since 3.0.0
1743   *
1744   * @param string $object Optional. The primary object.
1745   *
1746   * @return string The primary object.
1747   */
1748  function bp_nouveau_get_search_primary_object( $object = '' ) {
1749      if ( bp_is_user() ) {
1750          $object = 'member';
1751      } elseif ( bp_is_group() ) {
1752          $object = 'group';
1753      } elseif ( bp_is_directory() ) {
1754          $object = 'dir';
1755      } else {
1756  
1757          /**
1758           * Filters the search primary object if no other was found.
1759           *
1760           * @since 3.0.0
1761           *
1762           * @param string $object Search object.
1763           */
1764          $object = apply_filters( 'bp_nouveau_get_search_primary_object', $object );
1765      }
1766  
1767      return $object;
1768  }
1769  
1770  /**
1771   * Get The list of search objects (primary + secondary).
1772   *
1773   * @since 3.0.0
1774   *
1775   * @param array $objects Optional. The list of objects.
1776   *
1777   * @return array The list of objects.
1778   */
1779  function bp_nouveau_get_search_objects( $objects = array() ) {
1780      $primary = bp_nouveau_get_search_primary_object();
1781      if ( ! $primary ) {
1782          return $objects;
1783      }
1784  
1785      $objects = array(
1786          'primary' => $primary,
1787      );
1788  
1789      if ( 'member' === $primary || 'dir' === $primary ) {
1790          $objects['secondary'] = bp_current_component();
1791      } elseif ( 'group' === $primary ) {
1792          $objects['secondary'] = bp_current_action();
1793      } else {
1794  
1795          /**
1796           * Filters the search objects if no others were found.
1797           *
1798           * @since 3.0.0
1799           *
1800           * @param array $objects Search objects.
1801           */
1802          $objects = apply_filters( 'bp_nouveau_get_search_objects', $objects );
1803      }
1804  
1805      return $objects;
1806  }
1807  
1808  /**
1809   * Output the search form container classes.
1810   *
1811   * @since 3.0.0
1812   */
1813  function bp_nouveau_search_container_class() {
1814      $objects = bp_nouveau_get_search_objects();
1815      $class   = join( '-search ', array_map( 'sanitize_html_class', $objects ) ) . '-search';
1816  
1817      echo esc_attr( $class );
1818  }
1819  
1820  /**
1821   * Output the search form data-bp attribute.
1822   *
1823   * @since 3.0.0
1824   *
1825   * @param  string $attr The data-bp attribute.
1826   * @return string The data-bp attribute.
1827   */
1828  function bp_nouveau_search_object_data_attr( $attr = '' ) {
1829      $objects = bp_nouveau_get_search_objects();
1830  
1831      if ( ! isset( $objects['secondary'] ) ) {
1832          return $attr;
1833      }
1834  
1835      if ( bp_is_active( 'groups' ) && bp_is_group_members() ) {
1836          $attr = join( '_', $objects );
1837      } else {
1838          $attr = $objects['secondary'];
1839      }
1840  
1841      echo esc_attr( $attr );
1842  }
1843  
1844  /**
1845   * Output a selector ID.
1846   *
1847   * @since 3.0.0
1848   *
1849   * @param string $suffix Optional. A string to append at the end of the ID.
1850   * @param string $sep    Optional. The separator to use between each token.
1851   *
1852   * @return string The selector ID.
1853   */
1854  function bp_nouveau_search_selector_id( $suffix = '', $sep = '-' ) {
1855      $id = join( $sep, array_merge( bp_nouveau_get_search_objects(), (array) $suffix ) );
1856      echo esc_attr( $id );
1857  }
1858  
1859  /**
1860   * Output the name attribute of a selector.
1861   *
1862   * @since 3.0.0
1863   *
1864   * @param  string $suffix Optional. A string to append at the end of the name.
1865   * @param  string $sep    Optional. The separator to use between each token.
1866   *
1867   * @return string The name attribute of a selector.
1868   */
1869  function bp_nouveau_search_selector_name( $suffix = '', $sep = '_' ) {
1870      $objects = bp_nouveau_get_search_objects();
1871  
1872      if ( isset( $objects['secondary'] ) && ! $suffix ) {
1873          $name = bp_core_get_component_search_query_arg( $objects['secondary'] );
1874      } else {
1875          $name = join( $sep, array_merge( $objects, (array) $suffix ) );
1876      }
1877  
1878      echo esc_attr( $name );
1879  }
1880  
1881  /**
1882   * Output the default search text for the search object
1883   *
1884   * @since 3.0.0
1885   *
1886   * @param  string $text    Optional. The default search text for the search object.
1887   * @param  string $is_attr Optional. True if it's to be output inside an attribute. False Otherwise.
1888   *
1889   * @return string The default search text.
1890   *
1891   * @todo 28/09/17 added  'empty( $text )' check to $object query as it wasn't returning output as expected & not returning user set params
1892   * This may require further examination - hnla
1893   */
1894  function bp_nouveau_search_default_text( $text = '', $is_attr = true ) {
1895      $objects = bp_nouveau_get_search_objects();
1896  
1897      if ( ! empty( $objects['secondary'] ) && empty( $text ) ) {
1898          $text = bp_get_search_default_text( $objects['secondary'] );
1899      }
1900  
1901      if ( $is_attr ) {
1902          echo esc_attr( $text );
1903      } else {
1904          echo esc_html( $text );
1905      }
1906  }
1907  
1908  /**
1909   * Get the search form template part and fire some do_actions if needed.
1910   *
1911   * @since 3.0.0
1912   */
1913  function bp_nouveau_search_form() {
1914      $search_form_html = bp_buffer_template_part( 'common/search/search-form', null, false );
1915  
1916      $objects = bp_nouveau_get_search_objects();
1917      if ( empty( $objects['primary'] ) || empty( $objects['secondary'] ) ) {
1918          echo $search_form_html;
1919          return;
1920      }
1921  
1922      if ( 'dir' === $objects['primary'] ) {
1923          /**
1924           * Filter here to edit the HTML output of the directory search form.
1925           *
1926           * NB: This will take in charge the following BP Core Components filters
1927           *     - bp_directory_members_search_form
1928           *     - bp_directory_blogs_search_form
1929           *     - bp_directory_groups_search_form
1930           *
1931           * @since 1.9.0
1932           *
1933           * @param string $search_form_html The HTML output for the directory search form.
1934           */
1935          echo apply_filters( "bp_directory_{$objects['secondary']}_search_form", $search_form_html );
1936  
1937          if ( 'activity' === $objects['secondary'] ) {
1938              /**
1939               * Fires before the display of the activity syndication options.
1940               *
1941               * @since 1.2.0
1942               */
1943              do_action( 'bp_activity_syndication_options' );
1944  
1945          } elseif ( 'blogs' === $objects['secondary'] ) {
1946              /**
1947               * Fires inside the unordered list displaying blog sub-types.
1948               *
1949               * @since 1.5.0
1950               */
1951              do_action( 'bp_blogs_directory_blog_sub_types' );
1952  
1953          } elseif ( 'groups' === $objects['secondary'] ) {
1954              /**
1955               * Fires inside the groups directory group types.
1956               *
1957               * @since 1.2.0
1958               */
1959              do_action( 'bp_groups_directory_group_types' );
1960  
1961          } elseif ( 'members' === $objects['secondary'] ) {
1962              /**
1963               * Fires inside the members directory member sub-types.
1964               *
1965               * @since 1.5.0
1966               */
1967              do_action( 'bp_members_directory_member_sub_types' );
1968          }
1969      } elseif ( 'group' === $objects['primary'] ) {
1970          if ( 'members' !== $objects['secondary'] ) {
1971              /**
1972               * Filter here to edit the HTML output of the displayed group search form.
1973               *
1974               * @since 3.2.0
1975               *
1976               * @param string $search_form_html The HTML output for the directory search form.
1977               */
1978              echo apply_filters( "bp_group_{$objects['secondary']}_search_form", $search_form_html );
1979  
1980          } else {
1981              /**
1982               * Filters the Members component search form.
1983               *
1984               * @since 1.9.0
1985               *
1986               * @param string $search_form_html HTML markup for the member search form.
1987               */
1988              echo apply_filters( 'bp_directory_members_search_form', $search_form_html );
1989          }
1990  
1991          if ( 'members' === $objects['secondary'] ) {
1992              /**
1993               * Fires at the end of the group members search unordered list.
1994               *
1995               * Part of bp_groups_members_template_part().
1996               *
1997               * @since 1.5.0
1998               */
1999              do_action( 'bp_members_directory_member_sub_types' );
2000  
2001          } elseif ( 'activity' === $objects['secondary'] ) {
2002              /**
2003               * Fires inside the syndication options list, after the RSS option.
2004               *
2005               * @since 1.2.0
2006               */
2007              do_action( 'bp_group_activity_syndication_options' );
2008          }
2009      }
2010  }
2011  
2012  
2013  // Template tags for the directory & user/group screen filters.
2014  
2015  /**
2016   * Get the current component or action.
2017   *
2018   * If on single group screens we need to switch from component to bp_current_action() to add the correct
2019   * IDs/labels for group/activity & similar screens.
2020   *
2021   * @since 3.0.0
2022   */
2023  function bp_nouveau_current_object() {
2024      /*
2025       * If we're looking at groups single screens we need to factor in current action
2026       * to avoid the component check adding the wrong id for the main dir e.g 'groups' instead of 'activity'.
2027       * We also need to check for group screens to adjust the id's for prefixes.
2028       */
2029      $component = array();
2030  
2031      if ( bp_is_group() ) {
2032          $component['members_select']   = 'groups_members-order-select';
2033          $component['members_order_by'] = 'groups_members-order-by';
2034          $component['object']           = bp_current_action();
2035          $component['data_filter']      = bp_current_action();
2036  
2037          if ( 'activity' !== bp_current_action() ) {
2038              $component['data_filter'] = 'group_' . bp_current_action();
2039          }
2040  
2041      } else {
2042          $data_filter = bp_current_component();
2043          if ( 'friends' === $data_filter && bp_is_user_friend_requests() ) {
2044              $data_filter = 'friend_requests';
2045          }
2046  
2047          $component['members_select']   = 'members-order-select';
2048          $component['members_order_by'] = 'members-order-by';
2049          $component['object']           = bp_current_component();
2050          $component['data_filter']      = $data_filter;
2051      }
2052  
2053      return $component;
2054  }
2055  
2056  /**
2057   * Output data filter container's ID attribute value.
2058   *
2059   * @since 3.0.0
2060   */
2061  function bp_nouveau_filter_container_id() {
2062      echo esc_attr( bp_nouveau_get_filter_container_id() );
2063  }
2064  
2065      /**
2066       * Get data filter container's ID attribute value.
2067       *
2068       * @since 3.0.0
2069       *
2070       * @param string
2071       */
2072  	function bp_nouveau_get_filter_container_id() {
2073          $component = bp_nouveau_current_object();
2074  
2075          $ids = array(
2076              'members'       =>  $component['members_select'],
2077              'friends'       => 'members-friends-select',
2078              'notifications' => 'notifications-filter-select',
2079              'activity'      => 'activity-filter-select',
2080              'groups'        => 'groups-order-select',
2081              'blogs'         => 'blogs-order-select',
2082          );
2083  
2084          if ( isset( $ids[ $component['object'] ] ) ) {
2085  
2086              /**
2087               * Filters the container ID for BuddyPress Nouveau filters.
2088               *
2089               * @since 3.0.0
2090               *
2091               * @param string $value ID based on current component object.
2092               */
2093              return apply_filters( 'bp_nouveau_get_filter_container_id', $ids[ $component['object'] ] );
2094          }
2095  
2096          return '';
2097      }
2098  
2099  /**
2100   * Output data filter's ID attribute value.
2101   *
2102   * @since 3.0.0
2103   */
2104  function bp_nouveau_filter_id() {
2105      echo esc_attr( bp_nouveau_get_filter_id() );
2106  }
2107  
2108      /**
2109       * Get data filter's ID attribute value.
2110       *
2111       * @since 3.0.0
2112       *
2113       * @param string
2114       */
2115  	function bp_nouveau_get_filter_id() {
2116          $component = bp_nouveau_current_object();
2117  
2118          $ids = array(
2119              'members'       => $component['members_order_by'],
2120              'friends'       => 'members-friends',
2121              'notifications' => 'notifications-filter-by',
2122              'activity'      => 'activity-filter-by',
2123              'groups'        => 'groups-order-by',
2124              'blogs'         => 'blogs-order-by',
2125          );
2126  
2127          if ( isset( $ids[ $component['object'] ] ) ) {
2128  
2129              /**
2130               * Filters the filter ID for BuddyPress Nouveau filters.
2131               *
2132               * @since 3.0.0
2133               *
2134               * @param string $value ID based on current component object.
2135               */
2136              return apply_filters( 'bp_nouveau_get_filter_id', $ids[ $component['object'] ] );
2137          }
2138  
2139          return '';
2140      }
2141  
2142  /**
2143   * Output data filter's label.
2144   *
2145   * @since 3.0.0
2146   */
2147  function bp_nouveau_filter_label() {
2148      echo esc_html( bp_nouveau_get_filter_label() );
2149  }
2150  
2151      /**
2152       * Get data filter's label.
2153        *
2154       * @since 3.0.0
2155       *
2156       * @param string
2157       */
2158  	function bp_nouveau_get_filter_label() {
2159          $component = bp_nouveau_current_object();
2160          $label     = __( 'Order By:', 'buddypress' );
2161  
2162          if ( 'activity' === $component['object'] || 'friends' === $component['object'] ) {
2163              $label = __( 'Show:', 'buddypress' );
2164          }
2165  
2166          /**
2167           * Filters the label for BuddyPress Nouveau filters.
2168           *
2169           * @since 3.0.0
2170           *
2171           * @param string $label     Label for BuddyPress Nouveau filter.
2172           * @param array  $component The data filter's data-bp-filter attribute value.
2173           */
2174          return apply_filters( 'bp_nouveau_get_filter_label', $label, $component );
2175      }
2176  
2177  /**
2178   * Output data filter's data-bp-filter attribute value.
2179   *
2180   * @since 3.0.0
2181   */
2182  function bp_nouveau_filter_component() {
2183      $component = bp_nouveau_current_object();
2184      echo esc_attr( $component['data_filter'] );
2185  }
2186  
2187  /**
2188   * Output the <option> of the data filter's <select> element.
2189   *
2190   * @since 3.0.0
2191   */
2192  function bp_nouveau_filter_options() {
2193      echo bp_nouveau_get_filter_options();  // Escaped in inner functions.
2194  }
2195  
2196      /**
2197       * Get the <option> of the data filter's <select> element.
2198       *
2199       * @since 3.0.0
2200       *
2201       * @return string
2202       */
2203  	function bp_nouveau_get_filter_options() {
2204          $output = '';
2205  
2206          if ( 'notifications' === bp_current_component() ) {
2207              $output = bp_nouveau_get_notifications_filters();
2208  
2209          } else {
2210              $filters = bp_nouveau_get_component_filters();
2211  
2212              foreach ( $filters as $key => $value ) {
2213                  $output .= sprintf( '<option value="%1$s">%2$s</option>%3$s',
2214                      esc_attr( $key ),
2215                      esc_html( $value ),
2216                      PHP_EOL
2217                  );
2218              }
2219          }
2220  
2221          return $output;
2222      }
2223  
2224  
2225  /** Template tags for the Customizer ******************************************/
2226  
2227  /**
2228   * Get a link to reach a specific section into the customizer
2229   *
2230   * @since 3.0.0
2231   *
2232   * @param array $args Optional. The argument to customize the Customizer link.
2233   *
2234   * @return string HTML.
2235   */
2236  function bp_nouveau_get_customizer_link( $args = array() ) {
2237      $r = bp_parse_args( $args, array(
2238          'capability' => 'bp_moderate',
2239          'object'     => 'user',
2240          'item_id'    => 0,
2241          'autofocus'  => '',
2242          'text'       => '',
2243      ), 'nouveau_get_customizer_link' );
2244  
2245      if ( empty( $r['capability'] ) || empty( $r['autofocus'] ) || empty( $r['text'] ) ) {
2246          return '';
2247      }
2248  
2249      if ( ! bp_current_user_can( $r['capability'] ) ) {
2250          return '';
2251      }
2252  
2253      $url = '';
2254  
2255      if ( bp_is_user() ) {
2256          $url = rawurlencode( bp_displayed_user_domain() );
2257  
2258      } elseif ( bp_is_group() ) {
2259          $url = rawurlencode( bp_get_group_permalink( groups_get_current_group() ) );
2260  
2261      } elseif ( ! empty( $r['object'] ) && ! empty( $r['item_id'] ) ) {
2262          if ( 'user' === $r['object'] ) {
2263              $url = rawurlencode( bp_core_get_user_domain( $r['item_id'] ) );
2264  
2265          } elseif ( 'group' === $r['object'] ) {
2266              $group = groups_get_group( array( 'group_id' => $r['item_id'] ) );
2267  
2268              if ( ! empty( $group->id ) ) {
2269                  $url = rawurlencode( bp_get_group_permalink( $group ) );
2270              }
2271          }
2272      }
2273  
2274      if ( ! $url ) {
2275          return '';
2276      }
2277  
2278      $customizer_link = add_query_arg( array(
2279          'autofocus[section]' => $r['autofocus'],
2280          'url'                => $url,
2281      ), admin_url( 'customize.php' ) );
2282  
2283      return sprintf( '<a href="%1$s">%2$s</a>', esc_url( $customizer_link ), esc_html( $r['text'] ) );
2284  }
2285  
2286  /** Template tags for signup forms *******************************************/
2287  
2288  /**
2289   * Fire specific hooks into the register template
2290   *
2291   * @since 3.0.0
2292   *
2293   * @param string $when   'before' or 'after'
2294   * @param string $prefix Use it to add terms before the hook name
2295   */
2296  function bp_nouveau_signup_hook( $when = '', $prefix = '' ) {
2297      $hook = array( 'bp' );
2298  
2299      if ( $when ) {
2300          $hook[] = $when;
2301      }
2302  
2303      if ( $prefix ) {
2304          if ( 'page' === $prefix ) {
2305              $hook[] = 'register';
2306          } elseif ( 'steps' === $prefix ) {
2307              $hook[] = 'signup';
2308          }
2309  
2310          $hook[] = $prefix;
2311      }
2312  
2313      if ( 'page' !== $prefix && 'steps' !== $prefix ) {
2314          $hook[] = 'fields';
2315      }
2316  
2317      bp_nouveau_hook( $hook );
2318  }
2319  
2320  /**
2321   * Fire specific hooks into the activate template
2322   *
2323   * @since 3.0.0
2324   *
2325   * @param string $when   'before' or 'after'
2326   * @param string $prefix Use it to add terms before the hook name
2327   */
2328  function bp_nouveau_activation_hook( $when = '', $suffix = '' ) {
2329      $hook = array( 'bp' );
2330  
2331      if ( $when ) {
2332          $hook[] = $when;
2333      }
2334  
2335      $hook[] = 'activate';
2336  
2337      if ( $suffix ) {
2338          $hook[] = $suffix;
2339      }
2340  
2341      if ( 'page' === $suffix ) {
2342          $hook[2] = 'activation';
2343      }
2344  
2345      bp_nouveau_hook( $hook );
2346  }
2347  
2348  /**
2349   * Output the signup form for the requested section
2350   *
2351   * @since 3.0.0
2352   *
2353   * @param string $section Optional. The section of fields to get 'account_details' or 'blog_details'.
2354   *                        Default: 'account_details'.
2355   */
2356  function bp_nouveau_signup_form( $section = 'account_details' ) {
2357      $fields = bp_nouveau_get_signup_fields( $section );
2358      if ( ! $fields ) {
2359          return;
2360      }
2361  
2362      foreach ( $fields as $name => $attributes ) {
2363          if ( 'signup_password' === $name ) {
2364              ?>
2365              <label for="pass1"><?php esc_html_e( 'Choose a Password (required)', 'buddypress' ); ?></label>
2366              <div class="user-pass1-wrap">
2367                  <div class="wp-pwd">
2368                      <div class="password-input-wrapper">
2369                          <input type="password" data-reveal="1" name="signup_password" id="pass1" class="password-entry" size="24" value="" <?php bp_form_field_attributes( 'password', array( 'data-pw' => wp_generate_password( 12 ), 'aria-describedby' => 'pass-strength-result' ) ); ?> />
2370                          <button type="button" class="button wp-hide-pw">
2371                              <span class="dashicons dashicons-hidden" aria-hidden="true"></span>
2372                          </button>
2373                      </div>
2374                      <div id="pass-strength-result" aria-live="polite"><?php esc_html_e( 'Strength indicator', 'buddypress' ); ?></div>
2375                  </div>
2376                  <div class="pw-weak">
2377                      <label>
2378                          <input type="checkbox" name="pw_weak" class="pw-checkbox" />
2379                          <?php esc_html_e( 'Confirm use of weak password', 'buddypress' ); ?>
2380                      </label>
2381                  </div>
2382              </div>
2383              <?php
2384          } elseif ( 'signup_password_confirm' === $name ) {
2385              ?>
2386              <p class="user-pass2-wrap">
2387                  <label for="pass2"><?php esc_html_e( 'Confirm new password', 'buddypress' ); ?></label><br />
2388                  <input type="password" name="signup_password_confirm" id="pass2" class="password-entry-confirm" size="24" value="" <?php bp_form_field_attributes( 'password' ); ?> />
2389              </p>
2390  
2391              <p class="description indicator-hint"><?php echo wp_get_password_hint(); ?></p>
2392              <?php
2393          } else {
2394              list( $label, $required, $value, $attribute_type, $type, $class ) = array_values( $attributes );
2395  
2396              // Text fields are using strings, radios are using their inputs
2397              $label_output = '<label for="%1$s">%2$s</label>';
2398              $id           = $name;
2399              $classes      = '';
2400  
2401              if ( $required ) {
2402                  /* translators: Do not translate placeholders. 2 = form field name, 3 = "(required)". */
2403                  $label_output = __( '<label for="%1$s">%2$s %3$s</label>', 'buddypress' );
2404              }
2405  
2406              // Output the label for regular fields
2407              if ( 'radio' !== $type ) {
2408                  if ( $required ) {
2409                      printf( $label_output, esc_attr( $name ), esc_html( $label ), __( '(required)', 'buddypress' ) );
2410                  } else {
2411                      printf( $label_output, esc_attr( $name ), esc_html( $label ) );
2412                  }
2413  
2414                  if ( ! empty( $value ) && is_callable( $value ) ) {
2415                      $value = call_user_func( $value );
2416                  }
2417  
2418              // Handle the specific case of Site's privacy differently
2419              } elseif ( 'signup_blog_privacy_private' !== $name ) {
2420                  ?>
2421                      <span class="label">
2422                          <?php esc_html_e( 'I would like my site to appear in search engines, and in public listings around this network.', 'buddypress' ); ?>
2423                      </span>
2424                  <?php
2425              }
2426  
2427              // Set the additional attributes
2428              if ( $attribute_type ) {
2429                  $existing_attributes = array();
2430  
2431                  if ( ! empty( $required ) ) {
2432                      $existing_attributes = array( 'aria-required' => 'true' );
2433  
2434                      /**
2435                       * The blog section is hidden, so let's avoid a browser warning
2436                       * and deal with the Blog section in Javascript.
2437                       */
2438                      if ( $section !== 'blog_details' ) {
2439                          $existing_attributes['required'] = 'required';
2440                      }
2441                  }
2442  
2443                  $attribute_type = ' ' . bp_get_form_field_attributes( $attribute_type, $existing_attributes );
2444              }
2445  
2446              // Specific case for Site's privacy
2447              if ( 'signup_blog_privacy_public' === $name || 'signup_blog_privacy_private' === $name ) {
2448                  $name      = 'signup_blog_privacy';
2449                  $submitted = bp_get_signup_blog_privacy_value();
2450  
2451                  if ( ! $submitted ) {
2452                      $submitted = 'public';
2453                  }
2454  
2455                  $attribute_type = ' ' . checked( $value, $submitted, false );
2456              }
2457  
2458              // Do not run function to display errors for the private radio.
2459              if ( 'private' !== $value ) {
2460  
2461                  /**
2462                   * Fetch & display any BP member registration field errors.
2463                   *
2464                   * Passes BP signup errors to Nouveau's template function to
2465                   * render suitable markup for error string.
2466                   */
2467                  if ( isset( buddypress()->signup->errors[ $name ] ) ) {
2468                      nouveau_error_template( buddypress()->signup->errors[ $name ] );
2469                      $invalid = 'invalid';
2470                  }
2471              }
2472  
2473              if ( isset( $invalid ) && isset( buddypress()->signup->errors[ $name ] ) ) {
2474                  if ( ! empty( $class ) ) {
2475                      $class = $class . ' ' . $invalid;
2476                  } else {
2477                      $class = $invalid;
2478                  }
2479              }
2480  
2481              if ( $class ) {
2482                  $class = sprintf(
2483                      ' class="%s"',
2484                      esc_attr( join( ' ', array_map( 'sanitize_html_class', explode( ' ', $class ) ) ) )
2485                  );
2486              }
2487  
2488              // Set the input.
2489              $field_output = sprintf(
2490                  '<input type="%1$s" name="%2$s" id="%3$s" %4$s value="%5$s" %6$s />',
2491                  esc_attr( $type ),
2492                  esc_attr( $name ),
2493                  esc_attr( $id ),
2494                  $class,  // Constructed safely above.
2495                  esc_attr( $value ),
2496                  $attribute_type // Constructed safely above.
2497              );
2498  
2499              // Not a radio, let's output the field
2500              if ( 'radio' !== $type ) {
2501                  if ( 'signup_blog_url' !== $name ) {
2502                      print( $field_output );  // Constructed safely above.
2503  
2504                  // If it's the signup blog url, it's specific to Multisite config.
2505                  } elseif ( is_subdomain_install() ) {
2506                      // Constructed safely above.
2507                      printf(
2508                          '%1$s %2$s . %3$s',
2509                          is_ssl() ? 'https://' : 'http://',
2510                          $field_output,
2511                          bp_signup_get_subdomain_base()
2512                      );
2513  
2514                  // Subfolders!
2515                  } else {
2516                      printf(
2517                          '%1$s %2$s',
2518                          home_url( '/' ),
2519                          $field_output  // Constructed safely above.
2520                      );
2521                  }
2522  
2523              // It's a radio, let's output the field inside the label
2524              } else {
2525                  // $label_output and $field_output are constructed safely above.
2526                  printf( $label_output, esc_attr( $name ), $field_output . ' ' . esc_html( $label ) );
2527              }
2528          }
2529      }
2530  
2531      /**
2532       * Fires and displays any extra member registration details fields.
2533       *
2534       * This is a variable hook that depends on the current section.
2535       *
2536       * @since 1.9.0
2537       */
2538      do_action( "bp_{$section}_fields" );
2539  }
2540  
2541  /**
2542   * Outputs the Privacy Policy acceptance area on the registration page.
2543   *
2544   * @since 4.0.0
2545   */
2546  function bp_nouveau_signup_privacy_policy_acceptance_section() {
2547      $error = null;
2548      if ( isset( buddypress()->signup->errors['signup_privacy_policy'] ) ) {
2549          $error = buddypress()->signup->errors['signup_privacy_policy'];
2550      }
2551  
2552      ?>
2553  
2554      <div class="privacy-policy-accept">
2555          <?php if ( $error ) : ?>
2556              <?php nouveau_error_template( $error ); ?>
2557          <?php endif; ?>
2558  
2559          <label for="signup-privacy-policy-accept">
2560              <input type="hidden" name="signup-privacy-policy-check" value="1" />
2561  
2562              <?php /* translators: link to Privacy Policy */ ?>
2563              <input type="checkbox" name="signup-privacy-policy-accept" id="signup-privacy-policy-accept" required /> <?php printf( esc_html__( 'I have read and agree to this site\'s %s.', 'buddypress' ), sprintf( '<a href="%s">%s</a>', esc_url( get_privacy_policy_url() ), esc_html__( 'Privacy Policy', 'buddypress' ) ) ); ?>
2564          </label>
2565      </div>
2566  
2567      <?php
2568  }
2569  
2570  /**
2571   * Output a submit button and the nonce for the requested action.
2572   *
2573   * @since 3.0.0
2574   *
2575   * @param string $action The action to get the submit button for. Required.
2576   */
2577  function bp_nouveau_submit_button( $action ) {
2578      $submit_data = bp_nouveau_get_submit_button( $action );
2579      if ( empty( $submit_data['attributes'] ) || empty( $submit_data['nonce'] ) ) {
2580          return;
2581      }
2582  
2583      if ( ! empty( $submit_data['before'] ) ) {
2584  
2585          /**
2586           * Fires before display of the submit button.
2587           *
2588           * This is a dynamic filter that is dependent on the "before" value provided by bp_nouveau_get_submit_button().
2589           *
2590           * @since 3.0.0
2591           */
2592          do_action( $submit_data['before'] );
2593      }
2594  
2595      $submit_input = sprintf( '<input type="submit" %s/>',
2596          bp_get_form_field_attributes( 'submit', $submit_data['attributes'] )  // Safe.
2597      );
2598  
2599      // Output the submit button.
2600      if ( isset( $submit_data['wrapper'] ) && false === $submit_data['wrapper'] ) {
2601          echo $submit_input;
2602  
2603      // Output the submit button into a wrapper.
2604      } else {
2605          printf( '<div class="submit">%s</div>', $submit_input );
2606      }
2607  
2608      if ( empty( $submit_data['nonce_key'] ) ) {
2609          wp_nonce_field( $submit_data['nonce'] );
2610      } else {
2611          wp_nonce_field( $submit_data['nonce'], $submit_data['nonce_key'] );
2612      }
2613  
2614      if ( ! empty( $submit_data['after'] ) ) {
2615  
2616          /**
2617           * Fires before display of the submit button.
2618           *
2619           * This is a dynamic filter that is dependent on the "after" value provided by bp_nouveau_get_submit_button().
2620           *
2621           * @since 3.0.0
2622           */
2623          do_action( $submit_data['after'] );
2624      }
2625  }
2626  
2627  /**
2628   * Display supplemental error or feedback messages.
2629   *
2630   * This template handles in page error or feedback messages e.g signup fields
2631   * 'Username exists' type registration field error notices.
2632   *
2633   * @param string $message required: the message to display.
2634   * @param string $type optional: the type of error message e.g 'error'.
2635   *
2636   * @since 3.0.0
2637   */
2638  function nouveau_error_template( $message = '', $type = '' ) {
2639      if ( ! $message ) {
2640          return;
2641      }
2642  
2643      $type = ( $type ) ? $type : 'error';
2644      ?>
2645  
2646      <div class="<?php echo esc_attr( 'bp-messages bp-feedback ' . $type ); ?>">
2647          <span class="bp-icon" aria-hidden="true"></span>
2648          <p><?php echo esc_html( $message ); ?></p>
2649      </div>
2650  
2651      <?php
2652  }


Generated: Thu Jul 9 01:01:31 2020 Cross-referenced by PHPXref 0.7.1