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


Generated: Thu Oct 21 01:00:54 2021 Cross-referenced by PHPXref 0.7.1