[ 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          $class = array_map( 'sanitize_html_class', $classes );
1493  
1494          /**
1495           * Filters the final results for BuddyPress Nouveau container classes.
1496           *
1497           * This filter will return a single string of concatenated classes to be used.
1498           *
1499           * @since 3.0.0
1500           *
1501           * @param string $value   Concatenated classes.
1502           * @param array  $classes Array of classes that were concatenated.
1503           */
1504          return apply_filters( 'bp_nouveau_get_container_classes', join( ' ', $class ), $classes );
1505      }
1506  
1507  /**
1508   * Output single item nav container classes
1509   *
1510   * @since 3.0.0
1511   *
1512   * @return string CSS classes
1513   */
1514  function bp_nouveau_single_item_nav_classes() {
1515      echo esc_attr( bp_nouveau_get_single_item_nav_classes() );
1516  }
1517  
1518      /**
1519       * Returns the single item nav container classes
1520       *
1521       * @since 3.0.0
1522       *
1523       * @return string CSS classes
1524       */
1525  	function bp_nouveau_get_single_item_nav_classes() {
1526          $classes    = array( 'main-navs', 'no-ajax', 'bp-navs', 'single-screen-navs' );
1527          $component  = bp_current_component();
1528          $bp_nouveau = bp_nouveau();
1529  
1530          // @todo wasn't able to get $customizer_option to pass a string to get_settings
1531          // this is a temp workaround but differs from earlier dir approach- bad!
1532          if ( bp_is_group() ) {
1533              $nav_tabs = (int) bp_nouveau_get_temporary_setting( 'group_nav_tabs', bp_nouveau_get_appearance_settings( 'group_nav_tabs' ) );
1534  
1535          } elseif ( bp_is_user() ) {
1536              $nav_tabs = (int) bp_nouveau_get_temporary_setting( 'user_nav_tabs', bp_nouveau_get_appearance_settings( 'user_nav_tabs' ) );
1537          }
1538  
1539          if ( bp_is_group() && 1 === $nav_tabs) {
1540              $classes[] = 'group-nav-tabs';
1541              $classes[] = 'tabbed-links';
1542          } elseif ( bp_is_user() && 1 === $nav_tabs ) {
1543              $classes[] = 'user-nav-tabs';
1544              $classes[] = 'tabbed-links';
1545          }
1546  
1547          if ( bp_is_user() ) {
1548              $component = 'members';
1549              $menu_type = 'users-nav';
1550          } else {
1551              $menu_type = 'groups-nav';
1552          }
1553  
1554          $customizer_option = ( bp_is_user() )? 'user_nav_display' : 'group_nav_display';
1555  
1556          $layout_prefs = (int) bp_nouveau_get_temporary_setting( $customizer_option, bp_nouveau_get_appearance_settings( $customizer_option ) );
1557  
1558          // Set the global for a later use - this is moved from the `bp_nouveau_get_container_classes()
1559          // But was set as a check for this array class addition.
1560          $bp_nouveau->{$component}->single_primary_nav_layout = $layout_prefs;
1561  
1562          if ( 1 === $layout_prefs ) {
1563              $classes[] = 'vertical';
1564          } else {
1565              $classes[] = 'horizontal';
1566          }
1567  
1568          $classes[] = $menu_type;
1569          $class = array_map( 'sanitize_html_class', $classes );
1570  
1571          /**
1572           * Filters the final results for BuddyPress Nouveau single item nav classes.
1573           *
1574           * This filter will return a single string of concatenated classes to be used.
1575           *
1576           * @since 3.0.0
1577           *
1578           * @param string $value   Concatenated classes.
1579           * @param array  $classes Array of classes that were concatenated.
1580           */
1581          return apply_filters( 'bp_nouveau_get_single_item_nav_classes', join( ' ', $class ), $classes );
1582      }
1583  
1584  /**
1585   * Output single item subnav container classes.
1586   *
1587   * @since 3.0.0
1588   *
1589   * @return string CSS classes
1590   */
1591  function bp_nouveau_single_item_subnav_classes() {
1592      echo esc_attr( bp_nouveau_get_single_item_subnav_classes() );
1593  }
1594  
1595      /**
1596       * Returns the single item subnav container classes.
1597       *
1598       * @since 3.0.0
1599       *
1600       * @return string CSS classes
1601       */
1602  	function bp_nouveau_get_single_item_subnav_classes() {
1603          $classes = array( 'bp-navs', 'bp-subnavs', 'no-ajax' );
1604  
1605          // Set user or group class string
1606          if ( bp_is_user() ) {
1607              $classes[] = 'user-subnav';
1608          }
1609  
1610          if ( bp_is_group() ) {
1611              $classes[] = 'group-subnav';
1612          }
1613  
1614          if ( ( bp_is_group() && 'send-invites' === bp_current_action() ) || ( bp_is_group_create() && 'group-invites' === bp_get_groups_current_create_step() ) ) {
1615              $classes[] = 'bp-invites-nav';
1616          }
1617  
1618          $customizer_option = ( bp_is_user() )? 'user_subnav_tabs' : 'group_subnav_tabs';
1619          $nav_tabs = (int) bp_nouveau_get_temporary_setting( $customizer_option, bp_nouveau_get_appearance_settings( $customizer_option ) );
1620  
1621          if ( bp_is_user() && 1 === $nav_tabs ) {
1622              $classes[] = 'tabbed-links';
1623          }
1624  
1625          if ( bp_is_group() && 1 === $nav_tabs ) {
1626              $classes[] = 'tabbed-links';
1627          }
1628  
1629          $class = array_map( 'sanitize_html_class', $classes );
1630  
1631          /**
1632           * Filters the final results for BuddyPress Nouveau single item subnav classes.
1633           *
1634           * This filter will return a single string of concatenated classes to be used.
1635           *
1636           * @since 3.0.0
1637           *
1638           * @param string $value   Concatenated classes.
1639           * @param array  $classes Array of classes that were concatenated.
1640           */
1641          return apply_filters( 'bp_nouveau_get_single_item_subnav_classes', join( ' ', $class ), $classes );
1642      }
1643  
1644  /**
1645   * Output the groups create steps classes.
1646   *
1647   * @since 3.0.0
1648   *
1649   * @return string CSS classes
1650   */
1651  function bp_nouveau_groups_create_steps_classes() {
1652      echo esc_attr( bp_nouveau_get_group_create_steps_classes() );
1653  }
1654  
1655      /**
1656       * Returns the groups create steps customizer option choice class.
1657       *
1658       * @since 3.0.0
1659       *
1660       * @return string CSS classes
1661       */
1662  	function bp_nouveau_get_group_create_steps_classes() {
1663          $classes  = array( 'bp-navs', 'group-create-links', 'no-ajax' );
1664          $nav_tabs = (int) bp_nouveau_get_temporary_setting( 'groups_create_tabs', bp_nouveau_get_appearance_settings( 'groups_create_tabs' ) );
1665  
1666          if ( 1 === $nav_tabs ) {
1667              $classes[] = 'tabbed-links';
1668          }
1669  
1670          $class = array_map( 'sanitize_html_class', $classes );
1671  
1672          /**
1673           * Filters the final results for BuddyPress Nouveau group creation step classes.
1674           *
1675           * This filter will return a single string of concatenated classes to be used.
1676           *
1677           * @since 3.0.0
1678           *
1679           * @param string $value   Concatenated classes.
1680           * @param array  $classes Array of classes that were concatenated.
1681           */
1682          return apply_filters( 'bp_nouveau_get_group_create_steps_classes', join( ' ', $class ), $classes );
1683      }
1684  
1685  
1686  /** Template tags for the object search **************************************/
1687  
1688  /**
1689   * Get the search primary object
1690   *
1691   * @since 3.0.0
1692   *
1693   * @param string $object Optional. The primary object.
1694   *
1695   * @return string The primary object.
1696   */
1697  function bp_nouveau_get_search_primary_object( $object = '' ) {
1698      if ( bp_is_user() ) {
1699          $object = 'member';
1700      } elseif ( bp_is_group() ) {
1701          $object = 'group';
1702      } elseif ( bp_is_directory() ) {
1703          $object = 'dir';
1704      } else {
1705  
1706          /**
1707           * Filters the search primary object if no other was found.
1708           *
1709           * @since 3.0.0
1710           *
1711           * @param string $object Search object.
1712           */
1713          $object = apply_filters( 'bp_nouveau_get_search_primary_object', $object );
1714      }
1715  
1716      return $object;
1717  }
1718  
1719  /**
1720   * Get The list of search objects (primary + secondary).
1721   *
1722   * @since 3.0.0
1723   *
1724   * @param array $objects Optional. The list of objects.
1725   *
1726   * @return array The list of objects.
1727   */
1728  function bp_nouveau_get_search_objects( $objects = array() ) {
1729      $primary = bp_nouveau_get_search_primary_object();
1730      if ( ! $primary ) {
1731          return $objects;
1732      }
1733  
1734      $objects = array(
1735          'primary' => $primary,
1736      );
1737  
1738      if ( 'member' === $primary || 'dir' === $primary ) {
1739          $objects['secondary'] = bp_current_component();
1740      } elseif ( 'group' === $primary ) {
1741          $objects['secondary'] = bp_current_action();
1742      } else {
1743  
1744          /**
1745           * Filters the search objects if no others were found.
1746           *
1747           * @since 3.0.0
1748           *
1749           * @param array $objects Search objects.
1750           */
1751          $objects = apply_filters( 'bp_nouveau_get_search_objects', $objects );
1752      }
1753  
1754      return $objects;
1755  }
1756  
1757  /**
1758   * Output the search form container classes.
1759   *
1760   * @since 3.0.0
1761   */
1762  function bp_nouveau_search_container_class() {
1763      $objects = bp_nouveau_get_search_objects();
1764      $class   = join( '-search ', array_map( 'sanitize_html_class', $objects ) ) . '-search';
1765  
1766      echo esc_attr( $class );
1767  }
1768  
1769  /**
1770   * Output the search form data-bp attribute.
1771   *
1772   * @since 3.0.0
1773   *
1774   * @param  string $attr The data-bp attribute.
1775   * @return string The data-bp attribute.
1776   */
1777  function bp_nouveau_search_object_data_attr( $attr = '' ) {
1778      $objects = bp_nouveau_get_search_objects();
1779  
1780      if ( ! isset( $objects['secondary'] ) ) {
1781          return $attr;
1782      }
1783  
1784      if ( bp_is_active( 'groups' ) && bp_is_group_members() ) {
1785          $attr = join( '_', $objects );
1786      } else {
1787          $attr = $objects['secondary'];
1788      }
1789  
1790      echo esc_attr( $attr );
1791  }
1792  
1793  /**
1794   * Output a selector ID.
1795   *
1796   * @since 3.0.0
1797   *
1798   * @param string $suffix Optional. A string to append at the end of the ID.
1799   * @param string $sep    Optional. The separator to use between each token.
1800   *
1801   * @return string The selector ID.
1802   */
1803  function bp_nouveau_search_selector_id( $suffix = '', $sep = '-' ) {
1804      $id = join( $sep, array_merge( bp_nouveau_get_search_objects(), (array) $suffix ) );
1805      echo esc_attr( $id );
1806  }
1807  
1808  /**
1809   * Output the name attribute of a selector.
1810   *
1811   * @since 3.0.0
1812   *
1813   * @param  string $suffix Optional. A string to append at the end of the name.
1814   * @param  string $sep    Optional. The separator to use between each token.
1815   *
1816   * @return string The name attribute of a selector.
1817   */
1818  function bp_nouveau_search_selector_name( $suffix = '', $sep = '_' ) {
1819      $objects = bp_nouveau_get_search_objects();
1820  
1821      if ( isset( $objects['secondary'] ) && ! $suffix ) {
1822          $name = bp_core_get_component_search_query_arg( $objects['secondary'] );
1823      } else {
1824          $name = join( $sep, array_merge( $objects, (array) $suffix ) );
1825      }
1826  
1827      echo esc_attr( $name );
1828  }
1829  
1830  /**
1831   * Output the default search text for the search object
1832   *
1833   * @since 3.0.0
1834   *
1835   * @param  string $text    Optional. The default search text for the search object.
1836   * @param  string $is_attr Optional. True if it's to be output inside an attribute. False Otherwise.
1837   *
1838   * @return string The default search text.
1839   *
1840   * @todo 28/09/17 added  'empty( $text )' check to $object query as it wasn't returning output as expected & not returning user set params
1841   * This may require further examination - hnla
1842   */
1843  function bp_nouveau_search_default_text( $text = '', $is_attr = true ) {
1844      $objects = bp_nouveau_get_search_objects();
1845  
1846      if ( ! empty( $objects['secondary'] ) && empty( $text ) ) {
1847          $text = bp_get_search_default_text( $objects['secondary'] );
1848      }
1849  
1850      if ( $is_attr ) {
1851          echo esc_attr( $text );
1852      } else {
1853          echo esc_html( $text );
1854      }
1855  }
1856  
1857  /**
1858   * Get the search form template part and fire some do_actions if needed.
1859   *
1860   * @since 3.0.0
1861   */
1862  function bp_nouveau_search_form() {
1863      $search_form_html = bp_buffer_template_part( 'common/search/search-form', null, false );
1864  
1865      $objects = bp_nouveau_get_search_objects();
1866      if ( empty( $objects['primary'] ) || empty( $objects['secondary'] ) ) {
1867          echo $search_form_html;
1868          return;
1869      }
1870  
1871      if ( 'dir' === $objects['primary'] ) {
1872          /**
1873           * Filter here to edit the HTML output of the directory search form.
1874           *
1875           * NB: This will take in charge the following BP Core Components filters
1876           *     - bp_directory_members_search_form
1877           *     - bp_directory_blogs_search_form
1878           *     - bp_directory_groups_search_form
1879           *
1880           * @since 1.9.0
1881           *
1882           * @param string $search_form_html The HTML output for the directory search form.
1883           */
1884          echo apply_filters( "bp_directory_{$objects['secondary']}_search_form", $search_form_html );
1885  
1886          if ( 'activity' === $objects['secondary'] ) {
1887              /**
1888               * Fires before the display of the activity syndication options.
1889               *
1890               * @since 1.2.0
1891               */
1892              do_action( 'bp_activity_syndication_options' );
1893  
1894          } elseif ( 'blogs' === $objects['secondary'] ) {
1895              /**
1896               * Fires inside the unordered list displaying blog sub-types.
1897               *
1898               * @since 1.5.0
1899               */
1900              do_action( 'bp_blogs_directory_blog_sub_types' );
1901  
1902          } elseif ( 'groups' === $objects['secondary'] ) {
1903              /**
1904               * Fires inside the groups directory group types.
1905               *
1906               * @since 1.2.0
1907               */
1908              do_action( 'bp_groups_directory_group_types' );
1909  
1910          } elseif ( 'members' === $objects['secondary'] ) {
1911              /**
1912               * Fires inside the members directory member sub-types.
1913               *
1914               * @since 1.5.0
1915               */
1916              do_action( 'bp_members_directory_member_sub_types' );
1917          }
1918      } elseif ( 'group' === $objects['primary'] ) {
1919          if ( 'members' !== $objects['secondary'] ) {
1920              /**
1921               * Filter here to edit the HTML output of the displayed group search form.
1922               *
1923               * @since 3.2.0
1924               *
1925               * @param string $search_form_html The HTML output for the directory search form.
1926               */
1927              echo apply_filters( "bp_group_{$objects['secondary']}_search_form", $search_form_html );
1928  
1929          } else {
1930              /**
1931               * Filters the Members component search form.
1932               *
1933               * @since 1.9.0
1934               *
1935               * @param string $search_form_html HTML markup for the member search form.
1936               */
1937              echo apply_filters( 'bp_directory_members_search_form', $search_form_html );
1938          }
1939  
1940          if ( 'members' === $objects['secondary'] ) {
1941              /**
1942               * Fires at the end of the group members search unordered list.
1943               *
1944               * Part of bp_groups_members_template_part().
1945               *
1946               * @since 1.5.0
1947               */
1948              do_action( 'bp_members_directory_member_sub_types' );
1949  
1950          } elseif ( 'activity' === $objects['secondary'] ) {
1951              /**
1952               * Fires inside the syndication options list, after the RSS option.
1953               *
1954               * @since 1.2.0
1955               */
1956              do_action( 'bp_group_activity_syndication_options' );
1957          }
1958      }
1959  }
1960  
1961  
1962  // Template tags for the directory & user/group screen filters.
1963  
1964  /**
1965   * Get the current component or action.
1966   *
1967   * If on single group screens we need to switch from component to bp_current_action() to add the correct
1968   * IDs/labels for group/activity & similar screens.
1969   *
1970   * @since 3.0.0
1971   */
1972  function bp_nouveau_current_object() {
1973      /*
1974       * If we're looking at groups single screens we need to factor in current action
1975       * to avoid the component check adding the wrong id for the main dir e.g 'groups' instead of 'activity'.
1976       * We also need to check for group screens to adjust the id's for prefixes.
1977       */
1978      $component = array();
1979  
1980      if ( bp_is_group() ) {
1981          $component['members_select']   = 'groups_members-order-select';
1982          $component['members_order_by'] = 'groups_members-order-by';
1983          $component['object']           = bp_current_action();
1984          $component['data_filter']      = bp_current_action();
1985  
1986          if ( 'activity' !== bp_current_action() ) {
1987              $component['data_filter'] = 'group_' . bp_current_action();
1988          }
1989  
1990      } else {
1991          $data_filter = bp_current_component();
1992          if ( 'friends' === $data_filter && bp_is_user_friend_requests() ) {
1993              $data_filter = 'friend_requests';
1994          }
1995  
1996          $component['members_select']   = 'members-order-select';
1997          $component['members_order_by'] = 'members-order-by';
1998          $component['object']           = bp_current_component();
1999          $component['data_filter']      = $data_filter;
2000      }
2001  
2002      return $component;
2003  }
2004  
2005  /**
2006   * Output data filter container's ID attribute value.
2007   *
2008   * @since 3.0.0
2009   */
2010  function bp_nouveau_filter_container_id() {
2011      echo esc_attr( bp_nouveau_get_filter_container_id() );
2012  }
2013  
2014      /**
2015       * Get data filter container's ID attribute value.
2016       *
2017       * @since 3.0.0
2018       *
2019       * @param string
2020       */
2021  	function bp_nouveau_get_filter_container_id() {
2022          $component = bp_nouveau_current_object();
2023  
2024          $ids = array(
2025              'members'       =>  $component['members_select'],
2026              'friends'       => 'members-friends-select',
2027              'notifications' => 'notifications-filter-select',
2028              'activity'      => 'activity-filter-select',
2029              'groups'        => 'groups-order-select',
2030              'blogs'         => 'blogs-order-select',
2031          );
2032  
2033          if ( isset( $ids[ $component['object'] ] ) ) {
2034  
2035              /**
2036               * Filters the container ID for BuddyPress Nouveau filters.
2037               *
2038               * @since 3.0.0
2039               *
2040               * @param string $value ID based on current component object.
2041               */
2042              return apply_filters( 'bp_nouveau_get_filter_container_id', $ids[ $component['object'] ] );
2043          }
2044  
2045          return '';
2046      }
2047  
2048  /**
2049   * Output data filter's ID attribute value.
2050   *
2051   * @since 3.0.0
2052   */
2053  function bp_nouveau_filter_id() {
2054      echo esc_attr( bp_nouveau_get_filter_id() );
2055  }
2056  
2057      /**
2058       * Get data filter's ID attribute value.
2059       *
2060       * @since 3.0.0
2061       *
2062       * @param string
2063       */
2064  	function bp_nouveau_get_filter_id() {
2065          $component = bp_nouveau_current_object();
2066  
2067          $ids = array(
2068              'members'       => $component['members_order_by'],
2069              'friends'       => 'members-friends',
2070              'notifications' => 'notifications-filter-by',
2071              'activity'      => 'activity-filter-by',
2072              'groups'        => 'groups-order-by',
2073              'blogs'         => 'blogs-order-by',
2074          );
2075  
2076          if ( isset( $ids[ $component['object'] ] ) ) {
2077  
2078              /**
2079               * Filters the filter ID for BuddyPress Nouveau filters.
2080               *
2081               * @since 3.0.0
2082               *
2083               * @param string $value ID based on current component object.
2084               */
2085              return apply_filters( 'bp_nouveau_get_filter_id', $ids[ $component['object'] ] );
2086          }
2087  
2088          return '';
2089      }
2090  
2091  /**
2092   * Output data filter's label.
2093   *
2094   * @since 3.0.0
2095   */
2096  function bp_nouveau_filter_label() {
2097      echo esc_html( bp_nouveau_get_filter_label() );
2098  }
2099  
2100      /**
2101       * Get data filter's label.
2102        *
2103       * @since 3.0.0
2104       *
2105       * @param string
2106       */
2107  	function bp_nouveau_get_filter_label() {
2108          $component = bp_nouveau_current_object();
2109          $label     = __( 'Order By:', 'buddypress' );
2110  
2111          if ( 'activity' === $component['object'] || 'friends' === $component['object'] ) {
2112              $label = __( 'Show:', 'buddypress' );
2113          }
2114  
2115          /**
2116           * Filters the label for BuddyPress Nouveau filters.
2117           *
2118           * @since 3.0.0
2119           *
2120           * @param string $label     Label for BuddyPress Nouveau filter.
2121           * @param array  $component The data filter's data-bp-filter attribute value.
2122           */
2123          return apply_filters( 'bp_nouveau_get_filter_label', $label, $component );
2124      }
2125  
2126  /**
2127   * Output data filter's data-bp-filter attribute value.
2128   *
2129   * @since 3.0.0
2130   */
2131  function bp_nouveau_filter_component() {
2132      $component = bp_nouveau_current_object();
2133      echo esc_attr( $component['data_filter'] );
2134  }
2135  
2136  /**
2137   * Output the <option> of the data filter's <select> element.
2138   *
2139   * @since 3.0.0
2140   */
2141  function bp_nouveau_filter_options() {
2142      echo bp_nouveau_get_filter_options();  // Escaped in inner functions.
2143  }
2144  
2145      /**
2146       * Get the <option> of the data filter's <select> element.
2147       *
2148       * @since 3.0.0
2149       *
2150       * @return string
2151       */
2152  	function bp_nouveau_get_filter_options() {
2153          $output = '';
2154  
2155          if ( 'notifications' === bp_current_component() ) {
2156              $output = bp_nouveau_get_notifications_filters();
2157  
2158          } else {
2159              $filters = bp_nouveau_get_component_filters();
2160  
2161              foreach ( $filters as $key => $value ) {
2162                  $output .= sprintf( '<option value="%1$s">%2$s</option>%3$s',
2163                      esc_attr( $key ),
2164                      esc_html( $value ),
2165                      PHP_EOL
2166                  );
2167              }
2168          }
2169  
2170          return $output;
2171      }
2172  
2173  
2174  /** Template tags for the Customizer ******************************************/
2175  
2176  /**
2177   * Get a link to reach a specific section into the customizer
2178   *
2179   * @since 3.0.0
2180   *
2181   * @param array $args Optional. The argument to customize the Customizer link.
2182   *
2183   * @return string HTML.
2184   */
2185  function bp_nouveau_get_customizer_link( $args = array() ) {
2186      $r = bp_parse_args( $args, array(
2187          'capability' => 'bp_moderate',
2188          'object'     => 'user',
2189          'item_id'    => 0,
2190          'autofocus'  => '',
2191          'text'       => '',
2192      ), 'nouveau_get_customizer_link' );
2193  
2194      if ( empty( $r['capability'] ) || empty( $r['autofocus'] ) || empty( $r['text'] ) ) {
2195          return '';
2196      }
2197  
2198      if ( ! bp_current_user_can( $r['capability'] ) ) {
2199          return '';
2200      }
2201  
2202      $url = '';
2203  
2204      if ( bp_is_user() ) {
2205          $url = rawurlencode( bp_displayed_user_domain() );
2206  
2207      } elseif ( bp_is_group() ) {
2208          $url = rawurlencode( bp_get_group_permalink( groups_get_current_group() ) );
2209  
2210      } elseif ( ! empty( $r['object'] ) && ! empty( $r['item_id'] ) ) {
2211          if ( 'user' === $r['object'] ) {
2212              $url = rawurlencode( bp_core_get_user_domain( $r['item_id'] ) );
2213  
2214          } elseif ( 'group' === $r['object'] ) {
2215              $group = groups_get_group( array( 'group_id' => $r['item_id'] ) );
2216  
2217              if ( ! empty( $group->id ) ) {
2218                  $url = rawurlencode( bp_get_group_permalink( $group ) );
2219              }
2220          }
2221      }
2222  
2223      if ( ! $url ) {
2224          return '';
2225      }
2226  
2227      $customizer_link = add_query_arg( array(
2228          'autofocus[section]' => $r['autofocus'],
2229          'url'                => $url,
2230      ), admin_url( 'customize.php' ) );
2231  
2232      return sprintf( '<a href="%1$s">%2$s</a>', esc_url( $customizer_link ), esc_html( $r['text'] ) );
2233  }
2234  
2235  /** Template tags for signup forms *******************************************/
2236  
2237  /**
2238   * Fire specific hooks into the register template
2239   *
2240   * @since 3.0.0
2241   *
2242   * @param string $when   'before' or 'after'
2243   * @param string $prefix Use it to add terms before the hook name
2244   */
2245  function bp_nouveau_signup_hook( $when = '', $prefix = '' ) {
2246      $hook = array( 'bp' );
2247  
2248      if ( $when ) {
2249          $hook[] = $when;
2250      }
2251  
2252      if ( $prefix ) {
2253          if ( 'page' === $prefix ) {
2254              $hook[] = 'register';
2255          } elseif ( 'steps' === $prefix ) {
2256              $hook[] = 'signup';
2257          }
2258  
2259          $hook[] = $prefix;
2260      }
2261  
2262      if ( 'page' !== $prefix && 'steps' !== $prefix ) {
2263          $hook[] = 'fields';
2264      }
2265  
2266      bp_nouveau_hook( $hook );
2267  }
2268  
2269  /**
2270   * Fire specific hooks into the activate template
2271   *
2272   * @since 3.0.0
2273   *
2274   * @param string $when   'before' or 'after'
2275   * @param string $prefix Use it to add terms before the hook name
2276   */
2277  function bp_nouveau_activation_hook( $when = '', $suffix = '' ) {
2278      $hook = array( 'bp' );
2279  
2280      if ( $when ) {
2281          $hook[] = $when;
2282      }
2283  
2284      $hook[] = 'activate';
2285  
2286      if ( $suffix ) {
2287          $hook[] = $suffix;
2288      }
2289  
2290      if ( 'page' === $suffix ) {
2291          $hook[2] = 'activation';
2292      }
2293  
2294      bp_nouveau_hook( $hook );
2295  }
2296  
2297  /**
2298   * Output the signup form for the requested section
2299   *
2300   * @since 3.0.0
2301   *
2302   * @param string $section Optional. The section of fields to get 'account_details' or 'blog_details'.
2303   *                        Default: 'account_details'.
2304   */
2305  function bp_nouveau_signup_form( $section = 'account_details' ) {
2306      $fields = bp_nouveau_get_signup_fields( $section );
2307      if ( ! $fields ) {
2308          return;
2309      }
2310  
2311      foreach ( $fields as $name => $attributes ) {
2312          if ( 'signup_password' === $name ) {
2313              ?>
2314              <label for="pass1"><?php esc_html_e( 'Choose a Password (required)', 'buddypress' ); ?></label>
2315              <div class="user-pass1-wrap">
2316                  <div class="wp-pwd">
2317                      <div class="password-input-wrapper">
2318                          <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' ) ); ?> />
2319                          <button type="button" class="button wp-hide-pw">
2320                              <span class="dashicons dashicons-hidden" aria-hidden="true"></span>
2321                          </button>
2322                      </div>
2323                      <div id="pass-strength-result" aria-live="polite"><?php esc_html_e( 'Strength indicator', 'buddypress' ); ?></div>
2324                  </div>
2325                  <div class="pw-weak">
2326                      <label>
2327                          <input type="checkbox" name="pw_weak" class="pw-checkbox" />
2328                          <?php esc_html_e( 'Confirm use of weak password', 'buddypress' ); ?>
2329                      </label>
2330                  </div>
2331              </div>
2332              <?php
2333          } elseif ( 'signup_password_confirm' === $name ) {
2334              ?>
2335              <p class="user-pass2-wrap">
2336                  <label for="pass2"><?php esc_html_e( 'Confirm new password', 'buddypress' ); ?></label><br />
2337                  <input type="password" name="signup_password_confirm" id="pass2" class="password-entry-confirm" size="24" value="" <?php bp_form_field_attributes( 'password' ); ?> />
2338              </p>
2339  
2340              <p class="description indicator-hint"><?php echo wp_get_password_hint(); ?></p>
2341              <?php
2342          } else {
2343              list( $label, $required, $value, $attribute_type, $type, $class ) = array_values( $attributes );
2344  
2345              // Text fields are using strings, radios are using their inputs
2346              $label_output = '<label for="%1$s">%2$s</label>';
2347              $id           = $name;
2348              $classes      = '';
2349  
2350              if ( $required ) {
2351                  /* translators: Do not translate placeholders. 2 = form field name, 3 = "(required)". */
2352                  $label_output = __( '<label for="%1$s">%2$s %3$s</label>', 'buddypress' );
2353              }
2354  
2355              // Output the label for regular fields
2356              if ( 'radio' !== $type ) {
2357                  if ( $required ) {
2358                      printf( $label_output, esc_attr( $name ), esc_html( $label ), __( '(required)', 'buddypress' ) );
2359                  } else {
2360                      printf( $label_output, esc_attr( $name ), esc_html( $label ) );
2361                  }
2362  
2363                  if ( ! empty( $value ) && is_callable( $value ) ) {
2364                      $value = call_user_func( $value );
2365                  }
2366  
2367              // Handle the specific case of Site's privacy differently
2368              } elseif ( 'signup_blog_privacy_private' !== $name ) {
2369                  ?>
2370                      <span class="label">
2371                          <?php esc_html_e( 'I would like my site to appear in search engines, and in public listings around this network.', 'buddypress' ); ?>
2372                      </span>
2373                  <?php
2374              }
2375  
2376              // Set the additional attributes
2377              if ( $attribute_type ) {
2378                  $existing_attributes = array();
2379  
2380                  if ( ! empty( $required ) ) {
2381                      $existing_attributes = array( 'aria-required' => 'true' );
2382  
2383                      /**
2384                       * The blog section is hidden, so let's avoid a browser warning
2385                       * and deal with the Blog section in Javascript.
2386                       */
2387                      if ( $section !== 'blog_details' ) {
2388                          $existing_attributes['required'] = 'required';
2389                      }
2390                  }
2391  
2392                  $attribute_type = ' ' . bp_get_form_field_attributes( $attribute_type, $existing_attributes );
2393              }
2394  
2395              // Specific case for Site's privacy
2396              if ( 'signup_blog_privacy_public' === $name || 'signup_blog_privacy_private' === $name ) {
2397                  $name      = 'signup_blog_privacy';
2398                  $submitted = bp_get_signup_blog_privacy_value();
2399  
2400                  if ( ! $submitted ) {
2401                      $submitted = 'public';
2402                  }
2403  
2404                  $attribute_type = ' ' . checked( $value, $submitted, false );
2405              }
2406  
2407              // Do not run function to display errors for the private radio.
2408              if ( 'private' !== $value ) {
2409  
2410                  /**
2411                   * Fetch & display any BP member registration field errors.
2412                   *
2413                   * Passes BP signup errors to Nouveau's template function to
2414                   * render suitable markup for error string.
2415                   */
2416                  if ( isset( buddypress()->signup->errors[ $name ] ) ) {
2417                      nouveau_error_template( buddypress()->signup->errors[ $name ] );
2418                      $invalid = 'invalid';
2419                  }
2420              }
2421  
2422              if ( isset( $invalid ) && isset( buddypress()->signup->errors[ $name ] ) ) {
2423                  if ( ! empty( $class ) ) {
2424                      $class = $class . ' ' . $invalid;
2425                  } else {
2426                      $class = $invalid;
2427                  }
2428              }
2429  
2430              if ( $class ) {
2431                  $class = sprintf(
2432                      ' class="%s"',
2433                      esc_attr( join( ' ', array_map( 'sanitize_html_class', explode( ' ', $class ) ) ) )
2434                  );
2435              }
2436  
2437              // Set the input.
2438              $field_output = sprintf(
2439                  '<input type="%1$s" name="%2$s" id="%3$s" %4$s value="%5$s" %6$s />',
2440                  esc_attr( $type ),
2441                  esc_attr( $name ),
2442                  esc_attr( $id ),
2443                  $class,  // Constructed safely above.
2444                  esc_attr( $value ),
2445                  $attribute_type // Constructed safely above.
2446              );
2447  
2448              // Not a radio, let's output the field
2449              if ( 'radio' !== $type ) {
2450                  if ( 'signup_blog_url' !== $name ) {
2451                      print( $field_output );  // Constructed safely above.
2452  
2453                  // If it's the signup blog url, it's specific to Multisite config.
2454                  } elseif ( is_subdomain_install() ) {
2455                      // Constructed safely above.
2456                      printf(
2457                          '%1$s %2$s . %3$s',
2458                          is_ssl() ? 'https://' : 'http://',
2459                          $field_output,
2460                          bp_signup_get_subdomain_base()
2461                      );
2462  
2463                  // Subfolders!
2464                  } else {
2465                      printf(
2466                          '%1$s %2$s',
2467                          home_url( '/' ),
2468                          $field_output  // Constructed safely above.
2469                      );
2470                  }
2471  
2472              // It's a radio, let's output the field inside the label
2473              } else {
2474                  // $label_output and $field_output are constructed safely above.
2475                  printf( $label_output, esc_attr( $name ), $field_output . ' ' . esc_html( $label ) );
2476              }
2477          }
2478      }
2479  
2480      /**
2481       * Fires and displays any extra member registration details fields.
2482       *
2483       * This is a variable hook that depends on the current section.
2484       *
2485       * @since 1.9.0
2486       */
2487      do_action( "bp_{$section}_fields" );
2488  }
2489  
2490  /**
2491   * Outputs the Privacy Policy acceptance area on the registration page.
2492   *
2493   * @since 4.0.0
2494   */
2495  function bp_nouveau_signup_privacy_policy_acceptance_section() {
2496      $error = null;
2497      if ( isset( buddypress()->signup->errors['signup_privacy_policy'] ) ) {
2498          $error = buddypress()->signup->errors['signup_privacy_policy'];
2499      }
2500  
2501      ?>
2502  
2503      <div class="privacy-policy-accept">
2504          <?php if ( $error ) : ?>
2505              <?php nouveau_error_template( $error ); ?>
2506          <?php endif; ?>
2507  
2508          <label for="signup-privacy-policy-accept">
2509              <input type="hidden" name="signup-privacy-policy-check" value="1" />
2510  
2511              <?php /* translators: link to Privacy Policy */ ?>
2512              <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' ) ) ); ?>
2513          </label>
2514      </div>
2515  
2516      <?php
2517  }
2518  
2519  /**
2520   * Output a submit button and the nonce for the requested action.
2521   *
2522   * @since 3.0.0
2523   *
2524   * @param string $action The action to get the submit button for. Required.
2525   */
2526  function bp_nouveau_submit_button( $action ) {
2527      $submit_data = bp_nouveau_get_submit_button( $action );
2528      if ( empty( $submit_data['attributes'] ) || empty( $submit_data['nonce'] ) ) {
2529          return;
2530      }
2531  
2532      if ( ! empty( $submit_data['before'] ) ) {
2533  
2534          /**
2535           * Fires before display of the submit button.
2536           *
2537           * This is a dynamic filter that is dependent on the "before" value provided by bp_nouveau_get_submit_button().
2538           *
2539           * @since 3.0.0
2540           */
2541          do_action( $submit_data['before'] );
2542      }
2543  
2544      $submit_input = sprintf( '<input type="submit" %s/>',
2545          bp_get_form_field_attributes( 'submit', $submit_data['attributes'] )  // Safe.
2546      );
2547  
2548      // Output the submit button.
2549      if ( isset( $submit_data['wrapper'] ) && false === $submit_data['wrapper'] ) {
2550          echo $submit_input;
2551  
2552      // Output the submit button into a wrapper.
2553      } else {
2554          printf( '<div class="submit">%s</div>', $submit_input );
2555      }
2556  
2557      if ( empty( $submit_data['nonce_key'] ) ) {
2558          wp_nonce_field( $submit_data['nonce'] );
2559      } else {
2560          wp_nonce_field( $submit_data['nonce'], $submit_data['nonce_key'] );
2561      }
2562  
2563      if ( ! empty( $submit_data['after'] ) ) {
2564  
2565          /**
2566           * Fires before display of the submit button.
2567           *
2568           * This is a dynamic filter that is dependent on the "after" value provided by bp_nouveau_get_submit_button().
2569           *
2570           * @since 3.0.0
2571           */
2572          do_action( $submit_data['after'] );
2573      }
2574  }
2575  
2576  /**
2577   * Display supplemental error or feedback messages.
2578   *
2579   * This template handles in page error or feedback messages e.g signup fields
2580   * 'Username exists' type registration field error notices.
2581   *
2582   * @param string $message required: the message to display.
2583   * @param string $type optional: the type of error message e.g 'error'.
2584   *
2585   * @since 3.0.0
2586   */
2587  function nouveau_error_template( $message = '', $type = '' ) {
2588      if ( ! $message ) {
2589          return;
2590      }
2591  
2592      $type = ( $type ) ? $type : 'error';
2593      ?>
2594  
2595      <div class="<?php echo esc_attr( 'bp-messages bp-feedback ' . $type ); ?>">
2596          <span class="bp-icon" aria-hidden="true"></span>
2597          <p><?php echo esc_html( $message ); ?></p>
2598      </div>
2599  
2600      <?php
2601  }


Generated: Fri Oct 18 01:01:36 2019 Cross-referenced by PHPXref 0.7.1