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


Generated: Wed Jan 29 01:01:45 2020 Cross-referenced by PHPXref 0.7.1