[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

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

   1  <?php
   2  /**
   3   * Common functions
   4   *
   5   * @since 3.0.0
   6   * @version 10.0.0
   7   */
   8  
   9  // Exit if accessed directly.
  10  defined( 'ABSPATH' ) || exit;
  11  
  12  /**
  13   * This function looks scarier than it actually is. :)
  14   * Each object loop (activity/members/groups/blogs/forums) contains default
  15   * parameters to show specific information based on the page we are currently
  16   * looking at.
  17   *
  18   * The following function will take into account any cookies set in the JS and
  19   * allow us to override the parameters sent. That way we can change the results
  20   * returned without reloading the page.
  21   *
  22   * By using cookies we can also make sure that user settings are retained
  23   * across page loads.
  24   *
  25   * @since 3.0.0
  26   *
  27   * @param string $query_string Query string for the current request.
  28   * @param string $object       Object for cookie.
  29   *
  30   * @return string Query string for the component loops
  31   */
  32  function bp_nouveau_ajax_querystring( $query_string, $object ) {
  33      if ( empty( $object ) ) {
  34          return '';
  35      }
  36  
  37      // Default query
  38      $post_query = array(
  39          'filter'       => '',
  40          'scope'        => 'all',
  41          'page'         => 1,
  42          'search_terms' => '',
  43          'extras'       => '',
  44      );
  45  
  46      if ( ! empty( $_POST ) ) {
  47          $post_query = bp_parse_args(
  48              $_POST,
  49              $post_query,
  50              'nouveau_ajax_querystring'
  51          );
  52  
  53          // Make sure to transport the scope, filter etc.. in HeartBeat Requests
  54          if ( ! empty( $post_query['data']['bp_heartbeat'] ) ) {
  55              $bp_heartbeat = $post_query['data']['bp_heartbeat'];
  56  
  57              // Remove heartbeat specific vars
  58              $post_query = array_diff_key(
  59                  bp_parse_args(
  60                      $bp_heartbeat,
  61                      $post_query,
  62                      'nouveau_ajax_querystring_heartbeat'
  63                  ),
  64                  array(
  65                      'data'      => false,
  66                      'interval'  => false,
  67                      '_nonce'    => false,
  68                      'action'    => false,
  69                      'screen_id' => false,
  70                      'has_focus' => false,
  71                  )
  72              );
  73          }
  74      }
  75  
  76      // Init the query string
  77      $qs = array();
  78  
  79      // Activity stream filtering on action.
  80      if ( ! empty( $post_query['filter'] ) && '-1' !== $post_query['filter'] ) {
  81          if ( 'notifications' === $object ) {
  82              $qs[] = 'component_action=' . $post_query['filter'];
  83          } else {
  84              $qs[] = 'type=' . $post_query['filter'];
  85              $qs[] = 'action=' . $post_query['filter'];
  86          }
  87      }
  88  
  89      // Sort the notifications if needed
  90      if ( ! empty( $post_query['extras'] ) && 'notifications' === $object ) {
  91          $qs[] = 'sort_order=' . $post_query['extras'];
  92      }
  93  
  94      if ( 'personal' === $post_query['scope'] ) {
  95          $user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id();
  96          $qs[]    = 'user_id=' . $user_id;
  97      }
  98  
  99      // Activity stream scope only on activity directory.
 100      if ( 'all' !== $post_query['scope'] && ! bp_displayed_user_id() && ! bp_is_single_item() ) {
 101          $qs[] = 'scope=' . $post_query['scope'];
 102      }
 103  
 104      // If page have been passed via the AJAX post request, use those.
 105      if ( '-1' != $post_query['page'] ) {
 106          $qs[] = 'page=' . absint( $post_query['page'] );
 107      }
 108  
 109      // Excludes activity just posted and avoids duplicate ids.
 110      if ( ! empty( $post_query['exclude_just_posted'] ) ) {
 111          $just_posted = wp_parse_id_list( $post_query['exclude_just_posted'] );
 112          $qs[]        = 'exclude=' . implode( ',', $just_posted );
 113      }
 114  
 115      // To get newest activities.
 116      if ( ! empty( $post_query['offset'] ) ) {
 117          $qs[] = 'offset=' . intval( $post_query['offset'] );
 118      }
 119  
 120      $object_search_text = bp_get_search_default_text( $object );
 121      if ( ! empty( $post_query['search_terms'] ) && $object_search_text != $post_query['search_terms'] && 'false' != $post_query['search_terms'] && 'undefined' != $post_query['search_terms'] ) {
 122          $qs[] = 'search_terms=' . urlencode( $_POST['search_terms'] );
 123      }
 124  
 125      // Specific to messages
 126      if ( 'messages' === $object ) {
 127          if ( ! empty( $post_query['box'] ) ) {
 128              $qs[] = 'box=' . $post_query['box'];
 129          }
 130      }
 131  
 132      // Single activity.
 133      if ( bp_is_single_activity() && 'activity' === $object ) {
 134          $qs = array(
 135              'display_comments=threaded',
 136              'show_hidden=true',
 137              'include=' . bp_current_action(),
 138          );
 139      }
 140  
 141      // Now pass the querystring to override default values.
 142      $query_string = empty( $qs ) ? '' : join( '&', (array) $qs );
 143  
 144      // List the variables for the filter
 145      list( $filter, $scope, $page, $search_terms, $extras ) = array_values( $post_query );
 146  
 147      /**
 148       * Filters the AJAX query string for the component loops.
 149       *
 150       * @since 3.0.0
 151       *
 152       * @param string $query_string The query string we are working with.
 153       * @param string $object       The type of page we are on.
 154       * @param string $filter       The current object filter.
 155       * @param string $scope        The current object scope.
 156       * @param string $page         The current object page.
 157       * @param string $search_terms The current object search terms.
 158       * @param string $extras       The current object extras.
 159       */
 160      return apply_filters( 'bp_nouveau_ajax_querystring', $query_string, $object, $filter, $scope, $page, $search_terms, $extras );
 161  }
 162  
 163  /**
 164   * @since 3.0.0
 165   *
 166   * @return string
 167   */
 168  function bp_nouveau_ajax_button( $output = '', $button = null, $before = '', $after = '', $r = array() ) {
 169      if ( empty( $button->component ) ) {
 170          return $output;
 171      }
 172  
 173      // Custom data attribute.
 174      $r['button_attr']['data-bp-btn-action'] = $button->id;
 175  
 176      $reset_ids = array(
 177          'member_friendship' => true,
 178          'group_membership'  => true,
 179      );
 180  
 181      if ( ! empty( $reset_ids[ $button->id ] ) )  {
 182          $parse_class = array_map( 'sanitize_html_class', explode( ' ', $r['button_attr']['class'] ) );
 183          if ( false === $parse_class ) {
 184              return $output;
 185          }
 186  
 187          $find_id = array_intersect( $parse_class, array(
 188              'pending_friend',
 189              'is_friend',
 190              'not_friends',
 191              'leave-group',
 192              'join-group',
 193              'accept-invite',
 194              'membership-requested',
 195              'request-membership',
 196          ) );
 197  
 198          if ( 1 !== count( $find_id ) ) {
 199              return $output;
 200          }
 201  
 202          $data_attribute = reset( $find_id );
 203          if ( 'pending_friend' === $data_attribute ) {
 204              $data_attribute = str_replace( '_friend', '', $data_attribute );
 205          } elseif ( 'group_membership' === $button->id ) {
 206              $data_attribute = str_replace( '-', '_', $data_attribute );
 207          }
 208  
 209          $r['button_attr']['data-bp-btn-action'] = $data_attribute;
 210      }
 211  
 212      // Re-render the button with our custom data attribute.
 213      $output = new BP_Core_HTML_Element( array(
 214          'element'    => $r['button_element'],
 215          'attr'       => $r['button_attr'],
 216          'inner_html' => ! empty( $r['link_text'] ) ? $r['link_text'] : ''
 217      ) );
 218      $output = $output->contents();
 219  
 220      // Add span bp-screen-reader-text class
 221      return $before . $output . $after;
 222  }
 223  
 224  /**
 225   * Output HTML content into a wrapper.
 226   *
 227   * @since 3.0.0
 228   *
 229   * @param array $args {
 230   *     Optional arguments.
 231   *
 232   *     @type string $container         String HTML container type that should wrap
 233   *                                     the items as a group: 'div', 'ul', or 'p'. Required.
 234   *     @type string $container_id      The group wrapping container element ID
 235   *     @type string $container_classes The group wrapping container elements class
 236   *     @type string $output            The HTML to output. Required.
 237   * }
 238   */
 239  function bp_nouveau_wrapper( $args = array() ) {
 240      /**
 241       * Classes need to be determined & set by component to a certain degree.
 242       *
 243       * Check the component to find a default container_class based on the component ID to add.
 244       * We need to to this because bp_current_component() is using the component slugs which can differ
 245       * from the component ID.
 246       */
 247      $current_component_id = bp_core_get_active_components( array( 'slug' => bp_current_component() ) );
 248      if ( $current_component_id && 1 === count( $current_component_id ) ) {
 249          $current_component_id = reset( $current_component_id );
 250      } else {
 251          $current_component_id = bp_current_component();
 252      }
 253  
 254      $current_component_class = $current_component_id . '-meta';
 255  
 256      if ( bp_is_group_activity() ) {
 257          $generic_class = ' activity-meta ';
 258      } else {
 259          $generic_class = '';
 260      }
 261  
 262      $r = bp_parse_args(
 263          $args,
 264          array(
 265              'container'         => 'div',
 266              'container_id'      => '',
 267              'container_classes' => array( $generic_class, $current_component_class ),
 268              'output'            => '',
 269          ),
 270          'nouveau_wrapper'
 271      );
 272  
 273      $valid_containers = array(
 274          'div'  => true,
 275          'ul'   => true,
 276          'ol'   => true,
 277          'span' => true,
 278          'p'    => true,
 279      );
 280  
 281      // Actually merge some classes defaults and $args
 282      // @todo This is temp, we need certain classes but maybe improve this approach.
 283      $default_classes        = array( 'action' );
 284      $r['container_classes'] = array_merge( $r['container_classes'], $default_classes );
 285  
 286      if ( empty( $r['container'] ) || ! isset( $valid_containers[ $r['container'] ] ) || empty( $r['output'] ) ) {
 287          return;
 288      }
 289  
 290      $container         = $r['container'];
 291      $container_id      = '';
 292      $container_classes = '';
 293      $output            = $r['output'];
 294  
 295      if ( ! empty( $r['container_id'] ) ) {
 296          $container_id = ' id="' . esc_attr( $r['container_id'] ) . '"';
 297      }
 298  
 299      if ( ! empty( $r['container_classes'] ) && is_array( $r['container_classes'] ) ) {
 300          $container_classes = ' class="' . join( ' ', array_map( 'sanitize_html_class', $r['container_classes'] ) ) . '"';
 301      }
 302  
 303      // Print the wrapper and its content.
 304      printf( '<%1$s%2$s%3$s>%4$s</%1$s>', $container, $container_id, $container_classes, $output );
 305  }
 306  
 307  /**
 308   * Register the 2 sidebars for the Group & User default front page
 309   *
 310   * @since 3.0.0
 311   */
 312  function bp_nouveau_register_sidebars() {
 313      $default_fronts      = bp_nouveau_get_appearance_settings();
 314      $default_user_front  = 0;
 315      $default_group_front = 0;
 316      $is_active_groups    = bp_is_active( 'groups' );
 317  
 318      if ( isset( $default_fronts['user_front_page'] ) ) {
 319          $default_user_front = $default_fronts['user_front_page'];
 320      }
 321  
 322      if ( $is_active_groups ) {
 323          if ( isset( $default_fronts['group_front_page'] ) ) {
 324              $default_group_front = $default_fronts['group_front_page'];
 325          }
 326      }
 327  
 328      // Setting the front template happens too early, so we need this!
 329      if ( is_customize_preview() ) {
 330          $default_user_front = bp_nouveau_get_temporary_setting( 'user_front_page', $default_user_front );
 331  
 332          if ( $is_active_groups ) {
 333              $default_group_front = bp_nouveau_get_temporary_setting( 'group_front_page', $default_group_front );
 334          }
 335      }
 336  
 337      $sidebars = array();
 338      if ( $default_user_front ) {
 339          $sidebars[] = array(
 340              'name'          => __( 'BuddyPress Member\'s Home', 'buddypress' ),
 341              'id'            => 'sidebar-buddypress-members',
 342              'description'   => __( 'Add widgets here to appear in the front page of each member of your community.', 'buddypress' ),
 343              'before_widget' => '<div id="%1$s" class="widget %2$s">',
 344              'after_widget'  => '</div>',
 345              'before_title'  => '<h2 class="widget-title">',
 346              'after_title'   => '</h2>',
 347          );
 348      }
 349  
 350      if ( $default_group_front ) {
 351          $sidebars[] = array(
 352              'name'          => __( 'BuddyPress Group\'s Home', 'buddypress' ),
 353              'id'            => 'sidebar-buddypress-groups',
 354              'description'   => __( 'Add widgets here to appear in the front page of each group of your community.', 'buddypress' ),
 355              'before_widget' => '<div id="%1$s" class="widget %2$s">',
 356              'after_widget'  => '</div>',
 357              'before_title'  => '<h2 class="widget-title">',
 358              'after_title'   => '</h2>',
 359          );
 360      }
 361  
 362      if ( empty( $sidebars ) ) {
 363          return;
 364      }
 365  
 366      // Register the sidebars if needed.
 367      foreach ( $sidebars as $sidebar ) {
 368          register_sidebar( $sidebar );
 369      }
 370  }
 371  
 372  /**
 373   * @since 3.0.0
 374   *
 375   * @return bool
 376   */
 377  function bp_nouveau_is_object_nav_in_sidebar() {
 378      return bp_is_widget_block_active( 'bp/primary-nav', 'bp_nouveau_sidebar_object_nav_widget' );
 379  }
 380  
 381  /**
 382   * @since 3.0.0
 383   *
 384   * @return bool
 385   */
 386  function bp_nouveau_current_user_can( $capability = '' ) {
 387      /**
 388       * Filters whether or not the current user can perform an action for BuddyPress Nouveau.
 389       *
 390       * @since 3.0.0
 391       *
 392       * @param bool   $value      Whether or not the user is logged in.
 393       * @param string $capability Current capability being checked.
 394       * @param int    $value      Current logged in user ID.
 395       */
 396      return apply_filters( 'bp_nouveau_current_user_can', is_user_logged_in(), $capability, bp_loggedin_user_id() );
 397  }
 398  
 399  /**
 400   * Parse an html output to a list of component's directory nav item.
 401   *
 402   * @since 3.0.0
 403   *
 404   * @param string $hook      The hook to fire.
 405   * @param string $component The component nav belongs to.
 406   * @param int    $position  The position of the nav item.
 407   *
 408   * @return array A list of component's dir nav items
 409   */
 410  function bp_nouveau_parse_hooked_dir_nav( $hook = '', $component = '', $position = 99 ) {
 411      $extra_nav_items = array();
 412  
 413      if ( empty( $hook ) || empty( $component ) || ! has_action( $hook ) ) {
 414          return $extra_nav_items;
 415      }
 416  
 417      // Get the hook output.
 418      ob_start();
 419  
 420      /**
 421       * Fires at the start of the output for `bp_nouveau_parse_hooked_dir_nav()`.
 422       *
 423       * This hook is variable and depends on the hook parameter passed in.
 424       *
 425       * @since 3.0.0
 426       */
 427      do_action( $hook );
 428      $output = ob_get_clean();
 429  
 430      if ( empty( $output ) ) {
 431          return $extra_nav_items;
 432      }
 433  
 434      preg_match_all( "/<li\sid=\"{$component}\-(.*)\"[^>]*>/siU", $output, $lis );
 435      if ( empty( $lis[1] ) ) {
 436          return $extra_nav_items;
 437      }
 438  
 439      $extra_nav_items = array_fill_keys( $lis[1], array( 'component' => $component, 'position' => $position ) );
 440      preg_match_all( '/<a\s[^>]*>(.*)<\/a>/siU', $output, $as );
 441  
 442      if ( ! empty( $as[0] ) ) {
 443          foreach ( $as[0] as $ka => $a ) {
 444              $extra_nav_items[ $lis[1][ $ka ] ]['slug'] = $lis[1][ $ka ];
 445              $extra_nav_items[ $lis[1][ $ka ] ]['text'] = $as[1][ $ka ];
 446              preg_match_all( '/([\w\-]+)=([^"\'> ]+|([\'"]?)(?:[^\3]|\3+)+?\3)/', $a, $attrs );
 447  
 448              if ( ! empty( $attrs[1] ) ) {
 449                  foreach ( $attrs[1] as $katt => $att ) {
 450                      if ( 'href' === $att ) {
 451                          $extra_nav_items[ $lis[1][ $ka ] ]['link'] = trim( $attrs[2][ $katt ], '"' );
 452                      } else {
 453                          $extra_nav_items[ $lis[1][ $ka ] ][ $att ] = trim( $attrs[2][ $katt ], '"' );
 454                      }
 455                  }
 456              }
 457          }
 458      }
 459  
 460      if ( ! empty( $as[1] ) ) {
 461          foreach ( $as[1] as $ks => $s ) {
 462              preg_match_all( '/<span>(.*)<\/span>/siU', $s, $spans );
 463  
 464              if ( empty( $spans[0] ) ) {
 465                  $extra_nav_items[ $lis[1][ $ks ] ]['count'] = false;
 466              } elseif ( ! empty( $spans[1][0] ) ) {
 467                  $extra_nav_items[ $lis[1][ $ks ] ]['count'] = (int) $spans[1][0];
 468              } else {
 469                  $extra_nav_items[ $lis[1][ $ks ] ]['count'] = '';
 470              }
 471          }
 472      }
 473  
 474      return $extra_nav_items;
 475  }
 476  
 477  /**
 478   * Run specific "select filter" hooks to catch the options and build an array out of them
 479   *
 480   * @since 3.0.0
 481   *
 482   * @param string $hook
 483   * @param array  $filters
 484   *
 485   * @return array
 486   */
 487  function bp_nouveau_parse_hooked_options( $hook = '', $filters = array() ) {
 488      if ( empty( $hook ) ) {
 489          return $filters;
 490      }
 491  
 492      ob_start();
 493  
 494      /**
 495       * Fires at the start of the output for `bp_nouveau_parse_hooked_options()`.
 496       *
 497       * This hook is variable and depends on the hook parameter passed in.
 498       *
 499       * @since 3.0.0
 500       */
 501      do_action( $hook );
 502  
 503      $output = ob_get_clean();
 504  
 505      preg_match_all( '/<option value="(.*?)"\s*>(.*?)<\/option>/', $output, $matches );
 506  
 507      if ( ! empty( $matches[1] ) && ! empty( $matches[2] ) ) {
 508          foreach ( $matches[1] as $ik => $key_action ) {
 509              if ( ! empty( $matches[2][ $ik ] ) && ! isset( $filters[ $key_action ] ) ) {
 510                  $filters[ $key_action ] = $matches[2][ $ik ];
 511              }
 512          }
 513      }
 514  
 515      return $filters;
 516  }
 517  
 518  /**
 519   * Get Dropdawn filters for the current component of the one passed in params
 520   *
 521   * @since 3.0.0
 522   *
 523   * @param string $context   'directory', 'user' or 'group'
 524   * @param string $component The BuddyPress component ID
 525   *
 526   * @return array the dropdown filters
 527   */
 528  function bp_nouveau_get_component_filters( $context = '', $component = '' ) {
 529      $filters = array();
 530  
 531      if ( empty( $context ) ) {
 532          if ( bp_is_user() ) {
 533              $context = 'user';
 534          } elseif ( bp_is_group() ) {
 535              $context = 'group';
 536  
 537          // Defaults to directory
 538          } else {
 539              $context = 'directory';
 540          }
 541      }
 542  
 543      if ( empty( $component ) ) {
 544          if ( 'user' === $context ) {
 545              $component = bp_core_get_active_components( array( 'slug' => bp_current_component() ) );
 546              $component = reset( $component );
 547  
 548              if ( 'friends' === $component ) {
 549                  $context   = 'friends';
 550                  $component = 'members';
 551              }
 552          } elseif ( 'group' === $context && bp_is_group_activity() ) {
 553              $component = 'activity';
 554          } elseif ( 'group' === $context && bp_is_group_members() ) {
 555              $component = 'members';
 556          } else {
 557              $component = bp_current_component();
 558          }
 559      }
 560  
 561      if ( ! bp_is_active( $component ) ) {
 562          return $filters;
 563      }
 564  
 565      if ( 'members' === $component ) {
 566          $filters = bp_nouveau_get_members_filters( $context );
 567      } elseif ( 'activity' === $component ) {
 568          $filters = bp_nouveau_get_activity_filters();
 569  
 570          // Specific case for the activity dropdown
 571          $filters = array_merge( array( '-1' => __( '&mdash; Everything &mdash;', 'buddypress' ) ), $filters );
 572      } elseif ( 'groups' === $component ) {
 573          $filters = bp_nouveau_get_groups_filters( $context );
 574      } elseif ( 'blogs' === $component ) {
 575          $filters = bp_nouveau_get_blogs_filters( $context );
 576      }
 577  
 578      return $filters;
 579  }
 580  
 581  /**
 582   * When previewing make sure to get the temporary setting of the customizer.
 583   * This is necessary when we need to get these very early.
 584   *
 585   * @since 3.0.0
 586   *
 587   * @param string $option the index of the setting to get.
 588   * @param mixed  $retval the value to use as default.
 589   *
 590   * @return mixed The value for the requested option.
 591   */
 592  function bp_nouveau_get_temporary_setting( $option = '', $retval = false ) {
 593      if ( empty( $option ) || ! isset( $_POST['customized'] ) ) {
 594          return $retval;
 595      }
 596  
 597      $temporary_setting = wp_unslash( $_POST['customized'] );
 598      if ( ! is_array( $temporary_setting ) ) {
 599          $temporary_setting = json_decode( $temporary_setting, true );
 600      }
 601  
 602      // This is used to transport the customizer settings into Ajax requests.
 603      if ( 'any' === $option ) {
 604          $retval = array();
 605  
 606          foreach ( $temporary_setting as $key => $setting ) {
 607              if ( 0 !== strpos( $key, 'bp_nouveau_appearance' ) ) {
 608                  continue;
 609              }
 610  
 611              $k            = str_replace( array( '[', ']' ), array( '_', '' ), $key );
 612              $retval[ $k ] = $setting;
 613          }
 614  
 615      // Used when it's an early regular request
 616      } elseif ( isset( $temporary_setting[ 'bp_nouveau_appearance[' . $option . ']' ] ) ) {
 617          $retval = $temporary_setting[ 'bp_nouveau_appearance[' . $option . ']' ];
 618  
 619      // Used when it's an ajax request
 620      } elseif ( isset( $_POST['customized'][ 'bp_nouveau_appearance_' . $option ] ) ) {
 621          $retval = $_POST['customized'][ 'bp_nouveau_appearance_' . $option ];
 622      }
 623  
 624      return $retval;
 625  }
 626  
 627  /**
 628   * Get the BP Nouveau Appearance settings.
 629   *
 630   * @since 3.0.0
 631   *
 632   * @param string $option Leave empty to get all settings, specify a value for a specific one.
 633   * @param mixed          An array of settings, the value of the requested setting.
 634   *
 635   * @return array|false|mixed
 636   */
 637  function bp_nouveau_get_appearance_settings( $option = '' ) {
 638      $default_args = array(
 639          'avatar_style'       => 0,
 640          'global_alignment'   => 'alignwide',
 641          'user_front_page'    => 0,
 642          'user_front_bio'     => 0,
 643          'user_nav_display'   => 0, // O is default (horizontally). 1 is vertically.
 644          'user_nav_tabs'      => 0,
 645          'user_subnav_tabs'   => 0,
 646          'user_nav_order'     => array(),
 647          'members_layout'     => 1,
 648          'members_dir_tabs'   => 0,
 649          'members_dir_layout' => 0,
 650      );
 651  
 652      if ( bp_is_active( 'friends' ) ) {
 653          $default_args['members_friends_layout'] = 1;
 654      }
 655  
 656      if ( bp_is_active( 'activity' ) ) {
 657          $default_args['activity_dir_layout'] = 0;
 658          $default_args['activity_dir_tabs']   = 0; // default = no tabs
 659      }
 660  
 661      if ( bp_is_active( 'groups' ) ) {
 662          $default_args = array_merge( $default_args, array(
 663              'group_front_page'        => 0,
 664              'group_front_boxes'       => 0,
 665              'group_front_description' => 0,
 666              'group_nav_display'       => 0,       // O is default (horizontally). 1 is vertically.
 667              'group_nav_order'         => array(),
 668              'group_nav_tabs'          => 0,
 669              'group_subnav_tabs'       => 0,
 670              'groups_create_tabs'      => 1,
 671              'groups_layout'           => 1,
 672              'members_group_layout'    => 1,
 673              'groups_dir_layout'       => 0,
 674              'groups_dir_tabs'         => 0,
 675          ) );
 676      }
 677  
 678      if ( is_multisite() && bp_is_active( 'blogs' ) ) {
 679          $default_args = array_merge( $default_args, array(
 680              'sites_dir_layout' => 0,
 681              'sites_dir_tabs'   => 0,
 682          ) );
 683      }
 684  
 685      $settings = bp_parse_args(
 686          bp_get_option( 'bp_nouveau_appearance', array() ),
 687          $default_args,
 688          'nouveau_appearance_settings'
 689      );
 690  
 691      if ( ! empty( $option ) ) {
 692          if ( isset( $settings[ $option ] ) ) {
 693              return $settings[ $option ];
 694          } else {
 695              return false;
 696          }
 697      }
 698  
 699      return $settings;
 700  }
 701  
 702  /**
 703   * Returns the choices for the Layout option of the customizer
 704   * or the list of corresponding css classes.
 705   *
 706   * @since 3.0.0
 707   *
 708   * @param string $type 'option' to get the labels, 'classes' to get the classes
 709   *
 710   * @return array The list of labels or classes preserving keys.
 711   */
 712  function bp_nouveau_customizer_grid_choices( $type = 'option' ) {
 713      $columns = array(
 714          array( 'key' => '1', 'label' => __( 'One column', 'buddypress'    ), 'class' => ''      ),
 715          array( 'key' => '2', 'label' => __( 'Two columns', 'buddypress'   ), 'class' => 'two'   ),
 716          array( 'key' => '3', 'label' => __( 'Three columns', 'buddypress' ), 'class' => 'three' ),
 717          array( 'key' => '4', 'label' => __( 'Four columns', 'buddypress'  ), 'class' => 'four'  ),
 718      );
 719  
 720      if ( 'option' === $type ) {
 721          return wp_list_pluck( $columns, 'label', 'key' );
 722      }
 723  
 724      return wp_list_pluck( $columns, 'class', 'key' );
 725  }
 726  
 727  /**
 728   * Sanitize a list of slugs to save it as an array
 729   *
 730   * @since 3.0.0
 731   *
 732   * @param  string $option A comma separated list of nav items slugs.
 733   *
 734   * @return array An array of nav items slugs.
 735   */
 736  function bp_nouveau_sanitize_nav_order( $option = '' ) {
 737      $option = explode( ',', $option );
 738      return array_map( 'sanitize_key', $option );
 739  }
 740  
 741  /**
 742   * BP Nouveau's callback for the cover image feature.
 743   *
 744   * @since 3.0.0
 745   *
 746   * @param array $params Optional. The current component's feature parameters.
 747   *
 748   * @return string
 749   */
 750  function bp_nouveau_theme_cover_image( $params = array() ) {
 751      if ( empty( $params ) ) {
 752          return '';
 753      }
 754  
 755      // Avatar height - padding - 1/2 avatar height.
 756      $avatar_offset = $params['height'] - 5 - round( (int) bp_core_avatar_full_height() / 2 );
 757  
 758      // Header content offset + spacing.
 759      $top_offset  = bp_core_avatar_full_height() - 10;
 760      $left_offset = bp_core_avatar_full_width() + 20;
 761  
 762      $cover_image = isset( $params['cover_image'] ) ? 'background-image: url( ' . $params['cover_image'] . ' );' : '';
 763      $hide_avatar_style = '';
 764  
 765      // Adjust the cover image header, in case avatars are completely disabled.
 766      if ( ! buddypress()->avatar->show_avatars ) {
 767          $hide_avatar_style = '
 768              #buddypress #item-header-cover-image #item-header-avatar {
 769                  display:  none;
 770              }
 771          ';
 772  
 773          if ( bp_is_user() ) {
 774              $hide_avatar_style = '
 775                  #buddypress #item-header-cover-image #item-header-avatar a {
 776                      display: block;
 777                      height: ' . $top_offset . 'px;
 778                      margin: 0 15px 19px 0;
 779                  }
 780  
 781                  #buddypress div#item-header #item-header-cover-image #item-header-content {
 782                      margin-left:auto;
 783                  }
 784              ';
 785          }
 786      }
 787  
 788      return '
 789          /* Cover image */
 790          #buddypress #item-header-cover-image {
 791              min-height: ' . $params['height'] . 'px;
 792              margin-bottom: 1em;
 793          }
 794  
 795          #buddypress #item-header-cover-image:after {
 796              clear: both;
 797              content: "";
 798              display: table;
 799          }
 800  
 801          #buddypress #header-cover-image {
 802              height: ' . $params['height'] . 'px;
 803              ' . $cover_image . '
 804          }
 805  
 806          #buddypress #create-group-form #header-cover-image {
 807              position: relative;
 808              margin: 1em 0;
 809          }
 810  
 811          .bp-user #buddypress #item-header {
 812              padding-top: 0;
 813          }
 814  
 815          #buddypress #item-header-cover-image #item-header-avatar {
 816              margin-top: ' . $avatar_offset . 'px;
 817              float: left;
 818              overflow: visible;
 819              width:auto;
 820          }
 821  
 822          #buddypress div#item-header #item-header-cover-image #item-header-content {
 823              clear: both;
 824              float: left;
 825              margin-left: ' . $left_offset . 'px;
 826              margin-top: -' . $top_offset . 'px;
 827              width:auto;
 828          }
 829  
 830          body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-header-content,
 831          body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-actions {
 832              margin-top: ' . $params['height'] . 'px;
 833              margin-left: 0;
 834              clear: none;
 835              max-width: 50%;
 836          }
 837  
 838          body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-actions {
 839              padding-top: 20px;
 840              max-width: 20%;
 841          }
 842  
 843          ' . $hide_avatar_style . '
 844  
 845          #buddypress div#item-header-cover-image h2 a,
 846          #buddypress div#item-header-cover-image h2 {
 847              color: #FFF;
 848              text-rendering: optimizelegibility;
 849              text-shadow: 0px 0px 3px rgba( 0, 0, 0, 0.8 );
 850              margin: 0 0 .6em;
 851              font-size:200%;
 852          }
 853  
 854          #buddypress #item-header-cover-image #item-header-avatar img.avatar {
 855              border: solid 2px #FFF;
 856              background: rgba( 255, 255, 255, 0.8 );
 857          }
 858  
 859          #buddypress #item-header-cover-image #item-header-avatar a {
 860              border: none;
 861              text-decoration: none;
 862          }
 863  
 864          #buddypress #item-header-cover-image #item-buttons {
 865              margin: 0 0 10px;
 866              padding: 0 0 5px;
 867          }
 868  
 869          #buddypress #item-header-cover-image #item-buttons:after {
 870              clear: both;
 871              content: "";
 872              display: table;
 873          }
 874  
 875          @media screen and (max-width: 782px) {
 876              #buddypress #item-header-cover-image #item-header-avatar,
 877              .bp-user #buddypress #item-header #item-header-cover-image #item-header-avatar,
 878              #buddypress div#item-header #item-header-cover-image #item-header-content {
 879                  width:100%;
 880                  text-align:center;
 881              }
 882  
 883              #buddypress #item-header-cover-image #item-header-avatar a {
 884                  display:inline-block;
 885              }
 886  
 887              #buddypress #item-header-cover-image #item-header-avatar img {
 888                  margin:0;
 889              }
 890  
 891              #buddypress div#item-header #item-header-cover-image #item-header-content,
 892              body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-header-content,
 893              body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-actions {
 894                  margin:0;
 895              }
 896  
 897              body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-header-content,
 898              body.single-item.groups #buddypress div#item-header #item-header-cover-image #item-actions {
 899                  max-width: 100%;
 900              }
 901  
 902              #buddypress div#item-header-cover-image h2 a,
 903              #buddypress div#item-header-cover-image h2 {
 904                  color: inherit;
 905                  text-shadow: none;
 906                  margin:25px 0 0;
 907                  font-size:200%;
 908              }
 909  
 910              #buddypress #item-header-cover-image #item-buttons div {
 911                  float:none;
 912                  display:inline-block;
 913              }
 914  
 915              #buddypress #item-header-cover-image #item-buttons:before {
 916                  content:"";
 917              }
 918  
 919              #buddypress #item-header-cover-image #item-buttons {
 920                  margin: 5px 0;
 921              }
 922          }
 923      ';
 924  }
 925  
 926  /**
 927   * All user feedback messages are available here
 928   *
 929   * @since 3.0.0
 930   * @since 8.0.0 Adds the 'member-invites-none' feedback.
 931   *
 932   * @param string $feedback_id The ID of the message.
 933   *
 934   * @return string|false The list of parameters for the message
 935   */
 936  function bp_nouveau_get_user_feedback( $feedback_id = '' ) {
 937      /**
 938       * Filters the BuddyPress Nouveau feedback messages.
 939       *
 940       * Use this filter to add your custom feedback messages.
 941       *
 942       * @since 3.0.0
 943       * @since 8.0.0 Adds the 'member-invites-none' feedback.
 944       *
 945       * @param array $value The list of feedback messages.
 946       */
 947      $feedback_messages = apply_filters(
 948          'bp_nouveau_feedback_messages',
 949          array(
 950              'registration-disabled'             => array(
 951                  'type'    => 'info',
 952                  'message' => __( 'Member registration is currently not allowed.', 'buddypress' ),
 953                  'before'  => 'bp_before_registration_disabled',
 954                  'after'   => 'bp_after_registration_disabled'
 955              ),
 956              'request-details'                   => array(
 957                  'type'    => 'info',
 958                  'message' => __( 'Registering for this site is easy. Just fill in the fields below, and we\'ll get a new account set up for you in no time.', 'buddypress' ),
 959                  'before'  => false,
 960                  'after'   => false,
 961              ),
 962              'completed-confirmation'            => array(
 963                  'type'    => 'info',
 964                  'message' => __( 'You have successfully created your account! Please log in using the username and password you have just created.', 'buddypress' ),
 965                  'before'  => 'bp_before_registration_confirmed',
 966                  'after'   => 'bp_after_registration_confirmed',
 967              ),
 968              'directory-activity-loading'        => array(
 969                  'type'    => 'loading',
 970                  'message' => __( 'Loading the community updates. Please wait.', 'buddypress' ),
 971              ),
 972              'single-activity-loading'           => array(
 973                  'type'    => 'loading',
 974                  'message' => __( 'Loading the update. Please wait.', 'buddypress' ),
 975              ),
 976              'activity-loop-none'                => array(
 977                  'type'    => 'info',
 978                  'message' => __( 'Sorry, there was no activity found. Please try a different filter.', 'buddypress' ),
 979              ),
 980              'blogs-loop-none'                   => array(
 981                  'type'    => 'info',
 982                  'message' => __( 'Sorry, there were no sites found.', 'buddypress' ),
 983              ),
 984              'blogs-no-signup'                   => array(
 985                  'type'    => 'info',
 986                  'message' => __( 'Site registration is currently disabled.', 'buddypress' ),
 987              ),
 988              'directory-blogs-loading'           => array(
 989                  'type'    => 'loading',
 990                  'message' => __( 'Loading the sites of the network. Please wait.', 'buddypress' ),
 991              ),
 992              'directory-groups-loading'          => array(
 993                  'type'    => 'loading',
 994                  'message' => __( 'Loading the groups of the community. Please wait.', 'buddypress' ),
 995              ),
 996              'groups-loop-none'                  => array(
 997                  'type'    => 'info',
 998                  'message' => __( 'Sorry, there were no groups found.', 'buddypress' ),
 999              ),
1000              'group-activity-loading'            => array(
1001                  'type'    => 'loading',
1002                  'message' => __( 'Loading the group updates. Please wait.', 'buddypress' ),
1003              ),
1004              'group-members-loading'             => array(
1005                  'type'    => 'loading',
1006                  'message' => __( 'Requesting the group members. Please wait.', 'buddypress' ),
1007              ),
1008              'group-members-none'                => array(
1009                  'type'    => 'info',
1010                  'message' => __( 'Sorry, there were no group members found.', 'buddypress' ),
1011              ),
1012              'group-members-search-none'         => array(
1013                  'type'    => 'info',
1014                  'message' => __( 'Sorry, there was no member of that name found in this group.', 'buddypress' ),
1015              ),
1016              'group-manage-members-none'         => array(
1017                  'type'    => 'info',
1018                  'message' => __( 'This group has no members.', 'buddypress' ),
1019              ),
1020              'group-requests-none'               => array(
1021                  'type'    => 'info',
1022                  'message' => __( 'There are no pending membership requests.', 'buddypress' ),
1023              ),
1024              'group-requests-loading'            => array(
1025                  'type'    => 'loading',
1026                  'message' => __( 'Loading the members who requested to join the group. Please wait.', 'buddypress' ),
1027              ),
1028              'group-delete-warning'              => array(
1029                  'type'    => 'warning',
1030                  'message' => __( 'WARNING: Deleting this group will completely remove ALL content associated with it. There is no way back. Please be careful with this option.', 'buddypress' ),
1031              ),
1032              'group-avatar-delete-info'          => array(
1033                  'type'    => 'info',
1034                  'message' => __( 'If you\'d like to remove the existing group profile photo but not upload a new one, please use the delete group profile photo button.', 'buddypress' ),
1035              ),
1036              'directory-members-loading'         => array(
1037                  'type'    => 'loading',
1038                  'message' => __( 'Loading the members of your community. Please wait.', 'buddypress' ),
1039              ),
1040              'members-loop-none'                 => array(
1041                  'type'    => 'info',
1042                  'message' => __( 'Sorry, no members were found.', 'buddypress' ),
1043              ),
1044              'member-requests-none'              => array(
1045                  'type'    => 'info',
1046                  'message' => __( 'You have no pending friendship requests.', 'buddypress' ),
1047              ),
1048              'member-invites-none'               => array(
1049                  'type'    => 'info',
1050                  'message' => __( 'You have no outstanding group invites.', 'buddypress' ),
1051              ),
1052              'member-notifications-none'         => array(
1053                  'type'    => 'info',
1054                  'message' => __( 'This member has no notifications.', 'buddypress' ),
1055              ),
1056              'member-wp-profile-none'            => array(
1057                  'type'    => 'info',
1058                  /* translators: %s: member name */
1059                  'message' => __( '%s did not save any profile information yet.', 'buddypress' ),
1060              ),
1061              'member-delete-account'             => array(
1062                  'type'    => 'warning',
1063                  'message' => __( 'Deleting this account will delete all of the content it has created. It will be completely unrecoverable.', 'buddypress' ),
1064              ),
1065              'member-activity-loading'           => array(
1066                  'type'    => 'loading',
1067                  'message' => __( 'Loading the member\'s updates. Please wait.', 'buddypress' ),
1068              ),
1069              'member-blogs-loading'              => array(
1070                  'type'    => 'loading',
1071                  'message' => __( 'Loading the member\'s blogs. Please wait.', 'buddypress' ),
1072              ),
1073              'member-friends-loading'            => array(
1074                  'type'    => 'loading',
1075                  'message' => __( 'Loading the member\'s friends. Please wait.', 'buddypress' ),
1076              ),
1077              'member-groups-loading'             => array(
1078                  'type'    => 'loading',
1079                  'message' => __( 'Loading the member\'s groups. Please wait.', 'buddypress' ),
1080              ),
1081              'member-notifications-loading'      => array(
1082                  'type'    => 'loading',
1083                  'message' => __( 'Loading notifications. Please wait.', 'buddypress' ),
1084              ),
1085              'member-group-invites-all'          => array(
1086                  'type'    => 'info',
1087                  'message' => __( 'Currently every member of the community can invite you to join their groups. If you are not comfortable with it, you can always restrict group invites to your friends only.', 'buddypress' ),
1088              ),
1089              'member-group-invites-friends-only' => array(
1090                  'type'    => 'info',
1091                  'message' => __( 'Currently only your friends can invite you to groups. Uncheck the box to allow any member to send invites.', 'buddypress' ),
1092              ),
1093              'member-invitations-help'           => array(
1094                  'type'    => 'info',
1095                  'message' => __( 'Fill out the form below to invite a new user to join this site. Upon submission of the form, an email will be sent to the invitee containing a link to accept your invitation. You may also add a custom message to the email.', 'buddypress' ),
1096              ),
1097              'member-invitations-none'           => array(
1098                  'type'    => 'info',
1099                  'message' => __( 'There are no invitations to display.', 'buddypress' ),
1100              ),
1101              'member-invitations-not-allowed'    => array(
1102                  'type'    => 'error',
1103                  /**
1104                   * Use this filter to edit the restricted feedback message displayed into the Send invitation form.
1105                   *
1106                   * @since 8.0.0
1107                   *
1108                   * @param string $value The restricted feedback message displayed into the Send invitation form.
1109                   */
1110                  'message' => apply_filters(
1111                      'members_invitations_form_access_restricted',
1112                      __( 'Sorry, you are not allowed to send invitations.', 'buddypress' )
1113                  ),
1114              ),
1115          )
1116      );
1117  
1118      if ( ! isset( $feedback_messages[ $feedback_id ] ) ) {
1119          return false;
1120      }
1121  
1122      /*
1123       * Adjust some messages to the context.
1124       */
1125      if ( 'completed-confirmation' === $feedback_id && bp_get_membership_requests_required() ) {
1126          $feedback_messages['completed-confirmation']['message'] = __( 'You have successfully submitted your membership request! Our site moderators will review your submission and send you an activation email if your request is approved.', 'buddypress' );
1127      } elseif ( 'completed-confirmation' === $feedback_id && bp_registration_needs_activation() ) {
1128          $feedback_messages['completed-confirmation']['message'] = __( 'You have successfully created your account! To begin using this site you will need to activate your account via the email we have just sent to your address.', 'buddypress' );
1129      } elseif ( 'member-notifications-none' === $feedback_id ) {
1130          $is_myprofile = bp_is_my_profile();
1131  
1132          if ( bp_is_current_action( 'unread' ) ) {
1133              $feedback_messages['member-notifications-none']['message'] = __( 'This member has no unread notifications.', 'buddypress' );
1134  
1135              if ( $is_myprofile ) {
1136                  $feedback_messages['member-notifications-none']['message'] = __( 'You have no unread notifications.', 'buddypress' );
1137              }
1138          } elseif ( $is_myprofile ) {
1139              $feedback_messages['member-notifications-none']['message'] = __( 'You have no notifications.', 'buddypress' );
1140          }
1141      } elseif ( 'member-wp-profile-none' === $feedback_id && bp_is_user_profile() ) {
1142          $feedback_messages['member-wp-profile-none']['message'] = sprintf( $feedback_messages['member-wp-profile-none']['message'], bp_get_displayed_user_fullname() );
1143      } elseif ( 'member-delete-account' === $feedback_id && bp_is_my_profile() ) {
1144          $feedback_messages['member-delete-account']['message'] = __( 'Deleting your account will delete all of the content you have created. It will be completely irrecoverable.', 'buddypress' );
1145      } elseif ( 'member-activity-loading' === $feedback_id && bp_is_my_profile() ) {
1146          $feedback_messages['member-activity-loading']['message'] = __( 'Loading your updates. Please wait.', 'buddypress' );
1147      } elseif ( 'member-blogs-loading' === $feedback_id && bp_is_my_profile() ) {
1148          $feedback_messages['member-blogs-loading']['message'] = __( 'Loading your blogs. Please wait.', 'buddypress' );
1149      } elseif ( 'member-friends-loading' === $feedback_id && bp_is_my_profile() ) {
1150          $feedback_messages['member-friends-loading']['message'] = __( 'Loading your friends. Please wait.', 'buddypress' );
1151      } elseif ( 'member-groups-loading' === $feedback_id && bp_is_my_profile() ) {
1152          $feedback_messages['member-groups-loading']['message'] = __( 'Loading your groups. Please wait.', 'buddypress' );
1153      }
1154  
1155      /**
1156       * Filter here if you wish to edit the message just before being displayed
1157       *
1158       * @since 3.0.0
1159       *
1160       * @param array $feedback_messages
1161       */
1162      return apply_filters( 'bp_nouveau_get_user_feedback', $feedback_messages[ $feedback_id ] );
1163  }
1164  
1165  /**
1166   * Get the signup fields for the requested section
1167   *
1168   * @since 3.0.0
1169   *
1170   * @param string $section Optional. The section of fields to get 'account_details' or 'blog_details'.
1171   *
1172   * @return array|false The list of signup fields for the requested section. False if not found.
1173   */
1174  function bp_nouveau_get_signup_fields( $section = '' ) {
1175      if ( empty( $section ) ) {
1176          return false;
1177      }
1178  
1179      /**
1180       * Filter to add your specific 'text' or 'password' inputs
1181       *
1182       * If you need to use other types of field, please use the
1183       * do_action( 'bp_account_details_fields' ) or do_action( 'blog_details' ) hooks instead.
1184       *
1185       * @since 3.0.0
1186       *
1187       * @param array $value The list of fields organized into sections.
1188       */
1189      $fields = apply_filters( 'bp_nouveau_get_signup_fields', array(
1190          'account_details' => array(
1191              'signup_username' => array(
1192                  'label'          => __( 'Username', 'buddypress' ),
1193                  'required'       => true,
1194                  'value'          => 'bp_get_signup_username_value',
1195                  'attribute_type' => 'username',
1196                  'type'           => 'text',
1197                  'class'          => '',
1198              ),
1199              'signup_email' => array(
1200                  'label'          => __( 'Email Address', 'buddypress' ),
1201                  'required'       => true,
1202                  'value'          => 'bp_get_signup_email_value',
1203                  'attribute_type' => 'email',
1204                  'type'           => 'email',
1205                  'class'          => '',
1206              ),
1207              'signup_password' => array(),
1208              'signup_password_confirm' => array(),
1209          ),
1210          'blog_details' => array(
1211              'signup_blog_url' => array(
1212                  'label'          => __( 'Site URL', 'buddypress' ),
1213                  'required'       => true,
1214                  'value'          => 'bp_get_signup_blog_url_value',
1215                  'attribute_type' => 'slug',
1216                  'type'           => 'text',
1217                  'class'          => '',
1218              ),
1219              'signup_blog_title' => array(
1220                  'label'          => __( 'Site Title', 'buddypress' ),
1221                  'required'       => true,
1222                  'value'          => 'bp_get_signup_blog_title_value',
1223                  'attribute_type' => 'title',
1224                  'type'           => 'text',
1225                  'class'          => '',
1226              ),
1227              'signup_blog_privacy_public' => array(
1228                  'label'          => __( 'Yes', 'buddypress' ),
1229                  'required'       => false,
1230                  'value'          => 'public',
1231                  'attribute_type' => '',
1232                  'type'           => 'radio',
1233                  'class'          => '',
1234              ),
1235              'signup_blog_privacy_private' => array(
1236                  'label'          => __( 'No', 'buddypress' ),
1237                  'required'       => false,
1238                  'value'          => 'private',
1239                  'attribute_type' => '',
1240                  'type'           => 'radio',
1241                  'class'          => '',
1242              ),
1243          ),
1244      ) );
1245  
1246      if ( ! bp_get_blog_signup_allowed() ) {
1247          unset( $fields['blog_details'] );
1248      }
1249  
1250      if ( isset( $fields[ $section ] ) ) {
1251          return $fields[ $section ];
1252      }
1253  
1254      return false;
1255  }
1256  
1257  /**
1258   * Get Some submit buttons data.
1259   *
1260   * @since 3.0.0
1261   * @since 8.0.0 Adds the 'member-send-invite' button.
1262   *
1263   * @param string $action The action requested.
1264   *
1265   * @return array|false The list of the submit button parameters for the requested action
1266   *                     False if no actions were found.
1267   */
1268  function bp_nouveau_get_submit_button( $action = '' ) {
1269      if ( empty( $action ) ) {
1270          return false;
1271      }
1272  
1273      /**
1274       * Filter the Submit buttons to add your own.
1275       *
1276       * @since 3.0.0
1277       * @since 8.0.0 Adds the 'member-send-invite' button.
1278       *
1279       * @param array $value The list of submit buttons.
1280       *
1281       * @return array|false
1282       */
1283      $actions = apply_filters(
1284          'bp_nouveau_get_submit_button',
1285          array(
1286              'register'                      => array(
1287                  'before'     => 'bp_before_registration_submit_buttons',
1288                  'after'      => 'bp_after_registration_submit_buttons',
1289                  'nonce'      => 'bp_new_signup',
1290                  'attributes' => array(
1291                      'name'  => 'signup_submit',
1292                      'id'    => 'submit',
1293                      'value' => __( 'Complete Sign Up', 'buddypress' ),
1294                  ),
1295              ),
1296              'member-profile-edit'           => array(
1297                  'before'     => '',
1298                  'after'      => '',
1299                  'nonce'      => 'bp_xprofile_edit',
1300                  'attributes' => array(
1301                      'name'  => 'profile-group-edit-submit',
1302                      'id'    => 'profile-group-edit-submit',
1303                      'value' => __( 'Save Changes', 'buddypress' ),
1304                  ),
1305              ),
1306              'member-capabilities'           => array(
1307                  'before'     => 'bp_members_capabilities_account_before_submit',
1308                  'after'      => 'bp_members_capabilities_account_after_submit',
1309                  'nonce'      => 'capabilities',
1310                  'attributes' => array(
1311                      'name'  => 'capabilities-submit',
1312                      'id'    => 'capabilities-submit',
1313                      'value' => __( 'Save', 'buddypress' ),
1314                  ),
1315              ),
1316              'member-delete-account'         => array(
1317                  'before'     => 'bp_members_delete_account_before_submit',
1318                  'after'      => 'bp_members_delete_account_after_submit',
1319                  'nonce'      => 'delete-account',
1320                  'attributes' => array(
1321                      'disabled' => 'disabled',
1322                      'name'     => 'delete-account-button',
1323                      'id'       => 'delete-account-button',
1324                      'value'    => __( 'Delete Account', 'buddypress' ),
1325                  ),
1326              ),
1327              'members-general-settings'      => array(
1328                  'before'     => 'bp_core_general_settings_before_submit',
1329                  'after'      => 'bp_core_general_settings_after_submit',
1330                  'nonce'      => 'bp_settings_general',
1331                  'attributes' => array(
1332                      'name'  => 'submit',
1333                      'id'    => 'submit',
1334                      'value' => __( 'Save Changes', 'buddypress' ),
1335                      'class' => 'auto',
1336                  ),
1337              ),
1338              'member-notifications-settings' => array(
1339                  'before'     => 'bp_members_notification_settings_before_submit',
1340                  'after'      => 'bp_members_notification_settings_after_submit',
1341                  'nonce'      => 'bp_settings_notifications',
1342                  'attributes' => array(
1343                      'name'  => 'submit',
1344                      'id'    => 'submit',
1345                      'value' => __( 'Save Changes', 'buddypress' ),
1346                      'class' => 'auto',
1347                  ),
1348              ),
1349              'members-profile-settings'      => array(
1350                  'before'     => 'bp_core_xprofile_settings_before_submit',
1351                  'after'      => 'bp_core_xprofile_settings_after_submit',
1352                  'nonce'      => 'bp_xprofile_settings',
1353                  'attributes' => array(
1354                      'name'  => 'xprofile-settings-submit',
1355                      'id'    => 'submit',
1356                      'value' => __( 'Save Changes', 'buddypress' ),
1357                      'class' => 'auto',
1358                  ),
1359              ),
1360              'member-group-invites'          => array(
1361                  'nonce'      => 'bp_nouveau_group_invites_settings',
1362                  'attributes' => array(
1363                      'name'  => 'member-group-invites-submit',
1364                      'id'    => 'submit',
1365                      'value' => __( 'Save', 'buddypress' ),
1366                      'class' => 'auto',
1367                  ),
1368              ),
1369              'member-send-invite'            => array(
1370                  'nonce'                   => 'bp_members_invitation_send_%d',
1371                  'nonce_placeholder_value' => bp_displayed_user_id() ? bp_displayed_user_id() : bp_loggedin_user_id(),
1372                  'attributes'              => array(
1373                      'name'  => 'member-send-invite-submit',
1374                      'id'    => 'submit',
1375                      'value' => __( 'Send', 'buddypress' ),
1376                      'class' => 'auto',
1377                  ),
1378              ),
1379              'activity-new-comment'          => array(
1380                  'after'      => 'bp_activity_entry_comments',
1381                  'nonce'      => 'new_activity_comment',
1382                  'nonce_key'  => '_wpnonce_new_activity_comment',
1383                  'wrapper'    => false,
1384                  'attributes' => array(
1385                      'name'  => 'ac_form_submit',
1386                      'value' => _x( 'Post', 'button', 'buddypress' ),
1387                  ),
1388              ),
1389          )
1390      );
1391  
1392      if ( isset( $actions[ $action ] ) ) {
1393          return $actions[ $action ];
1394      }
1395  
1396      return false;
1397  }
1398  
1399  /**
1400   * Reorder a BuddyPress item nav according to a given list of nav item slugs
1401   *
1402   * @since 3.0.0
1403   *
1404   * @param object $nav         The BuddyPress Item Nav object to reorder
1405   * @param array  $order       A list of slugs ordered (eg: array( 'profile', 'activity', etc..) )
1406   * @param string $parent_slug A parent slug if it's a secondary nav we are reordering (case of the Groups single item)
1407   *
1408   * @return bool True on success. False otherwise.
1409   */
1410  function bp_nouveau_set_nav_item_order( $nav = null, $order = array(), $parent_slug = '' ) {
1411      if ( ! is_object( $nav ) || empty( $order ) || ! is_array( $order ) ) {
1412          return false;
1413      }
1414  
1415      $position = 0;
1416  
1417      foreach ( $order as $slug ) {
1418          $position += 10;
1419  
1420          $key = $slug;
1421          if ( ! empty( $parent_slug ) ) {
1422              $key = $parent_slug . '/' . $key;
1423          }
1424  
1425          $item_nav = $nav->get( $key );
1426  
1427          if ( ! $item_nav ) {
1428              continue;
1429          }
1430  
1431          if ( (int) $item_nav->position !== (int) $position ) {
1432              $nav->edit_nav( array( 'position' => $position ), $slug, $parent_slug );
1433          }
1434      }
1435  
1436      return true;
1437  }
1438  
1439  /**
1440   * Gets the component's slug thanks to its ID.
1441   *
1442   * @since 8.0.0
1443   *
1444   * @param string $component_id The component ID.
1445   * @return string The slug for the requested component ID.
1446   */
1447  function bp_nouveau_get_component_slug( $component_id = '' ) {
1448      $slug = '';
1449  
1450      if ( bp_is_active( $component_id ) ) {
1451          switch ( $component_id ) {
1452              case 'activity':
1453                  $slug = bp_get_activity_slug();
1454                  break;
1455              case 'blogs':
1456                  $slug = bp_get_blogs_slug();
1457                  break;
1458              case 'friends':
1459                  $slug = bp_get_friends_slug();
1460                  break;
1461              case 'groups':
1462                  $slug = bp_get_groups_slug();
1463                  break;
1464              case 'messages':
1465                  $slug = bp_get_messages_slug();
1466                  break;
1467              case 'notifications':
1468                  $slug = bp_get_notifications_slug();
1469                  break;
1470              case 'settings':
1471                  $slug = bp_get_settings_slug();
1472                  break;
1473              case 'xprofile':
1474                  $slug = bp_get_profile_slug();
1475                  break;
1476          }
1477      }
1478  
1479      // Defaults to the component ID.
1480      if ( ! $slug ) {
1481          $slug = $component_id;
1482      }
1483  
1484      /**
1485       * Filter here to edit the slug for the requested component ID.
1486       *
1487       * @since 8.0.0
1488       *
1489       * @param string $slug         The slug for the requested component ID.
1490       * @param string $component_id The component ID.
1491       */
1492      return apply_filters( 'bp_nouveau_get_component_slug', $slug, $component_id );
1493  }
1494  
1495  /**
1496   * Registers the 'bp/primary-nav' Widget Block.
1497   *
1498   * @since 9.0.0
1499   *
1500   * @param array $blocks The Core Blocks list.
1501   * @return array The Core Blocks list.
1502   */
1503  function bp_nouveau_register_primary_nav_widget_block( $blocks = array() ) {
1504      $editor_style = bp_locate_template_asset( 'css/primary-nav.css' );
1505  
1506      $blocks['bp/primary-nav'] = array(
1507          'name'               => 'bp/primary-nav',
1508          'editor_script'      => 'bp-primary-nav-block',
1509          'editor_script_url'  => trailingslashit( buddypress()->plugin_url . 'bp-core' ) . 'js/blocks/primary-nav.js',
1510          'editor_script_deps' => array(
1511              'wp-blocks',
1512              'wp-element',
1513              'wp-components',
1514              'wp-i18n',
1515              'wp-block-editor',
1516              'wp-server-side-render',
1517              'bp-block-data',
1518          ),
1519          'editor_style'       => 'bp-primary-nav-block',
1520          'editor_style_url'   => $editor_style['uri'],
1521          'attributes'         => array(
1522              'displayTitle' => array(
1523                  'type'    => 'boolean',
1524                  'default' => true,
1525              ),
1526          ),
1527          'render_callback'    => 'bp_nouveau_render_primary_nav_block',
1528      );
1529  
1530      return $blocks;
1531  }
1532  add_filter( 'bp_core_register_blocks', 'bp_nouveau_register_primary_nav_widget_block', 20, 1 );
1533  
1534  /**
1535   * Registers the 'bp/primary-nav' Widget Block classnames.
1536   *
1537   * @since 9.0.0
1538   *
1539   * @param array $block_globals The list of global properties for Core blocks.
1540   * @return array               The list of global properties for Core blocks.
1541   */
1542  function bp_nouveau_register_core_block_globals( $block_globals = array() ) {
1543      $block_globals['bp/primary-nav'] = array(
1544          'widget_classnames' => array( 'widget_nav_menu', 'buddypress_object_nav', 'buddypress' ),
1545      );
1546  
1547      return $block_globals;
1548  }
1549  add_filter( 'bp_core_block_globals', 'bp_nouveau_register_core_block_globals', 10, 1 );
1550  
1551  /**
1552   * Unregister the 'bp/primary-nav' Block from the post context.
1553   *
1554   * @since 9.0.0
1555   */
1556  function bp_nouveau_unregister_blocks_for_post_context() {
1557      $is_registered = WP_Block_Type_Registry::get_instance()->is_registered( 'bp/primary-nav' );
1558  
1559      if ( $is_registered ) {
1560          unregister_block_type( 'bp/primary-nav' );
1561      }
1562  }
1563  add_action( 'load-post.php', 'bp_nouveau_unregister_blocks_for_post_context' );
1564  add_action( 'load-post-new.php', 'bp_nouveau_unregister_blocks_for_post_context' );
1565  
1566  /**
1567   * Callback function to render the BP Primary Nav Block.
1568   *
1569   * @since 9.0.0
1570   *
1571   * @param array $attributes The block attributes.
1572   * @return string           HTML output.
1573   */
1574  function bp_nouveau_render_primary_nav_block( $attributes = array() ) {
1575      $widget_content = '';
1576      $widget_title   = '';
1577      $block_args     = bp_parse_args(
1578          $attributes,
1579          array(
1580              'displayTitle' => true,
1581          ),
1582          'widget_object_nav'
1583      );
1584  
1585      // Previewing the Block inside the editor.
1586      if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
1587          $widget_title = bp_get_loggedin_user_fullname();
1588  
1589          ob_start();
1590  
1591          // Temporary override the displayed user by the logged in one.
1592          add_filter( 'bp_displayed_user_id', 'bp_loggedin_user_id' );
1593  
1594          bp_get_template_part( 'members/single/parts/item-nav' );
1595          $widget_content = ob_get_clean();
1596  
1597          // Remove the temporary override.
1598          remove_filter( 'bp_displayed_user_id', 'bp_loggedin_user_id' );
1599      } else {
1600          ob_start();
1601  
1602          if ( bp_is_user() ) {
1603              $widget_title = bp_get_displayed_user_fullname();
1604              bp_get_template_part( 'members/single/parts/item-nav' );
1605          } elseif ( bp_is_group() ) {
1606              $widget_title = bp_get_current_group_name();
1607              bp_get_template_part( 'groups/single/parts/item-nav' );
1608          } elseif ( bp_is_directory() ) {
1609              $widget_title = bp_get_directory_title( bp_current_component() );
1610              bp_get_template_part( 'common/nav/directory-nav' );
1611          }
1612  
1613          $widget_content = ob_get_clean();
1614      }
1615  
1616      if ( ! $widget_content ) {
1617          return '';
1618      }
1619  
1620      // Set the Block's title.
1621      if ( true === $block_args['displayTitle'] ) {
1622          $widget_content = sprintf(
1623              '<h2 class="widget-title">%1$s</h2>
1624              %2$s',
1625              esc_html( $widget_title ),
1626              $widget_content
1627          );
1628      }
1629  
1630      // Only add a block wrapper if not loaded into a Widgets sidebar.
1631      if ( ! did_action( 'dynamic_sidebar_before' ) ) {
1632          $classnames         = 'widget_nav_menu buddypress_object_nav buddypress widget';
1633          $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) );
1634  
1635          return sprintf(
1636              '<div %1$s>%2$s</div>',
1637              $wrapper_attributes,
1638              $widget_content
1639          );
1640      }
1641  
1642      return $widget_content;
1643  }
1644  
1645  /**
1646   * Retuns the theme layout available widths.
1647   *
1648   * @since 10.0.0
1649   *
1650   * @return array The available theme layout widths.
1651   */
1652  function bp_nouveau_get_theme_layout_widths() {
1653      $layout_widths = array();
1654  
1655      if ( current_theme_supports( 'align-wide' ) ) {
1656          $layout_widths = array(
1657              'alignnone' => __( 'Default width', 'buddypress' ),
1658              'alignwide' => __( 'Wide width', 'buddypress' ),
1659              'alignfull' => __( 'Full width', 'buddypress' ),
1660          );
1661      }
1662  
1663      // `wp_get_global_settings()` has been introduced in WordPress 5.9
1664      if ( function_exists( 'wp_get_global_settings' ) ) {
1665          $theme_layouts = wp_get_global_settings( array( 'layout' ) );
1666  
1667          if ( isset( $theme_layouts['wideSize'] ) && $theme_layouts['wideSize'] ) {
1668              $layout_widths = array(
1669                  'alignnone' => __( 'Content width', 'buddypress' ),
1670                  'alignwide' => __( 'Wide width', 'buddypress' ),
1671              );
1672          }
1673      }
1674  
1675      /**
1676       * Filter here to edit the available theme layout widths.
1677       *
1678       * @since 10.0.0
1679       *
1680       * @param array $layout_widths The available theme layout widths.
1681       */
1682      return apply_filters( 'bp_nouveau_get_theme_layout_widths', $layout_widths );
1683  }


Generated: Wed Jun 29 01:00:59 2022 Cross-referenced by PHPXref 0.7.1