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


Generated: Mon Mar 30 01:01:27 2020 Cross-referenced by PHPXref 0.7.1