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