[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
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' => __( '— Everything —', '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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Oct 16 01:00:54 2024 | Cross-referenced by PHPXref 0.7.1 |