Ticket #6534: 6534.2.diff
File 6534.2.diff, 99.4 KB (added by , 7 years ago) |
---|
-
src/bp-core/bp-core-buddybar.php
diff --git src/bp-core/bp-core-buddybar.php src/bp-core/bp-core-buddybar.php index 9f1ffb0..63c7a5d 100644
13 13 defined( 'ABSPATH' ) || exit; 14 14 15 15 /** 16 * Add an item to the main BuddyPress navigation array.16 * Add an item to the primary navigation of the specified component. 17 17 * 18 18 * @since 1.1.0 19 * @since 2.6.0 Introduced the `$component` parameter. 19 20 * 20 21 * @param array|string $args { 21 22 * Array describing the new nav item. … … defined( 'ABSPATH' ) || exit; 32 33 * @type bool|string $default_subnav_slug Optional. The slug of the default subnav item to select when the nav 33 34 * item is clicked. 34 35 * } 36 * @param string $component The component the navigation is attached to. Defaults to 'members'. 35 37 * @return bool|null Returns false on failure. 36 38 */ 37 function bp_core_new_nav_item( $args = '' ) { 39 40 function bp_core_new_nav_item( $args, $component = 'members' ) { 41 if ( ! bp_is_active( $component ) ) { 42 return; 43 } 38 44 39 45 $defaults = array( 40 46 'name' => false, // Display name for the nav item. … … function bp_core_new_nav_item( $args = '' ) { 49 55 50 56 $r = wp_parse_args( $args, $defaults ); 51 57 52 // First, add the nav item link to the bp_nav array.53 $ created = bp_core_create_nav_link( $r);58 // Validate nav link data. 59 $nav_item = bp_core_create_nav_link( $r, $component ); 54 60 55 // To mimic the existing behavior, if bp_core_create_nav_link() 56 // returns false, we make an early exit and don't attempt to register 57 // the screen function. 58 if ( false === $created ) { 61 /* 62 * To mimic legacy behavior, if bp_core_create_nav_link() returns false, we make 63 * an early exit and don't attempt to register the screen function. 64 */ 65 if ( false === $nav_item ) { 59 66 return false; 60 67 } 61 68 62 69 // Then, hook the screen function for the added nav item. 63 $hooked = bp_core_register_nav_screen_function( $ r);70 $hooked = bp_core_register_nav_screen_function( $nav_item ); 64 71 if ( false === $hooked ){ 65 72 return false; 66 73 } … … function bp_core_new_nav_item( $args = '' ) { 81 88 } 82 89 83 90 /** 84 * Add a link to the main BuddyPress navigation array.91 * Add a link to the main BuddyPress navigation. 85 92 * 86 93 * @since 2.4.0 94 * @since 2.6.0 Introduced the `$component` parameter. Began returning a BP_Nav_Item object on success. 87 95 * 88 96 * @param array|string $args { 89 97 * Array describing the new nav item. … … function bp_core_new_nav_item( $args = '' ) { 100 108 * @type bool|string $default_subnav_slug Optional. The slug of the default subnav item to select when the nav 101 109 * item is clicked. 102 110 * } 103 * @return bool|null Returns false on failure. 111 * @param string $component Optional. Component that the nav belongs to. 112 * @return bool|BP_Nav_Item Returns false on failure, new nav item on success. 104 113 */ 105 function bp_core_create_nav_link( $args = '' ) {114 function bp_core_create_nav_link( $args = '', $component = 'members' ) { 106 115 $bp = buddypress(); 107 116 108 117 $defaults = array( … … function bp_core_create_nav_link( $args = '' ) { 132 141 $r['item_css_id'] = $r['slug']; 133 142 } 134 143 135 $ bp->bp_nav[$r['slug']]= array(144 $nav_item = array( 136 145 'name' => $r['name'], 137 146 'slug' => $r['slug'], 138 147 'link' => trailingslashit( bp_loggedin_user_domain() . $r['slug'] ), … … function bp_core_create_nav_link( $args = '' ) { 143 152 'default_subnav_slug' => $r['default_subnav_slug'] 144 153 ); 145 154 155 // Add the item to the nav. 156 $retval = buddypress()->{$component}->nav->add_nav( $nav_item ); 157 146 158 /** 147 * Fires after a link is added to the main BuddyPress nav igation array.159 * Fires after a link is added to the main BuddyPress nav. 148 160 * 149 161 * @since 2.4.0 150 162 * 151 * @param array $r Parsed arguments for the nav item. 152 * @param array $args Originally passed in arguments for the nav item. 153 * @param array $defaults Default arguments for a nav item. 163 * @param array $r Parsed arguments for the nav item. 164 * @param array $args Originally passed in arguments for the nav item. 165 * @param array $defaults Default arguments for a nav item. 166 * @param string $component Component that the nav belongs to. 154 167 */ 155 do_action( 'bp_core_create_nav_link', $r, $args, $defaults ); 168 do_action( 'bp_core_create_nav_link', $r, $args, $defaults, $component ); 169 170 return $retval; 156 171 } 157 172 158 173 /** … … function bp_core_new_nav_default( $args = '' ) { 290 305 291 306 $r = wp_parse_args( $args, $defaults ); 292 307 293 if ( $function = $bp->bp_nav[$r['parent_slug']]['screen_function'] ) { 308 // This is specific to Members - it's not available in Groups. 309 $parent_nav = $bp->members->nav->get_primary( array( 'slug' => $r['parent_slug'] ), false ); 310 311 if ( ! $parent_nav ) { 312 return ; 313 } 314 315 $parent_nav = reset( $parent_nav ); 316 317 if ( ! empty( $parent_nav->screen_function ) ) { 294 318 // Remove our screen hook if screen function is callable. 295 if ( is_callable( $ function ) ) {296 remove_action( 'bp_screens', $ function, 3 );319 if ( is_callable( $parent_nav->screen_function ) ) { 320 remove_action( 'bp_screens', $parent_nav->screen_function, 3 ); 297 321 } 298 322 } 299 323 300 $bp->bp_nav[$r['parent_slug']]['screen_function'] = &$r['screen_function']; 324 // Edit the screen function for the parent nav 325 $bp->members->nav->edit_nav( array( 326 'screen_function' => &$r['screen_function'], 327 'default_subnav_slug' => $r['subnav_slug'], 328 ), $parent_nav->slug ); 301 329 302 if ( bp_is_current_component( $ r['parent_slug']) ) {330 if ( bp_is_current_component( $parent_nav->slug ) ) { 303 331 304 332 // The only way to tell whether to set the subnav is to peek at the unfiltered_uri 305 333 // Find the component. 306 $component_uri_key = array_search( $ r['parent_slug'], $bp->unfiltered_uri );334 $component_uri_key = array_search( $parent_nav->slug, $bp->unfiltered_uri ); 307 335 308 336 if ( false !== $component_uri_key ) { 309 337 if ( ! empty( $bp->unfiltered_uri[$component_uri_key + 1] ) ) { … … function bp_core_new_nav_default( $args = '' ) { 339 367 } 340 368 341 369 /** 342 * Sort the navigation menu items. 343 * 344 * The sorting is split into a separate function because it can only happen 345 * after all plugins have had a chance to register their navigation items. 346 * 347 * @since 1.0.0 348 * 349 * @return bool|null Returns false on failure. 350 */ 351 function bp_core_sort_nav_items() { 352 $bp = buddypress(); 353 354 if ( empty( $bp->bp_nav ) || ! is_array( $bp->bp_nav ) ) { 355 return false; 356 } 357 358 $temp = array(); 359 360 foreach ( (array) $bp->bp_nav as $slug => $nav_item ) { 361 if ( empty( $temp[$nav_item['position']] ) ) { 362 $temp[$nav_item['position']] = $nav_item; 363 } else { 364 // Increase numbers here to fit new items in. 365 do { 366 $nav_item['position']++; 367 } while ( ! empty( $temp[$nav_item['position']] ) ); 368 369 $temp[$nav_item['position']] = $nav_item; 370 } 371 } 372 373 ksort( $temp ); 374 $bp->bp_nav = &$temp; 375 } 376 add_action( 'wp_head', 'bp_core_sort_nav_items' ); 377 add_action( 'admin_head', 'bp_core_sort_nav_items' ); 378 379 /** 380 * Add a subnav item to the BuddyPress navigation. 370 * Add an item to secondary navigation of the specified component. 381 371 * 382 372 * @since 1.1.0 373 * @since 2.6.0 Introduced the `$component` parameter. 383 374 * 384 375 * @param array|string $args { 385 376 * Array describing the new subnav item. … … add_action( 'admin_head', 'bp_core_sort_nav_items' ); 403 394 * @type bool $show_in_admin_bar Optional. Whether the nav item should be added into the group's "Edit" 404 395 * Admin Bar menu for group admins. Default: false. 405 396 * } 397 * @param string $component The component the navigation is attached to. Defaults to 'members'. 406 398 * @return bool|null Returns false on failure. 407 399 */ 408 function bp_core_new_subnav_item( $args = '' ) { 400 function bp_core_new_subnav_item( $args, $component = null ) { 401 // Backward compatibility for plugins using `bp_core_new_subnav_item()` without `$component` 402 // to add group subnav items. 403 if ( null === $component && bp_is_active( 'groups' ) && bp_is_group() && isset( $args['parent_slug'] ) ) { 404 /* 405 * Assume that this item is intended to belong to the current group if: 406 * a) the 'parent_slug' is the same as the slug of the current group, or 407 * b) the 'parent_slug' starts with the slug of the current group, and the members nav doesn't have 408 * a primary item with that slug 409 */ 410 $group_slug = bp_get_current_group_slug(); 411 if ( 412 $group_slug === $args['parent_slug'] || 413 ( 0 === strpos( $args['parent_slug'], $group_slug ) && ! buddypress()->members->nav->get_primary( array( 'slug' => $args['parent_slug'] ), false ) ) 414 ) { 415 $component = 'groups'; 416 } 417 } 409 418 410 // First, add the subnav item link to the bp_options_nav array. 411 $created = bp_core_create_subnav_link( $args ); 419 if ( ! $component ) { 420 $component = 'members'; 421 } 422 423 if ( ! bp_is_active( $component ) ) { 424 return; 425 } 426 427 // First, register the subnav item in the nav. 428 $subnav_item = bp_core_create_subnav_link( $args, $component ); 412 429 413 // To mimic the existing behavior, if bp_core_create_subnav_link() 414 // returns false, we make an early exit and don't attempt to register 415 // the screen function. 416 if ( false === $created ) { 430 /* 431 * To mimic legacy behavior, if bp_core_create_subnav_link() returns false, we make an 432 * early exit and don't attempt to register the screen function. 433 */ 434 if ( false === $subnav_item ) { 417 435 return false; 418 436 } 419 437 420 438 // Then, hook the screen function for the added subnav item. 421 $hooked = bp_core_register_subnav_screen_function( $ args);439 $hooked = bp_core_register_subnav_screen_function( $subnav_item, $component ); 422 440 if ( false === $hooked ) { 423 441 return false; 424 442 } … … function bp_core_new_subnav_item( $args = '' ) { 428 446 * Add a subnav link to the BuddyPress navigation. 429 447 * 430 448 * @since 2.4.0 449 * @since 2.6.0 Introduced the `$component` parameter. Began returning a BP_Nav_Item object on success. 431 450 * 432 451 * @param array|string $args { 433 452 * Array describing the new subnav item. … … function bp_core_new_subnav_item( $args = '' ) { 455 474 * the group's "Edit" Admin Bar menu for group admins. 456 475 * Default: false. 457 476 * } 458 * @return bool|null Returns false on failure. 477 * @param string $component The component the navigation is attached to. Defaults to 'members'. 478 * @return bool|BP_Nav_Item Returns false on failure, new nav item on success. 459 479 */ 460 function bp_core_create_subnav_link( $args = '' ) {480 function bp_core_create_subnav_link( $args = '', $component = 'members' ) { 461 481 $bp = buddypress(); 462 482 463 483 $r = wp_parse_args( $args, array( … … function bp_core_create_subnav_link( $args = '' ) { 483 503 if ( empty( $r['link'] ) ) { 484 504 $r['link'] = trailingslashit( $r['parent_url'] . $r['slug'] ); 485 505 506 $parent_nav = $bp->{$component}->nav->get_primary( array( 'slug' => $r['parent_slug'] ), false ); 507 486 508 // If this sub item is the default for its parent, skip the slug. 487 if ( ! empty( $bp->bp_nav[$r['parent_slug']]['default_subnav_slug'] ) && $r['slug'] == $bp->bp_nav[$r['parent_slug']]['default_subnav_slug'] ) { 488 $r['link'] = trailingslashit( $r['parent_url'] ); 509 if ( $parent_nav ) { 510 $parent_nav_item = reset( $parent_nav ); 511 if ( ! empty( $parent_nav_item->default_subnav_slug ) && $r['slug'] === $parent_nav_item->default_subnav_slug ) { 512 $r['link'] = trailingslashit( $r['parent_url'] ); 513 } 489 514 } 490 515 } 491 516 … … function bp_core_create_subnav_link( $args = '' ) { 502 527 'name' => $r['name'], 503 528 'link' => $r['link'], 504 529 'slug' => $r['slug'], 530 'parent_slug' => $r['parent_slug'], 505 531 'css_id' => $r['item_css_id'], 506 532 'position' => $r['position'], 507 533 'user_has_access' => $r['user_has_access'], … … function bp_core_create_subnav_link( $args = '' ) { 510 536 'show_in_admin_bar' => (bool) $r['show_in_admin_bar'], 511 537 ); 512 538 513 $bp->bp_options_nav[$r['parent_slug']][$r['slug']] = $subnav_item;539 return buddypress()->{$component}->nav->add_nav( $subnav_item ); 514 540 } 515 541 516 542 /** 517 543 * Register a screen function, whether or not a related subnav link exists. 518 544 * 519 545 * @since 2.4.0 546 * @since 2.6.0 Introduced the `$component` parameter. 520 547 * 521 548 * @param array|string $args { 522 549 * Array describing the new subnav item. … … function bp_core_create_subnav_link( $args = '' ) { 541 568 * the group's "Edit" Admin Bar menu for group admins. 542 569 * Default: false. 543 570 * } 571 * @param string $component The component the navigation is attached to. Defaults to 'members'. 544 572 * @return bool|null Returns false on failure. 545 573 */ 546 function bp_core_register_subnav_screen_function( $args = '' ) {574 function bp_core_register_subnav_screen_function( $args = '', $component = 'members' ) { 547 575 $bp = buddypress(); 548 576 549 577 $r = wp_parse_args( $args, array( … … function bp_core_register_subnav_screen_function( $args = '' ) { 555 583 'screen_function' => false, // The name of the function to run when clicked. 556 584 ) ); 557 585 558 /* *586 /* 559 587 * Hook the screen function for the added subnav item. But this only needs to 560 588 * be done if this subnav item is the current view, and the user has access to the 561 589 * subnav item. We figure out whether we're currently viewing this subnav by … … function bp_core_register_subnav_screen_function( $args = '' ) { 568 596 * (b) there is no current_action (ie, this is the default subnav for the parent nav) 569 597 * and this subnav item is the default for the parent item (which we check by 570 598 * comparing this subnav item's screen function with the screen function of the 571 * parent nav item in $bp->bp_nav). This condition only arises when viewing a572 * user, since groups should always have an action set.599 * parent nav item in the component's primary nav). This condition only arises 600 * when viewing a user, since groups should always have an action set. 573 601 */ 574 602 575 603 // If we *don't* meet condition (1), return. … … function bp_core_register_subnav_screen_function( $args = '' ) { 577 605 return; 578 606 } 579 607 608 $parent_nav = $bp->{$component}->nav->get_primary( array( 'slug' => $r['parent_slug'] ), false ); 609 580 610 // If we *do* meet condition (2), then the added subnav item is currently being requested. 581 if ( ( bp_current_action() && bp_is_current_action( $r['slug'] ) ) || ( bp_is_user() && ! bp_current_action() && ( $r['screen_function'] == $bp->bp_nav[$r['parent_slug']]['screen_function'] )) ) {611 if ( ( bp_current_action() && bp_is_current_action( $r['slug'] ) ) || ( bp_is_user() && ! bp_current_action() && ! empty( $parent_nav->screen_function ) && $r['screen_function'] == $parent_nav->screen_function ) ) { 582 612 583 613 // If this is for site admins only and the user is not one, don't create the subnav item. 584 614 if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) { 585 615 return false; 586 616 } 587 617 588 $hooked = bp_core_maybe_hook_new_subnav_screen_function( $r );618 $hooked = bp_core_maybe_hook_new_subnav_screen_function( $r, $component ); 589 619 590 620 // If redirect args have been returned, perform the redirect now. 591 621 if ( ! empty( $hooked['status'] ) && 'failure' === $hooked['status'] && isset( $hooked['redirect_args'] ) ) { … … function bp_core_register_subnav_screen_function( $args = '' ) { 598 628 * For a given subnav item, either hook the screen function or generate redirect arguments, as necessary. 599 629 * 600 630 * @since 2.1.0 631 * @since 2.6.0 Introduced the `$component` parameter. 601 632 * 602 * @param array $subnav_item The subnav array added to bp_options_nav in `bp_core_new_subnav_item()`. 633 * @param array $subnav_item The subnav array added to the secondary navigation of 634 * the component in bp_core_new_subnav_item(). 635 * @param string $component The component the navigation is attached to. Defaults to 'members'. 603 636 * @return array 604 637 */ 605 function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ) {638 function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item, $component = 'members' ) { 606 639 $retval = array( 607 640 'status' => '', 608 641 ); … … function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ) { 645 678 // redirect URL. 646 679 } elseif ( bp_is_user() ) { 647 680 681 $parent_nav_default = $bp->{$component}->nav->get_primary( array( 'slug' => $bp->default_component ), false ); 682 if ( $parent_nav_default ) { 683 $parent_nav_default_item = reset( $parent_nav_default ); 684 } 685 648 686 // Redirect to the displayed user's default 649 687 // component, as long as that component is 650 688 // publicly accessible. 651 if ( bp_is_my_profile() || ! empty( $bp->bp_nav[ $bp->default_component ]['show_for_displayed_user']) ) {689 if ( bp_is_my_profile() || ( isset( $parent_nav_default_item ) && $parent_nav_default_item->show_for_displayed_user ) ) { 652 690 $message = __( 'You do not have access to this page.', 'buddypress' ); 653 691 $redirect_to = bp_displayed_user_domain(); 654 692 … … function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ) { 691 729 } 692 730 693 731 /** 694 * Sort all subnavigation arrays.732 * Check whether a given nav item has subnav items. 695 733 * 696 * @since 1.1.0 734 * @since 1.5.0 735 * @since 2.6.0 Introduced the `$component` parameter. 697 736 * 698 * @return bool|null Returns false on failure. 737 * @param string $nav_item The slug of the top-level nav item whose subnav items you're checking. 738 * Default: the current component slug. 739 * @param string $component The component the navigation is attached to. Defaults to 'members'. 740 * @return bool $has_subnav True if the nav item is found and has subnav items; false otherwise. 699 741 */ 700 function bp_ core_sort_subnav_items() {742 function bp_nav_item_has_subnav( $nav_item = '', $component = 'members' ) { 701 743 $bp = buddypress(); 702 744 703 if ( empty( $bp->bp_options_nav ) || !is_array( $bp->bp_options_nav ) )745 if ( ! isset( $bp->{$component}->nav ) ) { 704 746 return false; 747 } 705 748 706 foreach ( (array) $bp->bp_options_nav as $parent_slug => $subnav_items ) { 707 if ( !is_array( $subnav_items ) ) 708 continue; 709 710 foreach ( (array) $subnav_items as $subnav_item ) { 711 if ( empty( $temp[$subnav_item['position']]) ) 712 $temp[$subnav_item['position']] = $subnav_item; 713 else { 714 // Increase numbers here to fit new items in. 715 do { 716 $subnav_item['position']++; 717 } while ( !empty( $temp[$subnav_item['position']] ) ); 749 if ( ! $nav_item ) { 750 $nav_item = bp_current_component(); 718 751 719 $temp[$subnav_item['position']] = $subnav_item;720 }752 if ( bp_is_group() ) { 753 $nav_item = bp_current_item(); 721 754 } 722 ksort( $temp );723 $bp->bp_options_nav[$parent_slug] = &$temp;724 unset( $temp );725 755 } 726 }727 add_action( 'wp_head', 'bp_core_sort_subnav_items' );728 add_action( 'admin_head', 'bp_core_sort_subnav_items' );729 730 /**731 * Check whether a given nav item has subnav items.732 *733 * @since 1.5.0734 *735 * @param string $nav_item The slug of the top-level nav item whose subnav items you're checking.736 * Default: the current component slug.737 * @return bool $has_subnav True if the nav item is found and has subnav items; false otherwise.738 */739 function bp_nav_item_has_subnav( $nav_item = '' ) {740 $bp = buddypress();741 742 if ( !$nav_item )743 $nav_item = bp_current_component();744 756 745 $has_subnav = isset( $bp->bp_options_nav[$nav_item] ) && count( $bp->bp_options_nav[$nav_item] ) > 0;757 $has_subnav = (bool) $bp->{$component}->nav->get_secondary( array( 'parent_slug' => $nav_item ), false ); 746 758 747 759 /** 748 760 * Filters whether or not a given nav item has subnav items. … … function bp_nav_item_has_subnav( $nav_item = '' ) { 756 768 } 757 769 758 770 /** 759 * Remove a nav item from the navigation array.771 * Deletes an item from the primary navigation of the specified component. 760 772 * 761 * @since 1.0.0773 * @since 2.6.0 762 774 * 763 * @param int $parent_id The slug of the parent navigation item. 764 * @return bool Returns false on failure, ie if the nav item can't be found. 775 * @param string $slug The slug of the primary navigation item. 776 * @param string $component The component the navigation is attached to. Defaults to 'members'. 777 * @return bool Returns false on failure, True on success. 765 778 */ 766 function bp_core_ remove_nav_item( $parent_id) {779 function bp_core_delete_nav_item( $slug, $component = 'members' ) { 767 780 $bp = buddypress(); 768 781 769 // Unset subnav items for this nav item. 770 if ( isset( $bp->bp_options_nav[$parent_id] ) && is_array( $bp->bp_options_nav[$parent_id] ) ) { 771 foreach( (array) $bp->bp_options_nav[$parent_id] as $subnav_item ) { 772 bp_core_remove_subnav_item( $parent_id, $subnav_item['slug'] ); 773 } 782 if ( ! isset( $bp->{$component}->nav ) ) { 783 return false; 774 784 } 775 785 776 if ( empty( $bp->bp_nav[ $parent_id ] ) ) 786 $screen_functions = $bp->{$component}->nav->delete_nav( $slug ); 787 788 if ( ! is_array( $screen_functions ) ) { 777 789 return false; 790 } 778 791 779 if ( $function = $bp->bp_nav[$parent_id]['screen_function']) {792 foreach ( $screen_functions as $screen_function ) { 780 793 // Remove our screen hook if screen function is callable. 781 if ( is_callable( $ function ) ) {782 remove_action( 'bp_screens', $ function, 3 );794 if ( is_callable( $screen_function ) ) { 795 remove_action( 'bp_screens', $screen_function, 3 ); 783 796 } 784 797 } 785 798 786 unset( $bp->bp_nav[$parent_id] );799 return true; 787 800 } 788 801 789 802 /** 790 * Remove a subnav item from the navigation array.803 * Deletes an item from the secondary navigation of the specified component. 791 804 * 792 * @since 1.0.0805 * @since 2.6.0 793 806 * 794 * @param string $parent_id The slug of the parent navigation item. 795 * @param string $slug The slug of the subnav item to be removed. 807 * @param string $slug The slug of the secondary item to be removed. 808 * @param string $parent_slug The slug of the primary navigation item. 809 * @param string $component The component the navigation is attached to. Defaults to 'members'. 810 * @return bool Returns false on failure, True on success. 796 811 */ 797 function bp_core_ remove_subnav_item( $parent_id, $slug) {812 function bp_core_delete_subnav_item( $slug, $parent_slug, $component = 'members' ) { 798 813 $bp = buddypress(); 799 814 800 $screen_function = isset( $bp->bp_options_nav[$parent_id][$slug]['screen_function'] )801 ? $bp->bp_options_nav[$parent_id][$slug]['screen_function']802 : false;815 if ( ! isset( $bp->{$component}->nav ) ) { 816 return false; 817 } 803 818 804 if ( ! empty( $screen_function ) ) { 805 // Remove our screen hook if screen function is callable. 806 if ( is_callable( $screen_function ) ) { 807 remove_action( 'bp_screens', $screen_function, 3 ); 808 } 819 $screen_functions = $bp->{$component}->nav->delete_nav( $slug, $parent_slug ); 820 821 if ( ! is_array( $screen_functions ) ) { 822 return false; 809 823 } 810 824 811 unset( $bp->bp_options_nav[$parent_id][$slug] ); 825 $screen_function = reset( $screen_functions ); 826 827 // Remove our screen hook if screen function is callable. 828 if ( is_callable( $screen_function ) ) { 829 remove_action( 'bp_screens', $screen_function, 3 ); 830 } 812 831 813 if ( isset( $bp->bp_options_nav[$parent_id] ) && !count( $bp->bp_options_nav[$parent_id] ) ) 814 unset($bp->bp_options_nav[$parent_id]); 832 return true; 815 833 } 816 834 817 835 /** 818 836 * Clear all subnav items from a specific nav item. 819 837 * 820 838 * @since 1.0.0 839 * @since 2.6.0 Introduced the `$component` parameter. 821 840 * 822 841 * @param string $parent_slug The slug of the parent navigation item. 842 * @param string $component The component the navigation is attached to. Defaults to 'members'. 823 843 */ 824 function bp_core_reset_subnav_items( $parent_slug ) {844 function bp_core_reset_subnav_items( $parent_slug, $component = 'members' ) { 825 845 $bp = buddypress(); 826 846 827 unset( $bp->bp_options_nav[$parent_slug] ); 847 if ( ! isset( $bp->{$component}->nav ) ) { 848 return; 849 } 850 851 $subnav_items = $bp->{$component}->nav->get_secondary( array( 'parent_slug' => $parent_slug ), false ); 852 853 if ( ! $subnav_items ) { 854 return; 855 } 856 857 foreach( $subnav_items as $subnav_item ) { 858 $bp->{$component}->nav->delete_nav( $subnav_item->slug, $parent_slug ); 859 } 828 860 } 829 861 830 862 -
src/bp-core/bp-core-classes.php
diff --git src/bp-core/bp-core-classes.php src/bp-core/bp-core-classes.php index bebf4ed..9d2d377 100644
require dirname( __FILE__ ) . '/classes/class-bp-email-recipient.php'; 30 30 require dirname( __FILE__ ) . '/classes/class-bp-email.php'; 31 31 require dirname( __FILE__ ) . '/classes/class-bp-email-delivery.php'; 32 32 require dirname( __FILE__ ) . '/classes/class-bp-phpmailer.php'; 33 require dirname( __FILE__ ) . '/classes/class-bp-core-nav.php'; 34 require dirname( __FILE__ ) . '/classes/class-bp-core-nav-item.php'; 35 36 if ( buddypress()->do_nav_backcompat ) { 37 require dirname( __FILE__ ) . '/classes/class-bp-core-bp-nav-backcompat.php'; 38 require dirname( __FILE__ ) . '/classes/class-bp-core-bp-options-nav-backcompat.php'; 39 } -
src/bp-core/bp-core-functions.php
diff --git src/bp-core/bp-core-functions.php src/bp-core/bp-core-functions.php index 702d0dd..a489fd4 100644
function bp_nav_menu_get_loggedin_pages() { 2443 2443 return buddypress()->wp_nav_menu_items->loggedin; 2444 2444 } 2445 2445 2446 // Pull up a list of items registered in BP's top-level nav array. 2447 $bp_menu_items = buddypress()->bp_nav; 2448 2449 // Alphabetize. 2450 $bp_menu_items = bp_alpha_sort_by_key( $bp_menu_items, 'name' ); 2446 // Pull up a list of items registered in BP's primary nav for the member. 2447 $bp_menu_items = buddypress()->members->nav->get_primary(); 2451 2448 2452 2449 // Some BP nav menu items will not be represented in bp_nav, because 2453 2450 // they are not real BP components. We add them manually here. … … function bp_nav_menu_get_loggedin_pages() { 2478 2475 'post_type' => 'page', 2479 2476 'post_status' => 'publish', 2480 2477 'comment_status' => 'closed', 2481 'guid' => $bp_item['link'] 2478 'guid' => $bp_item['link'], 2482 2479 ); 2483 2480 } 2484 2481 … … function bp_nav_menu_get_loggedout_pages() { 2575 2572 * @since 1.9.0 2576 2573 * 2577 2574 * @param string $slug The slug of the nav item: login, register, or one of the 2578 * slugs from buddypress()->bp_nav.2575 * slugs from the members navigation. 2579 2576 * @return string $nav_item_url The URL generated for the current user. 2580 2577 */ 2581 2578 function bp_nav_menu_get_item_url( $slug ) { -
src/bp-core/bp-core-template.php
diff --git src/bp-core/bp-core-template.php src/bp-core/bp-core-template.php index 1f2c5e9..abfb275 100644
defined( 'ABSPATH' ) || exit; 13 13 /** 14 14 * Output the "options nav", the secondary-level single item navigation menu. 15 15 * 16 * Uses the $bp->bp_options_nav global to render out the sub navigation for the16 * Uses the component's nav global to render out the sub navigation for the 17 17 * current component. Each component adds to its sub navigation array within 18 18 * its own setup_nav() function. 19 19 * … … function bp_get_options_nav( $parent_slug = '' ) { 40 40 $component_index = !empty( $bp->displayed_user ) ? bp_current_component() : bp_get_root_slug( bp_current_component() ); 41 41 $selected_item = bp_current_action(); 42 42 43 // Default to the Members nav. 43 44 if ( ! bp_is_single_item() ) { 44 if ( !isset( $bp->bp_options_nav[$component_index] ) || count( $bp->bp_options_nav[$component_index] ) < 1 ) { 45 // Set the parent slug, if not provided. 46 if ( empty( $parent_slug ) ) { 47 $parent_slug = $component_index; 48 } 49 50 $secondary_nav_items = $bp->members->nav->get_secondary( array( 'parent_slug' => $parent_slug ) ); 51 52 if ( ! $secondary_nav_items ) { 45 53 return false; 46 } else {47 $the_index = $component_index;48 54 } 55 56 // For a single item, try to use the component's nav. 49 57 } else { 50 58 $current_item = bp_current_item(); 59 $single_item_component = bp_current_component(); 51 60 61 // Adjust the selected nav item for the current single item if needed. 52 62 if ( ! empty( $parent_slug ) ) { 53 63 $current_item = $parent_slug; 54 64 $selected_item = bp_action_variable( 0 ); 55 65 } 56 66 57 if ( !isset( $bp->bp_options_nav[$current_item] ) || count( $bp->bp_options_nav[$current_item] ) < 1 ) { 58 return false; 67 // If the nav is not defined by the parent component, look in the Members nav. 68 if ( ! isset( $bp->{$single_item_component}->nav ) ) { 69 $secondary_nav_items = $bp->members->nav->get_secondary( array( 'parent_slug' => $current_item ) ); 59 70 } else { 60 $the_index = $current_item; 71 $secondary_nav_items = $bp->{$single_item_component}->nav->get_secondary( array( 'parent_slug' => $current_item ) ); 72 } 73 74 if ( ! $secondary_nav_items ) { 75 return false; 61 76 } 62 77 } 63 78 64 79 // Loop through each navigation item. 65 foreach ( (array) $bp->bp_options_nav[$the_index]as $subnav_item ) {66 if ( empty( $subnav_item ['user_has_access']) ) {80 foreach ( $secondary_nav_items as $subnav_item ) { 81 if ( empty( $subnav_item->user_has_access ) ) { 67 82 continue; 68 83 } 69 84 70 85 // If the current action or an action variable matches the nav item id, then add a highlight CSS class. 71 if ( $subnav_item ['slug']== $selected_item ) {86 if ( $subnav_item->slug === $selected_item ) { 72 87 $selected = ' class="current selected"'; 73 88 } else { 74 89 $selected = ''; … … function bp_get_options_nav( $parent_slug = '' ) { 88 103 * @param array $subnav_item Submenu array item being displayed. 89 104 * @param string $selected_item Current action. 90 105 */ 91 echo apply_filters( 'bp_get_options_nav_' . $subnav_item ['css_id'], '<li id="' . esc_attr( $subnav_item['css_id'] . '-' . $list_type . '-li' ) . '" ' . $selected . '><a id="' . esc_attr( $subnav_item['css_id'] ) . '" href="' . esc_url( $subnav_item['link'] ) . '">' . $subnav_item['name']. '</a></li>', $subnav_item, $selected_item );106 echo apply_filters( 'bp_get_options_nav_' . $subnav_item->css_id, '<li id="' . esc_attr( $subnav_item->css_id . '-' . $list_type . '-li' ) . '" ' . $selected . '><a id="' . esc_attr( $subnav_item->css_id ) . '" href="' . esc_url( $subnav_item->link ) . '">' . $subnav_item->name . '</a></li>', $subnav_item, $selected_item ); 92 107 } 93 108 } 94 109 … … function bp_get_title_parts( $seplocation = 'right' ) { 3010 3025 // Set empty subnav name. 3011 3026 $component_subnav_name = ''; 3012 3027 3028 if ( ! empty( $bp->members->nav ) ) { 3029 $primary_nav_item = $bp->members->nav->get_primary( array( 'slug' => $component_id ), false ); 3030 $primary_nav_item = reset( $primary_nav_item ); 3031 } 3032 3013 3033 // Use the component nav name. 3014 if ( ! empty( $ bp->bp_nav[$component_id]) ) {3015 $component_name = _bp_strip_spans_from_title( $ bp->bp_nav[ $component_id ]['name']);3034 if ( ! empty( $primary_nav_item->name ) ) { 3035 $component_name = _bp_strip_spans_from_title( $primary_nav_item->name ); 3016 3036 3017 3037 // Fall back on the component ID. 3018 3038 } elseif ( ! empty( $bp->{$component_id}->id ) ) { 3019 3039 $component_name = ucwords( $bp->{$component_id}->id ); 3020 3040 } 3021 3041 3022 // Append action name if we're on a member component sub-page. 3023 if ( ! empty( $bp->bp_options_nav[ $component_id ] ) && ! empty( $bp->canonical_stack['action'] ) ) { 3024 $component_subnav_name = wp_filter_object_list( $bp->bp_options_nav[ $component_id ], array( 'slug' => bp_current_action() ), 'and', 'name' ); 3042 if ( ! empty( $bp->members->nav ) ) { 3043 $secondary_nav_item = $bp->members->nav->get_secondary( array( 3044 'parent_slug' => $component_id, 3045 'slug' => bp_current_action() 3046 ), false ); 3025 3047 3026 if ( ! empty( $component_subnav_name )) {3027 $ component_subnav_name = array_shift( $component_subnav_name);3048 if ( $secondary_nav_item ) { 3049 $secondary_nav_item = reset( $secondary_nav_item ); 3028 3050 } 3029 3051 } 3030 3052 3053 // Append action name if we're on a member component sub-page. 3054 if ( ! empty( $secondary_nav_item->name ) && ! empty( $bp->canonical_stack['action'] ) ) { 3055 $component_subnav_name = $secondary_nav_item->name; 3056 } 3057 3031 3058 // If on the user profile's landing page, just use the fullname. 3032 3059 if ( bp_is_current_component( $bp->default_component ) && ( bp_get_requested_url() === bp_displayed_user_domain() ) ) { 3033 3060 $bp_title_parts[] = $displayed_user_name; … … function bp_get_title_parts( $seplocation = 'right' ) { 3045 3072 } 3046 3073 } 3047 3074 3048 // A single group. 3049 } elseif ( bp_is_active( 'groups' ) && ! empty( $bp->groups->current_group ) && ! empty( $bp->bp_options_nav[ $bp->groups->current_group->slug ] ) ) { 3050 $subnav = isset( $bp->bp_options_nav[ $bp->groups->current_group->slug ][ bp_current_action() ]['name'] ) ? $bp->bp_options_nav[ $bp->groups->current_group->slug ][ bp_current_action() ]['name'] : ''; 3051 $bp_title_parts = array( $bp->bp_options_title, $subnav ); 3052 3053 // A single item from a component other than groups. 3075 // A single item from a component other than Members. 3054 3076 } elseif ( bp_is_single_item() ) { 3055 $bp_title_parts = array( $bp->bp_options_title, $bp->bp_options_nav[ bp_current_item() ][ bp_current_action() ]['name'] ); 3077 $component_id = bp_current_component(); 3078 3079 if ( ! empty( $bp->{$component_id}->nav ) ) { 3080 $secondary_nav_item = $bp->{$component_id}->nav->get_secondary( array( 3081 'parent_slug' => bp_current_item(), 3082 'slug' => bp_current_action() 3083 ), false ); 3084 3085 if ( $secondary_nav_item ) { 3086 $secondary_nav_item = reset( $secondary_nav_item ); 3087 } 3088 } 3089 3090 $single_item_subnav = ''; 3091 3092 if ( ! empty( $secondary_nav_item->name ) ) { 3093 $single_item_subnav = $secondary_nav_item->name; 3094 } 3095 3096 $bp_title_parts = array( $bp->bp_options_title, $single_item_subnav ); 3056 3097 3057 3098 // An index or directory. 3058 3099 } elseif ( bp_is_directory() ) { … … function _bp_nav_menu_sort( $a, $b ) { 3428 3469 * Get the items registered in the primary and secondary BuddyPress navigation menus. 3429 3470 * 3430 3471 * @since 1.7.0 3472 * @since 2.6.0 Introduced the `$component` parameter. 3431 3473 * 3474 * @param string $component Optional. Component whose nav items are being fetched. 3432 3475 * @return array A multidimensional array of all navigation items. 3433 3476 */ 3434 function bp_get_nav_menu_items() { 3435 $menus = $selected_menus = array(); 3436 3437 // Get the second level menus. 3438 foreach ( (array) buddypress()->bp_options_nav as $parent_menu => $sub_menus ) { 3439 3440 // The root menu's ID is "xprofile", but the Profile submenus are using "profile". See BP_Core::setup_nav(). 3441 if ( 'profile' === $parent_menu ) { 3442 $parent_menu = 'xprofile'; 3443 } 3444 3445 // Sort the items in this menu's navigation by their position property. 3446 $second_level_menus = (array) $sub_menus; 3447 usort( $second_level_menus, '_bp_nav_menu_sort' ); 3448 3449 // Iterate through the second level menus. 3450 foreach( $second_level_menus as $sub_nav ) { 3451 3452 // Skip items we don't have access to. 3453 if ( empty( $sub_nav['user_has_access'] ) ) { 3454 continue; 3455 } 3456 3457 // Add this menu. 3458 $menu = new stdClass; 3459 $menu->class = array( 'menu-child' ); 3460 $menu->css_id = $sub_nav['css_id']; 3461 $menu->link = $sub_nav['link']; 3462 $menu->name = $sub_nav['name']; 3463 $menu->parent = $parent_menu; // Associate this sub nav with a top-level menu. 3464 3465 // If we're viewing this item's screen, record that we need to mark its parent menu to be selected. 3466 if ( $sub_nav['slug'] == bp_current_action() ) { 3467 $menu->class[] = 'current-menu-item'; 3468 $selected_menus[] = $parent_menu; 3469 } 3477 function bp_get_nav_menu_items( $component = 'members' ) { 3478 $bp = buddypress(); 3479 $menus = array(); 3470 3480 3471 $menus[] = $menu;3472 }3481 if ( ! isset( $bp->{$component}->nav ) ) { 3482 return $menus; 3473 3483 } 3474 3484 3475 // Get the top-level menu parts (Friends, Groups, etc) and sort by their position property. 3476 $top_level_menus = (array) buddypress()->bp_nav; 3477 usort( $top_level_menus, '_bp_nav_menu_sort' ); 3478 3479 // Iterate through the top-level menus. 3480 foreach ( $top_level_menus as $nav ) { 3481 3482 // Skip items marked as user-specific if you're not on your own profile. 3483 if ( empty( $nav['show_for_displayed_user'] ) && ! bp_core_can_edit_settings() ) { 3484 continue; 3485 } 3486 3485 // Get the item nav and build the menus. 3486 foreach ( $bp->{$component}->nav->get_item_nav() as $nav_menu ) { 3487 3487 // Get the correct menu link. See https://buddypress.trac.wordpress.org/ticket/4624. 3488 $link = bp_loggedin_user_domain() ? str_replace( bp_loggedin_user_domain(), bp_displayed_user_domain(), $nav ['link'] ) : trailingslashit( bp_displayed_user_domain() . $nav['link']);3488 $link = bp_loggedin_user_domain() ? str_replace( bp_loggedin_user_domain(), bp_displayed_user_domain(), $nav_menu->link ) : trailingslashit( bp_displayed_user_domain() . $nav_menu->link ); 3489 3489 3490 3490 // Add this menu. 3491 3491 $menu = new stdClass; 3492 3492 $menu->class = array( 'menu-parent' ); 3493 $menu->css_id = $nav ['css_id'];3494 $menu->link = $ link;3495 $menu->name = $nav ['name'];3493 $menu->css_id = $nav_menu->css_id; 3494 $menu->link = $nav_menu->link; 3495 $menu->name = $nav_menu->name; 3496 3496 $menu->parent = 0; 3497 3497 3498 // Check if we need to mark this menu as selected. 3499 if ( in_array( $nav['css_id'], $selected_menus ) ) { 3500 $menu->class[] = 'current-menu-parent'; 3498 if ( ! empty( $nav_menu->children ) ) { 3499 $submenus = array(); 3500 3501 foreach( $nav_menu->children as $sub_menu ) { 3502 $submenu = new stdClass; 3503 $submenu->class = array( 'menu-child' ); 3504 $submenu->css_id = $sub_menu->css_id; 3505 $submenu->link = $sub_menu->link; 3506 $submenu->name = $sub_menu->name; 3507 $submenu->parent = $nav_menu->slug; 3508 3509 // If we're viewing this item's screen, record that we need to mark its parent menu to be selected. 3510 if ( $sub_menu->slug == bp_current_action() ) { 3511 $menu->class[] = 'current-menu-parent'; 3512 $submenu->class[] = 'current-menu-item'; 3513 } 3514 3515 $submenus[] = $submenu; 3516 } 3501 3517 } 3502 3518 3503 3519 $menus[] = $menu; 3520 3521 if ( ! empty( $submenus ) ) { 3522 $menus = array_merge( $menus, $submenus ); 3523 } 3504 3524 } 3505 3525 3506 3526 /** -
src/bp-core/classes/class-bp-component.php
diff --git src/bp-core/classes/class-bp-component.php src/bp-core/classes/class-bp-component.php index 8a53680..d9096dd 100644
class BP_Component { 489 489 490 490 // No sub nav items without a main nav item. 491 491 if ( !empty( $main_nav ) ) { 492 bp_core_new_nav_item( $main_nav );492 bp_core_new_nav_item( $main_nav, 'members' ); 493 493 494 494 // Sub nav items are not required. 495 495 if ( !empty( $sub_nav ) ) { 496 496 foreach( (array) $sub_nav as $nav ) { 497 bp_core_new_subnav_item( $nav );497 bp_core_new_subnav_item( $nav, 'members' ); 498 498 } 499 499 } 500 500 } -
new file src/bp-core/classes/class-bp-core-bp-nav-backcompat.php
diff --git src/bp-core/classes/class-bp-core-bp-nav-backcompat.php src/bp-core/classes/class-bp-core-bp-nav-backcompat.php new file mode 100644 index 0000000..cf39fe5
- + 1 <?php 2 /** 3 * Backward compatibility for the $bp->bp_nav global. 4 * 5 * @since 2.6.0 6 */ 7 8 // Exit if accessed directly. 9 defined( 'ABSPATH' ) || exit; 10 11 /** 12 * bp_nav backward compatibility class. 13 * 14 * This class is used to provide backward compatibility for extensions that access and modify 15 * the $bp->bp_nav global. 16 * 17 * @since 2.6.0 18 */ 19 class BP_Core_BP_Nav_BackCompat implements ArrayAccess { 20 /** 21 * Nav items. 22 * 23 * @since 2.6.0 24 * @access public 25 * @var array 26 */ 27 public $backcompat_nav = array(); 28 29 /** 30 * Component to which nav items belong. 31 * 32 * @since 2.6.0 33 * @access public 34 * @var array 35 */ 36 public $component; 37 38 /** 39 * Constructor. 40 * 41 * @since 2.6.0 42 * 43 * @param array $backcompat_nav Optional. Array of nav items. 44 */ 45 public function __construct( $backcompat_nav = array() ) { 46 foreach ( $backcompat_nav as $key => $value ) { 47 if ( is_array( $value ) ) { 48 $this->backcompat_nav[ $key ] = new self( $value ); 49 } else { 50 $this->backcompat_nav[ $key ] = $value; 51 } 52 } 53 } 54 55 /** 56 * Assign a value to the nav array at the specified offset. 57 * 58 * @since 2.6.0 59 * 60 * @param mixed $offset Array offset. 61 * @param array $value Nav item. 62 */ 63 public function offsetSet( $offset, $value ) { 64 _doing_it_wrong( 65 'bp_nav', 66 __( 'The bp_nav and bp_options_nav globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'buddypress' ), 67 '2.6.0' 68 ); 69 70 $bp = buddypress(); 71 72 if ( is_array( $value ) ) { 73 $value = new self( $value ); 74 } 75 76 if ( $offset !== null ) { 77 // Temporarily set the backcompat_nav. 78 $this->backcompat_nav[ $offset ] = $value; 79 80 $args = $this->to_array(); 81 if ( isset( $args['parent_slug'] ) ) { 82 $this->get_component_nav( $args['parent_slug'] )->edit_nav( $args, $args['slug'], $args['parent_slug'] ); 83 } elseif ( isset( $args['slug'] ) ) { 84 $bp->members->nav->edit_nav( $args, $args['slug'] ); 85 } 86 } 87 } 88 89 /** 90 * Get a value of the nav array at the specified offset. 91 * 92 * @since 2.6.0 93 * 94 * @param mixed $offset Array offset. 95 * @return BP_Core_BP_Nav_BackCompat 96 */ 97 public function offsetGet( $offset ) { 98 _doing_it_wrong( 99 'bp_nav', 100 __( 'The bp_nav and bp_options_nav globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'buddypress' ), 101 '2.6.0' 102 ); 103 104 if ( ! isset( $this->backcompat_nav[ $offset ] ) ) { 105 $nav = $this->get_nav( $offset ); 106 if ( $nav && isset( $nav[ $offset ] ) ) { 107 $this->backcompat_nav[ $offset ] = new self( $nav[ $offset ] ); 108 } 109 } 110 111 return $this->backcompat_nav[ $offset ]; 112 } 113 114 /** 115 * Check whether nav array has a value at the specified offset. 116 * 117 * @since 2.6.0 118 * 119 * @param mixed $offset Array offset. 120 * @return bool 121 */ 122 public function offsetExists( $offset ) { 123 _doing_it_wrong( 124 'bp_nav', 125 __( 'The bp_nav and bp_options_nav globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'buddypress' ), 126 '2.6.0' 127 ); 128 129 if ( isset( $this->backcompat_nav[ $offset ] ) ) { 130 return true; 131 } 132 133 $nav = $this->get_nav( $offset ); 134 if ( $nav && isset( $nav[ $offset ] ) ) { 135 return true; 136 } 137 138 return false; 139 } 140 141 /** 142 * Unset a nav array value at the specified offset. 143 * 144 * @since 2.6.0 145 * 146 * @param mixed $offset Array offset. 147 */ 148 public function offsetUnset( $offset ) { 149 _doing_it_wrong( 150 'bp_nav', 151 __( 'The bp_nav and bp_options_nav globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'buddypress' ), 152 '2.6.0' 153 ); 154 155 // For top-level nav items, the backcompat nav hasn't yet been initialized. 156 if ( ! isset( $this->backcompat_nav[ $offset ] ) ) { 157 buddypress()->members->nav->delete_nav( $offset ); 158 unset( $this->backcompat_nav[ $offset ] ); 159 } 160 } 161 162 /** 163 * Set the component to which the nav belongs. 164 * 165 * @since 2.6.0 166 * 167 * @param string $component 168 */ 169 public function set_component( $component ) { 170 $this->component = $component; 171 } 172 173 /** 174 * Get the component to which the a nav item belongs. 175 * 176 * We use the following heuristic to guess, based on an offset, which component the item belongs to: 177 * - If this is a group, and the offset is the same as the current group's slug, it's a group nav item. 178 * - Otherwise, it's a member nav item. 179 * 180 * @since 2.6.0 181 * 182 * @param mixed $offset Array offset. 183 * @return string 184 */ 185 public function get_component( $offset = '' ) { 186 if ( ! isset( $this->component ) ) { 187 if ( bp_is_active( 'groups' ) && $offset === bp_get_current_group_slug() ) { 188 $this->component = 'groups'; 189 } else { 190 $this->component = 'members'; 191 } 192 } 193 194 return $this->component; 195 } 196 197 /** 198 * Get the nav object corresponding to the specified offset. 199 * 200 * @since 2.6.0 201 * 202 * @param mixed $offset Array offset. 203 * @return bool|array 204 */ 205 protected function get_nav( $offset ) { 206 $bp = buddypress(); 207 208 $component_nav = $this->get_component_nav( $offset ); 209 $primary_nav = $component_nav->get_primary( array( 'slug' => $offset ), false ); 210 211 $nav = array(); 212 213 if ( empty( $primary_nav ) ) { 214 return $nav; 215 } 216 217 foreach ( $primary_nav as $item ) { 218 $nav[ $item->slug ] = (array) $item; 219 } 220 221 return $nav; 222 } 223 224 /** 225 * Get the BP_Core_Nav object corresponding to the component, based on a nav item name. 226 * 227 * The way bp_nav was previously organized makes it impossible to know for sure which component's nav is 228 * being referenced by a given nav item name. We guess in the following manner: 229 * - If we're looking at a group, and the nav item name (`$offset`) is the same as the slug of the current 230 * group, we assume that the proper component nav is 'groups'. 231 * - Otherwise, fall back on 'members'. 232 * 233 * @since 2.6.0 234 * 235 * @param string $offset Nav item name. 236 * @return BP_Core_Nav 237 */ 238 protected function get_component_nav( $offset = '' ) { 239 $component = $this->get_component( $offset ); 240 241 $bp = buddypress(); 242 if ( ! isset( $bp->{$component}->nav ) ) { 243 return false; 244 } 245 246 return $bp->{$component}->nav; 247 } 248 249 /** 250 * Get the nav data, formatted as a flat array. 251 * 252 * @since 2.6.0 253 * 254 * @return array 255 */ 256 protected function to_array() { 257 return $this->backcompat_nav; 258 } 259 } -
new file src/bp-core/classes/class-bp-core-bp-options-nav-backcompat.php
diff --git src/bp-core/classes/class-bp-core-bp-options-nav-backcompat.php src/bp-core/classes/class-bp-core-bp-options-nav-backcompat.php new file mode 100644 index 0000000..a91eb44
- + 1 <?php 2 /** 3 * Backward compatibility for the $bp->bp_options_nav global. 4 * 5 * @since 2.6.0 6 */ 7 8 // Exit if accessed directly. 9 defined( 'ABSPATH' ) || exit; 10 11 /** 12 * bp_options_nav backward compatibility class. 13 * 14 * This class is used to provide backward compatibility for extensions that access and modify 15 * the $bp->bp_options_nav global. 16 * 17 * @since 2.6.0 18 */ 19 class BP_Core_BP_Options_Nav_BackCompat extends BP_Core_BP_Nav_BackCompat { 20 /** 21 * Parent slug of the current nav item. 22 * 23 * @since 2.6.0 24 * @access protected 25 * @var string 26 */ 27 protected $parent_slug = ''; 28 29 /** 30 * Get a value of the nav array at the specified offset. 31 * 32 * @since 2.6.0 33 * 34 * @param mixed $offset Array offset. 35 * @return BP_Core_BP_Nav_BackCompat 36 */ 37 public function offsetGet( $offset ) { 38 _doing_it_wrong( 39 'bp_nav', 40 __( 'These globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'buddypress' ), 41 '2.6.0' 42 ); 43 44 if ( empty( $this->backcompat_nav[ $offset ] ) ) { 45 $nav = $this->get_nav( $offset ); 46 if ( $nav ) { 47 $subnavs = $this->get_component_nav( $offset )->get_secondary( array( 'parent_slug' => $offset ) ); 48 $subnav_keyed = array(); 49 foreach ( $subnavs as $subnav ) { 50 $subnav_keyed[ $subnav->slug ] = (array) $subnav; 51 } 52 53 $subnav_object = new self( $subnav_keyed ); 54 $subnav_object->set_component( $this->get_component() ); 55 $subnav_object->set_parent_slug( $offset ); 56 57 $this->backcompat_nav[ $offset ] = $subnav_object; 58 } 59 } 60 61 return $this->backcompat_nav[ $offset ]; 62 } 63 64 /** 65 * Unset a nav array value at the specified offset. 66 * 67 * @since 2.6.0 68 * 69 * @param mixed $offset Array offset. 70 */ 71 public function offsetUnset( $offset ) { 72 _doing_it_wrong( 73 'bp_nav', 74 __( 'These globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'buddypress' ), 75 '2.6.0' 76 ); 77 78 $this->get_component_nav( $offset )->delete_nav( $offset, $this->get_parent_slug() ); 79 80 // Clear the cached nav. 81 unset( $this->backcompat_nav[ $offset ] ); 82 } 83 84 /** 85 * Get the parent slug of the current nav item. 86 * 87 * @since 2.6.0 88 * 89 * @return string 90 */ 91 public function get_parent_slug() { 92 return $this->parent_slug; 93 } 94 95 /** 96 * Set the parent slug of the current nav item. 97 * 98 * @since 2.6.0 99 */ 100 public function set_parent_slug( $slug ) { 101 $this->parent_slug = $slug; 102 } 103 104 /** 105 * Get the nav object corresponding to the specified offset. 106 * 107 * @since 2.6.0 108 * 109 * @param mixed $offset Array offset. 110 * @return bool|array 111 */ 112 public function get_nav( $offset ) { 113 $nav = parent::get_nav( $offset ); 114 115 if ( ! $nav ) { 116 $component_nav = $this->get_component_nav( $offset ); 117 $secondary_nav = $component_nav->get_secondary( array( 'slug' => $offset ), false ); 118 119 $nav = array(); 120 121 if ( empty( $primary_nav ) ) { 122 return $nav; 123 } 124 125 foreach ( $primary_nav as $item ) { 126 $nav[ $item->slug ] = (array) $item; 127 } 128 } 129 130 return $nav; 131 } 132 } -
new file src/bp-core/classes/class-bp-core-nav-item.php
diff --git src/bp-core/classes/class-bp-core-nav-item.php src/bp-core/classes/class-bp-core-nav-item.php new file mode 100644 index 0000000..8b901b3
- + 1 <?php 2 3 // Exit if accessed directly. 4 defined( 'ABSPATH' ) || exit; 5 6 if ( class_exists( 'ArrayObject' ) ) : 7 8 /** 9 * Navigation item. 10 * 11 * @since 2.6.0 12 */ 13 class BP_Core_Nav_Item extends ArrayObject { 14 public function __construct( $data ) { 15 parent::__construct( $data, ArrayObject::ARRAY_AS_PROPS ); 16 } 17 } 18 19 else : 20 21 /** 22 * Navigation item. 23 * 24 * @since 2.6.0 25 */ 26 class BP_Core_Nav_Item { 27 public function __construct( $data ) { 28 foreach ( $data as $key => $value ) { 29 $this->key = $value; 30 } 31 } 32 } 33 34 endif; -
new file src/bp-core/classes/class-bp-core-nav.php
diff --git src/bp-core/classes/class-bp-core-nav.php src/bp-core/classes/class-bp-core-nav.php new file mode 100644 index 0000000..a13fec8
- + 1 <?php 2 /** 3 * Core component class. 4 * 5 * @package BuddyPress 6 * @subpackage Core 7 * @since 2.6.0 8 */ 9 10 // Exit if accessed directly. 11 defined( 'ABSPATH' ) || exit; 12 13 /** 14 * BuddyPress Nav. 15 * 16 * This class is used to build each component's navigation. 17 * 18 * @since 2.6.0 19 */ 20 class BP_Core_Nav { 21 /** 22 * An associative array containing the nav items for the object ID. 23 * 24 * @since 2.6.0 25 * @var array 26 */ 27 protected $nav; 28 29 /** 30 * The current object ID. 31 * 32 * @since 2.6.0 33 * @var int 34 */ 35 private $object_id; 36 37 /** 38 * Initializes the Nav belonging to the specified object. 39 * 40 * @since 2.6.0 41 * 42 * @param int $object_id The item ID to build the nav for. Default is the displayed user ID. 43 */ 44 public function __construct( $object_id = 0 ) { 45 if ( empty( $object_id ) ) { 46 $this->object_id = (int) bp_displayed_user_id(); 47 } else { 48 $this->object_id = (int) $object_id; 49 } 50 51 $this->nav[ $this->object_id ] = array(); 52 } 53 54 /** 55 * Checks whether a nav item is set. 56 * 57 * @since 2.6.0 58 * 59 * @param string $key The requested nav slug. 60 * @return bool True if the nav item is set, false otherwise. 61 */ 62 public function __isset( $key ) { 63 return isset( $this->nav[ $this->object_id ][ $key ] ); 64 } 65 66 /** 67 * Gets a nav item. 68 * 69 * @since 2.6.0 70 * 71 * @param string $key The requested nav slug. 72 * @return mixed The value corresponding to the requested nav item. 73 */ 74 public function __get( $key ) { 75 if ( ! isset( $this->nav[ $this->object_id ][ $key ] ) ) { 76 $this->nav[ $this->object_id ][ $key ] = null; 77 } 78 79 return $this->nav[ $this->object_id ][ $key ]; 80 } 81 82 /** 83 * Sets a nav item. 84 * 85 * @since 2.6.0 86 * 87 * @param string $key The requested nav slug. 88 * @param mixed $value The value of the nav item. 89 */ 90 public function __set( $key, $value ) { 91 if ( is_array( $value ) ) { 92 $value['primary'] = true; 93 } 94 95 $this->nav[ $this->object_id ][ $key ] = new BP_Core_Nav_Item( $value ); 96 } 97 98 /** 99 * Gets a specific nav item or array of nav items. 100 * 101 * @since 2.6.0 102 * 103 * @param string $key The nav item slug to get. Optional. 104 * @return mixed An array of nav item, a single nav item, or null if none found. 105 */ 106 public function get( $key = '' ) { 107 $return = null; 108 109 // Return the requested nav item. 110 if ( ! empty( $key ) ) { 111 if ( ! isset( $this->nav[ $this->object_id ][ $key ] ) ) { 112 $return = null; 113 } else { 114 $return = $this->nav[ $this->object_id ][ $key ]; 115 } 116 117 // Return all nav item items. 118 } else { 119 $return = $this->nav[ $this->object_id ]; 120 } 121 122 return $return; 123 } 124 125 /** 126 * Adds a new nav item. 127 * 128 * @since 2.6.0 129 * 130 * @param array $args The nav item's arguments. 131 * @return BP_Core_Nav_Item 132 */ 133 public function add_nav( $args ) { 134 if ( empty( $args['slug'] ) ) { 135 return false; 136 } 137 138 // We have a child and the parent exists. 139 if ( ! empty( $args['parent_slug'] ) ) { 140 $slug = $args['parent_slug'] . '/' . $args['slug']; 141 $args['secondary'] = true; 142 143 // This is a parent. 144 } else { 145 $slug = $args['slug']; 146 $args['primary'] = true; 147 } 148 149 // Add to the nav. 150 $this->nav[ $this->object_id ][ $slug ] = new BP_Core_Nav_Item( $args ); 151 152 return $this->nav[ $this->object_id ][ $slug ]; 153 } 154 155 /** 156 * Edits a nav item. 157 * 158 * @since 2.6.0 159 * 160 * @param array $args The nav item's arguments. 161 * @param string $slug The slug of the nav item. 162 * @param string $parent_slug The slug of the parent nav item (required to edit a child). 163 * @return BP_Core_Nav_Item 164 */ 165 public function edit_nav( $args = array(), $slug = '', $parent_slug = '' ) { 166 if ( empty( $slug ) ) { 167 return false; 168 } 169 170 // We're editing a parent! 171 if ( empty( $parent_slug ) ) { 172 $nav_items = $this->get_primary( array( 'slug' => $slug ), false ); 173 174 if ( ! $nav_items ) { 175 return false; 176 } 177 178 $nav_item = reset( $nav_items ); 179 $this->nav[ $this->object_id ][ $slug ] = new BP_Core_Nav_Item( wp_parse_args( $args, (array) $nav_item ) ); 180 181 // Return the edited object. 182 return $this->nav[ $this->object_id ][ $slug ]; 183 184 // We're editing a child. 185 } else { 186 $sub_items = $this->get_secondary( array( 'parent_slug' => $parent_slug, 'slug' => $slug ), false ); 187 188 if ( ! $sub_items ) { 189 return false; 190 } 191 192 $sub_item = reset( $sub_items ); 193 194 $params = wp_parse_args( $args, (array) $sub_item ); 195 196 // When we have parents, it's for life, we can't change them! 197 if ( empty( $params['parent_slug'] ) || $parent_slug !== $params['parent_slug'] ) { 198 return false; 199 } 200 201 $this->nav[ $this->object_id ][ $parent_slug . '/' . $slug ] = new BP_Core_Nav_Item( $params ); 202 203 // Return the edited object. 204 return $this->nav[ $this->object_id ][ $parent_slug . '/' . $slug ]; 205 } 206 } 207 208 /** 209 * Unset an item or a subitem of the nav. 210 * 211 * @since 2.6.0 212 * 213 * @param string $key The slug of the main item. 214 * @param string $sub_key The slug of the sub item. 215 * @return bool|callable|array False on failure, the screen function(s) on success. 216 */ 217 public function delete_nav( $slug, $parent_slug = '' ) { 218 if ( empty( $slug ) ) { 219 return false; 220 } 221 222 // We're deleting a child 223 if ( ! empty( $parent_slug ) ) { 224 225 // Validate the subnav 226 $sub_items = $this->get_secondary( array( 'parent_slug' => $parent_slug, 'slug' => $slug ), false ); 227 228 if ( ! $sub_items ) { 229 return false; 230 } 231 232 $sub_item = reset( $sub_items ); 233 234 if ( empty( $sub_item->slug ) ) { 235 return false; 236 } 237 238 // Delete the child 239 unset( $this->nav[ $this->object_id ][ $parent_slug . '/' . $slug ] ); 240 241 // Return the deleted item's screen function 242 return array( $sub_item->screen_function ); 243 244 // We're deleting a parent 245 } else { 246 // Validate the nav 247 $nav_items = $this->get_primary( array( 'slug' => $slug ), false ); 248 249 if ( ! $nav_items ) { 250 return false; 251 } 252 253 $nav_item = reset( $nav_items ); 254 255 if ( empty( $nav_item->slug ) ) { 256 return false; 257 } 258 259 $screen_functions = array( $nav_item->screen_function ); 260 261 // Life's unfair, children won't survive the parent :( 262 $sub_items = $this->get_secondary( array( 'parent_slug' => $nav_item->slug ), false ); 263 264 if ( ! empty( $sub_items ) ) { 265 foreach ( $sub_items as $sub_item ) { 266 $screen_functions[] = $sub_item->screen_function; 267 268 // Delete the child 269 unset( $this->nav[ $this->object_id ][ $nav_item->slug . '/' . $sub_item->slug ] ); 270 } 271 } 272 273 // Delete the parent. 274 unset( $this->nav[ $this->object_id ][ $nav_item->slug ] ); 275 276 // Return the deleted item's screen functions. 277 return array_unique( $screen_functions ); 278 } 279 } 280 281 /** 282 * Sorts a list of nav items. 283 * 284 * @since 2.6.0 285 * 286 * @param array $items The nav items to sort. 287 * @return array 288 */ 289 public function sort_nav( $items ) { 290 $sorted = array(); 291 292 foreach ( $items as $item ) { 293 // Default position 294 $position = 99; 295 296 if ( isset( $item->position ) ) { 297 $position = (int) $item->position; 298 } 299 300 // If position is already taken, move to the first next available 301 if ( isset( $sorted[ $position ] ) ) { 302 $sorted_keys = array_keys( $sorted ); 303 304 do { 305 $position += 1; 306 } while ( in_array( $position, $sorted_keys ) ); 307 } 308 309 $sorted[ $position ] = $item; 310 } 311 312 ksort( $sorted ); 313 return $sorted; 314 } 315 316 /** 317 * Gets the primary nav items. 318 * 319 * @since 2.6.0 320 * 321 * @param array $args Filters to select the specific primary items. See wp_list_filter(). 322 * @param bool $sort True to sort the nav items. False otherwise. 323 * @return array The list of primary objects nav 324 */ 325 public function get_primary( $args = array(), $sort = true ) { 326 $params = wp_parse_args( $args, array( 'primary' => true ) ); 327 328 // This parameter is not overridable 329 if ( empty( $params['primary'] ) ) { 330 return false; 331 } 332 333 $primary_nav = wp_list_filter( $this->nav[ $this->object_id ], $params ); 334 335 if ( ! $primary_nav ) { 336 return false; 337 } 338 339 if ( true !== $sort ) { 340 return $primary_nav; 341 } 342 343 return $this->sort_nav( $primary_nav ); 344 } 345 346 /** 347 * Gets the secondary nav items. 348 * 349 * @since 2.6.0 350 * 351 * @param array $args Filters to select the specific secondary items. See wp_list_filter(). 352 * @param bool $sort True to sort the nav items. False otherwise. 353 * @return array The list of secondary objects nav 354 */ 355 public function get_secondary( $args = array(), $sort = true ) { 356 $params = wp_parse_args( $args, array( 'parent_slug' => '' ) ); 357 358 // No need to search children if the parent is not set 359 if ( empty( $params['parent_slug'] ) && empty( $params['secondary'] ) ) { 360 return false; 361 } 362 363 $secondary_nav = wp_list_filter( $this->nav[ $this->object_id ], $params ); 364 365 if ( ! $secondary_nav ) { 366 return false; 367 } 368 369 if ( true !== $sort ) { 370 return $secondary_nav; 371 } 372 373 return $this->sort_nav( $secondary_nav ); 374 } 375 376 /** 377 * Gets a nested list of visible nav items. 378 * 379 * @since 2.6.0 380 * 381 * @return array The list of visible nav items. 382 */ 383 public function get_item_nav() { 384 $primary_nav_items = $this->get_primary( array( 'show_for_displayed_user' => true ) ); 385 386 if ( $primary_nav_items ) { 387 foreach( $primary_nav_items as $key_nav => $primary_nav ) { 388 // Try to get the children 389 $children = $this->get_secondary( array( 'parent_slug' => $primary_nav->slug, 'user_has_access' => true ) ); 390 391 if ( $children ) { 392 $primary_nav_items[ $key_nav ] = clone( $primary_nav ); 393 $primary_nav_items[ $key_nav ]->children = $children; 394 } 395 } 396 } 397 398 return $primary_nav_items; 399 } 400 } -
src/bp-core/classes/class-bp-core.php
diff --git src/bp-core/classes/class-bp-core.php src/bp-core/classes/class-bp-core.php index 3cdfc0e..e6cc35b 100644
class BP_Core extends BP_Component { 254 254 // bp-notifications instead. 255 255 $bp->core->table_name_notifications = $bp->table_prefix . 'bp_notifications'; 256 256 257 // Backward compatibility for plugins modifying the legacy bp_nav and bp_options_nav global properties. 258 if ( buddypress()->do_nav_backcompat ) { 259 $bp->bp_nav = new BP_Core_BP_Nav_BackCompat(); 260 $bp->bp_options_nav = new BP_Core_BP_Options_Nav_BackCompat(); 261 } 262 257 263 /** 258 264 * Used to determine if user has admin rights on current content. If the 259 265 * logged in user is viewing their own profile and wants to delete -
src/bp-core/deprecated/2.6.php
diff --git src/bp-core/deprecated/2.6.php src/bp-core/deprecated/2.6.php index acc5e23..1b1de5c 100644
function bp_core_print_generation_time() { 21 21 22 22 <?php 23 23 } 24 25 /** 26 * Sort the navigation menu items. 27 * 28 * The sorting is split into a separate function because it can only happen 29 * after all plugins have had a chance to register their navigation items. 30 * 31 * @since 1.0.0 32 * @deprecated 2.6.0 33 * 34 * @return bool|null Returns false on failure. 35 */ 36 function bp_core_sort_nav_items() { 37 _deprecated_function( __FUNCTION__, '2.6' ); 38 } 39 40 /** 41 * Sort all subnavigation arrays. 42 * 43 * @since 1.1.0 44 * @deprecated 2.6.0 45 * 46 * @return bool|null Returns false on failure. 47 */ 48 function bp_core_sort_subnav_items() { 49 _deprecated_function( __FUNCTION__, '2.6' ); 50 } 51 52 /** 53 * Remove a nav item from the navigation array. 54 * 55 * @since 1.0.0 56 * @deprecated 2.6.0 57 * 58 * @param int $parent_id The slug of the parent navigation item. 59 * @return bool Returns false on failure, ie if the nav item can't be found. 60 */ 61 function bp_core_remove_nav_item( $parent_id ) { 62 $bp = buddypress(); 63 64 _deprecated_function( __FUNCTION__, '2.6', 'bp_core_delete_nav_item' ); 65 66 if ( bp_is_active( 'groups' ) && isset( $bp->groups->nav ) ) { 67 68 if ( $bp->groups->nav->get_primary( array( 'slug' => $parent_id ) ) ) { 69 return bp_core_delete_nav_item( $parent_id, 'groups' ); 70 } 71 } 72 73 return bp_core_delete_nav_item( $parent_id ); 74 } 75 76 /** 77 * Remove a subnav item from the navigation array. 78 * 79 * @since 1.0.0 80 * @deprecated 2.6.0 81 * 82 * @param string $parent_id The slug of the parent navigation item. 83 * @param string $slug The slug of the subnav item to be removed. 84 */ 85 function bp_core_remove_subnav_item( $parent_id, $slug ) { 86 $bp = buddypress(); 87 88 _deprecated_function( __FUNCTION__, '2.6', 'bp_core_delete_subnav_item' ); 89 90 if ( bp_is_active( 'groups' ) && isset( $bp->groups->nav ) ) { 91 92 if ( $bp->groups->nav->get_primary( array( 'slug' => $parent_id ) ) ) { 93 return bp_core_delete_subnav_item( $slug, $parent_id, 'groups' ); 94 } 95 } 96 97 return bp_core_delete_subnav_item( $slug, $parent_id ); 98 } -
src/bp-groups/bp-groups-adminbar.php
diff --git src/bp-groups/bp-groups-adminbar.php src/bp-groups/bp-groups-adminbar.php index f27f74e..6cef4b5 100644
function bp_groups_group_admin_menu() { 47 47 ) ); 48 48 49 49 // Index of the Manage tabs parent slug. 50 $ nav_index = $bp->groups->current_group->slug . '_manage';50 $secondary_nav_items = $bp->groups->nav->get_secondary( array( 'parent_slug' => $bp->groups->current_group->slug . '_manage' ) ); 51 51 52 52 // Check if current group has Manage tabs. 53 if ( empty( $bp->bp_options_nav[ $nav_index ] )) {53 if ( ! $secondary_nav_items ) { 54 54 return; 55 55 } 56 56 57 57 // Build the Group Admin menus. 58 foreach ( $ bp->bp_options_nav[ $nav_index ]as $menu ) {58 foreach ( $secondary_nav_items as $menu ) { 59 59 /** 60 60 * Should we add the current manage link in the Group's "Edit" Admin Bar menu ? 61 61 * … … function bp_groups_group_admin_menu() { 63 63 * to also add the link to the "edit screen" of their group component. To do so, set the 64 64 * the 'show_in_admin_bar' argument of your edit screen to true 65 65 */ 66 if ( $menu ['show_in_admin_bar']) {67 $title = sprintf( _x( 'Edit Group %s', 'Group WP Admin Bar manage links', 'buddypress' ), $menu ['name']);66 if ( $menu->show_in_admin_bar ) { 67 $title = sprintf( _x( 'Edit Group %s', 'Group WP Admin Bar manage links', 'buddypress' ), $menu->name ); 68 68 69 69 // Title is specific for delete. 70 if ( 'delete-group' == $menu ['slug']) {71 $title = sprintf( _x( '%s Group', 'Group WP Admin Bar delete link', 'buddypress' ), $menu ['name']);70 if ( 'delete-group' == $menu->slug ) { 71 $title = sprintf( _x( '%s Group', 'Group WP Admin Bar delete link', 'buddypress' ), $menu->name ); 72 72 } 73 73 74 74 $wp_admin_bar->add_menu( array( 75 75 'parent' => $bp->group_admin_menu_id, 76 'id' => $menu ['slug'],76 'id' => $menu->slug, 77 77 'title' => $title, 78 'href' => bp_get_groups_action_link( 'admin/' . $menu ['slug'])78 'href' => bp_get_groups_action_link( 'admin/' . $menu->slug ) 79 79 ) ); 80 80 } 81 81 } -
src/bp-groups/classes/class-bp-group-extension.php
diff --git src/bp-groups/classes/class-bp-group-extension.php src/bp-groups/classes/class-bp-group-extension.php index 5709b0b..c0ae5df 100644
class BP_Group_Extension { 737 737 'screen_function' => array( &$this, '_display_hook' ), 738 738 'user_has_access' => $user_can_see_nav_item, 739 739 'no_access_url' => $group_permalink, 740 ) );740 ), 'groups' ); 741 741 } 742 742 743 743 // If the user can visit the screen, we register it. … … class BP_Group_Extension { 752 752 'screen_function' => array( &$this, '_display_hook' ), 753 753 'user_has_access' => $user_can_visit, 754 754 'no_access_url' => $group_permalink, 755 ) );755 ), 'groups' ); 756 756 757 757 // When we are viewing the extension display page, set the title and options title. 758 758 if ( bp_is_current_action( $this->slug ) ) { … … class BP_Group_Extension { 967 967 } 968 968 969 969 // Add the tab to the manage navigation. 970 bp_core_new_subnav_item( $subnav_args );970 bp_core_new_subnav_item( $subnav_args, 'groups' ); 971 971 972 972 // Catch the edit screen and forward it to the plugin template. 973 973 if ( bp_is_groups_component() && bp_is_current_action( 'admin' ) && bp_is_action_variable( $screen['slug'], 0 ) ) { -
src/bp-groups/classes/class-bp-groups-component.php
diff --git src/bp-groups/classes/class-bp-groups-component.php src/bp-groups/classes/class-bp-groups-component.php index 355ab8c..994a584 100644
class BP_Groups_Component extends BP_Component { 253 253 // Check once if the current group has a custom front template. 254 254 $this->current_group->front_template = bp_groups_get_front_template( $this->current_group ); 255 255 256 // Initialize the nav for the groups component. 257 $this->nav = new BP_Core_Nav( $this->current_group->id ); 258 256 259 // Set current_group to 0 to prevent debug errors. 257 260 } else { 258 261 $this->current_group = 0; … … class BP_Groups_Component extends BP_Component { 496 499 // Reset sub nav. 497 500 $sub_nav = array(); 498 501 499 // Add 'Groups' to the main navigation. 500 $main_nav = array( 502 bp_core_new_nav_item( array( 501 503 'name' => __( 'Memberships', 'buddypress' ), 502 504 'slug' => $this->current_group->slug, 503 505 'position' => -1, // Do not show in BuddyBar. 504 506 'screen_function' => 'groups_screen_group_home', 505 507 'default_subnav_slug' => $this->default_extension, 506 508 'item_css_id' => $this->id 507 ) ;509 ), 'groups' ); 508 510 509 511 $group_link = bp_get_group_permalink( $this->current_group ); 510 512 … … class BP_Groups_Component extends BP_Component { 675 677 ), $default_params ); 676 678 } 677 679 678 parent::setup_nav( $main_nav, $sub_nav ); 680 foreach ( $sub_nav as $nav ) { 681 bp_core_new_subnav_item( $nav, 'groups' ); 682 } 679 683 } 680 684 681 685 if ( isset( $this->current_group->user_has_access ) ) { -
src/bp-loader.php
diff --git src/bp-loader.php src/bp-loader.php index 4a744c4..f89d7b3 100644
class BuddyPress { 109 109 */ 110 110 public $do_autoload = false; 111 111 112 /** 113 * Whether to load backward compatibility classes for navigation globals. 114 * 115 * @since 2.6.0 116 * @var bool 117 */ 118 public $do_nav_backcompat = false; 119 112 120 /** Option Overload *******************************************************/ 113 121 114 122 /** … … class BuddyPress { 434 442 /** Post types and taxonomies *****************************************/ 435 443 $this->email_post_type = apply_filters( 'bp_email_post_type', 'bp-email' ); 436 444 $this->email_taxonomy_type = apply_filters( 'bp_email_tax_type', 'bp-email-type' ); 445 446 /** Navigation backward compatibility *********************************/ 447 if ( interface_exists( 'ArrayAccess', false ) ) { 448 $this->do_nav_backcompat = true; 449 } 437 450 } 438 451 439 452 /** -
src/bp-members/bp-members-template.php
diff --git src/bp-members/bp-members-template.php src/bp-members/bp-members-template.php index bffd155..038ec06 100644
function bp_get_loggedin_user_nav() { 1290 1290 $bp = buddypress(); 1291 1291 1292 1292 // Loop through each navigation item. 1293 foreach( (array) $bp-> bp_navas $nav_item ) {1293 foreach( (array) $bp->members->nav->get_primary() as $nav_item ) { 1294 1294 1295 1295 $selected = ''; 1296 1296 1297 1297 // If the current component matches the nav item id, then add a highlight CSS class. 1298 if ( !bp_is_directory() && !empty( $bp->active_components[bp_current_component()] ) && $bp->active_components[bp_current_component()] == $nav_item ['css_id']) {1298 if ( !bp_is_directory() && !empty( $bp->active_components[bp_current_component()] ) && $bp->active_components[bp_current_component()] == $nav_item->css_id ) { 1299 1299 $selected = ' class="current selected"'; 1300 1300 } 1301 1301 … … function bp_get_loggedin_user_nav() { 1307 1307 $selected = ''; 1308 1308 1309 1309 if ( bp_is_active( 'friends' ) ) { 1310 if ( $nav_item ['css_id']== $bp->friends->id ) {1310 if ( $nav_item->css_id == $bp->friends->id ) { 1311 1311 if ( friends_check_friendship( bp_loggedin_user_id(), bp_displayed_user_id() ) ) { 1312 1312 $selected = ' class="current selected"'; 1313 1313 } … … function bp_get_loggedin_user_nav() { 1316 1316 } 1317 1317 1318 1318 // Echo out the final list item. 1319 echo apply_filters_ref_array( 'bp_get_loggedin_user_nav_' . $nav_item ['css_id'], array( '<li id="li-nav-' . $nav_item['css_id'] . '" ' . $selected . '><a id="my-' . $nav_item['css_id'] . '" href="' . $nav_item['link'] . '">' . $nav_item['name']. '</a></li>', &$nav_item ) );1319 echo apply_filters_ref_array( 'bp_get_loggedin_user_nav_' . $nav_item->css_id, array( '<li id="li-nav-' . $nav_item->css_id . '" ' . $selected . '><a id="my-' . $nav_item->css_id . '" href="' . $nav_item->link . '">' . $nav_item->name . '</a></li>', &$nav_item ) ); 1320 1320 } 1321 1321 1322 1322 // Always add a log out list item to the end of the navigation. … … function bp_get_loggedin_user_nav() { 1333 1333 function bp_get_displayed_user_nav() { 1334 1334 $bp = buddypress(); 1335 1335 1336 foreach ( (array) $bp->bp_navas $user_nav_item ) {1337 if ( empty( $user_nav_item ['show_for_displayed_user'] ) && !bp_is_my_profile() )1336 foreach ( $bp->members->nav->get_primary() as $user_nav_item ) { 1337 if ( empty( $user_nav_item->show_for_displayed_user ) && ! bp_is_my_profile() ) { 1338 1338 continue; 1339 } 1339 1340 1340 1341 $selected = ''; 1341 if ( bp_is_current_component( $user_nav_item ['slug']) ) {1342 if ( bp_is_current_component( $user_nav_item->slug ) ) { 1342 1343 $selected = ' class="current selected"'; 1343 1344 } 1344 1345 1345 1346 if ( bp_loggedin_user_domain() ) { 1346 $link = str_replace( bp_loggedin_user_domain(), bp_displayed_user_domain(), $user_nav_item ['link']);1347 $link = str_replace( bp_loggedin_user_domain(), bp_displayed_user_domain(), $user_nav_item->link ); 1347 1348 } else { 1348 $link = trailingslashit( bp_displayed_user_domain() . $user_nav_item ['link']);1349 $link = trailingslashit( bp_displayed_user_domain() . $user_nav_item->link ); 1349 1350 } 1350 1351 1351 1352 /** … … function bp_get_displayed_user_nav() { 1359 1360 * @param array $user_nav_item Array holding parts used to construct tab list item. 1360 1361 * Passed by reference. 1361 1362 */ 1362 echo apply_filters_ref_array( 'bp_get_displayed_user_nav_' . $user_nav_item ['css_id'], array( '<li id="' . $user_nav_item['css_id'] . '-personal-li" ' . $selected . '><a id="user-' . $user_nav_item['css_id'] . '" href="' . $link . '">' . $user_nav_item['name']. '</a></li>', &$user_nav_item ) );1363 echo apply_filters_ref_array( 'bp_get_displayed_user_nav_' . $user_nav_item->css_id, array( '<li id="' . $user_nav_item->css_id . '-personal-li" ' . $selected . '><a id="user-' . $user_nav_item->css_id . '" href="' . $link . '">' . $user_nav_item->name . '</a></li>', &$user_nav_item ) ); 1363 1364 } 1364 1365 } 1365 1366 -
src/bp-members/classes/class-bp-members-component.php
diff --git src/bp-members/classes/class-bp-members-component.php src/bp-members/classes/class-bp-members-component.php index 92a2c85..edf49a4 100644
class BP_Members_Component extends BP_Component { 150 150 // The domain for the user currently being displayed. 151 151 $bp->displayed_user->domain = bp_core_get_user_domain( bp_displayed_user_id() ); 152 152 153 // Initialize the nav for the members component. 154 $this->nav = new BP_Core_Nav(); 155 153 156 /** Signup *********************************************************** 154 157 */ 155 158 -
src/bp-messages/bp-messages-screens.php
diff --git src/bp-messages/bp-messages-screens.php src/bp-messages/bp-messages-screens.php index 2be4937..0e92210 100644
function messages_screen_conversation() { 132 132 $class = ( 0 === $count ) ? 'no-count' : 'count'; 133 133 $nav_name = sprintf( __( 'Messages <span class="%s">%s</span>', 'buddypress' ), esc_attr( $class ), bp_core_number_format( $count ) ); 134 134 135 $bp->bp_nav[ $bp->messages->slug ]['name'] = $nav_name; 135 // Edit the Navigation name. 136 $bp->members->nav->edit_nav( array( 137 'name' => $nav_name, 138 ), $bp->messages->slug ); 136 139 137 140 /** 138 141 * Fires right before the loading of the Messages view screen template file. -
src/bp-settings/bp-settings-actions.php
diff --git src/bp-settings/bp-settings-actions.php src/bp-settings/bp-settings-actions.php index f377ff6..6a68868 100644
add_action( 'bp_actions', 'bp_settings_verify_email_change' ); 488 488 */ 489 489 function bp_settings_remove_email_subnav() { 490 490 if ( ! has_action( 'bp_notification_settings' ) ) { 491 bp_core_ remove_subnav_item( BP_SETTINGS_SLUG, 'notifications');491 bp_core_delete_subnav_item( 'notifications', BP_SETTINGS_SLUG ); 492 492 } 493 493 } 494 494 add_action( 'bp_actions', 'bp_settings_remove_email_subnav' ); -
src/bp-xprofile/classes/class-bp-xprofile-component.php
diff --git src/bp-xprofile/classes/class-bp-xprofile-component.php src/bp-xprofile/classes/class-bp-xprofile-component.php index 87689b1..f25edec 100644
class BP_XProfile_Component extends BP_Component { 302 302 'screen_function' => 'bp_xprofile_screen_settings', 303 303 'position' => 30, 304 304 'user_has_access' => bp_core_can_edit_settings() 305 ) );305 ), 'members' ); 306 306 } 307 307 308 308 /** -
deleted file tests/phpunit/testcases/core/nav.php
diff --git tests/phpunit/testcases/core/nav.php tests/phpunit/testcases/core/nav.php deleted file mode 100644 index 721217d..0000000
+ - 1 <?php2 3 /**4 * @group core5 * @group nav6 */7 class BP_Tests_Core_Nav extends BP_UnitTestCase {8 9 /**10 * @group bp_core_sort_nav_items11 */12 public function test_bp_core_sort_nav_items() {13 $bp_nav = buddypress()->bp_nav;14 15 $u = $this->factory->user->create();16 $old_current_user = get_current_user_id();17 $this->set_current_user( $u );18 19 $this->go_to( bp_core_get_user_domain( $u ) );20 21 bp_core_new_nav_item( array(22 'name' => 'Foo',23 'slug' => 'foo',24 'position' => 25,25 'screen_function' => 'foo_screen_function',26 'default_subnav_slug' => 'foo-sub'27 ) );28 29 $expected = array(30 'name' => 'Foo',31 'slug' => 'foo',32 'link' => trailingslashit( bp_core_get_user_domain( $u ) . 'foo' ),33 'css_id' => 'foo',34 'show_for_displayed_user' => true,35 'position' => 25,36 'screen_function' => 'foo_screen_function',37 'default_subnav_slug' => 'foo-sub'38 );39 40 bp_core_sort_nav_items();41 42 $this->assertSame( buddypress()->bp_nav[25], $expected );43 44 // Clean up45 buddypress()->bp_nav = $bp_nav;46 $this->set_current_user( $old_current_user );47 }48 49 /**50 * @group bp_core_sort_subnav_items51 */52 public function test_bp_core_sort_subnav_items() {53 $bp_options_nav = buddypress()->bp_options_nav;54 55 $u = $this->factory->user->create();56 $old_current_user = get_current_user_id();57 $this->set_current_user( $u );58 59 $user_domain = bp_core_get_user_domain( $u );60 61 $this->go_to( $user_domain );62 63 bp_core_new_subnav_item( array(64 'name' => 'Foo',65 'slug' => 'foo',66 'parent_url' => trailingslashit( $user_domain . 'foo' ),67 'parent_slug' => 'foo',68 'screen_function' => 'foo_screen_function',69 'position' => 1070 ) );71 72 bp_core_sort_subnav_items();73 74 $expected = array(75 'name' => 'Foo',76 'link' => trailingslashit( $user_domain . 'foo/foo' ),77 'slug' => 'foo',78 'css_id' => 'foo',79 'position' => 10,80 'user_has_access' => true,81 'no_access_url' => '',82 'screen_function' => 'foo_screen_function',83 'show_in_admin_bar' => false,84 );85 86 $this->assertSame( buddypress()->bp_options_nav['foo'][10], $expected );87 88 // Clean up89 buddypress()->bp_options_nav = $bp_options_nav;90 $this->set_current_user( $old_current_user );91 }92 } -
new file tests/phpunit/testcases/core/nav/backCompat.php
diff --git tests/phpunit/testcases/core/nav/backCompat.php tests/phpunit/testcases/core/nav/backCompat.php new file mode 100644 index 0000000..5f5f017
- + 1 <?php 2 3 /** 4 * @group core 5 * @group nav 6 * @ticket BP6534 7 * @expectedIncorrectUsage bp_nav 8 */ 9 class BP_Core_Nav_BackCompat extends BP_UnitTestCase { 10 protected $bp_nav; 11 protected $bp_options_nav; 12 13 public function setUp() { 14 parent::setUp(); 15 $this->bp_nav = buddypress()->bp_nav; 16 $this->bp_options_nav = buddypress()->bp_options_nav; 17 } 18 19 public function tearDown() { 20 buddypress()->bp_nav = $this->bp_nav; 21 buddypress()->bp_options_nav = $this->bp_options_nav; 22 parent::tearDown(); 23 } 24 25 protected function create_nav_items() { 26 bp_core_new_nav_item( array( 27 'name' => 'Foo', 28 'slug' => 'foo', 29 'position' => 25, 30 'screen_function' => 'foo_screen_function', 31 'default_subnav_slug' => 'foo-subnav' 32 ) ); 33 34 bp_core_new_subnav_item( array( 35 'name' => 'Foo Subnav', 36 'slug' => 'foo-subnav', 37 'parent_url' => 'example.com/foo', 38 'parent_slug' => 'foo', 39 'screen_function' => 'foo_screen_function', 40 'position' => 10 41 ) ); 42 } 43 44 /** 45 * Create a group, set up nav item, and go to the group. 46 */ 47 protected function set_up_group() { 48 $g = $this->factory->group->create( array( 49 'slug' => 'testgroup', 50 ) ); 51 52 $group = groups_get_group( array( 'group_id' => $g ) ); 53 $group_permalink = bp_get_group_permalink( $group ); 54 55 $this->go_to( $group_permalink ); 56 57 bp_core_new_subnav_item( array( 58 'name' => 'Foo', 59 'slug' => 'foo', 60 'parent_url' => $group_permalink, 61 'parent_slug' => 'testgroup', 62 'screen_function' => 'foo_screen_function', 63 'position' => 10 64 ), 'groups' ); 65 } 66 67 public function test_bp_nav_isset() { 68 $this->create_nav_items(); 69 70 $bp = buddypress(); 71 72 $this->assertTrue( isset( $bp->bp_nav ) ); 73 $this->assertTrue( isset( $bp->bp_nav['foo'] ) ); 74 $this->assertTrue( isset( $bp->bp_nav['foo']['name'] ) ); 75 } 76 77 public function test_bp_nav_unset() { 78 $this->create_nav_items(); 79 80 $bp = buddypress(); 81 82 // No support for this - it would create a malformed nav item. 83 /* 84 unset( $bp->bp_nav['foo']['css_id'] ); 85 $this->assertFalse( isset( $bp->bp_nav['foo']['css_id'] ) ); 86 */ 87 88 unset( $bp->bp_nav['foo'] ); 89 $this->assertFalse( isset( $bp->bp_nav['foo'] ) ); 90 } 91 92 public function test_bp_nav_get() { 93 $this->create_nav_items(); 94 95 $bp = buddypress(); 96 97 $foo = $bp->bp_nav['foo']; 98 $this->assertSame( 'Foo', $foo['name'] ); 99 100 $this->assertSame( 'Foo', $bp->bp_nav['foo']['name'] ); 101 } 102 103 public function test_bp_nav_set() { 104 $this->create_nav_items(); 105 106 $bp = buddypress(); 107 108 $bp->bp_nav['foo']['name'] = 'Bar'; 109 110 $nav = bp_get_nav_menu_items(); 111 112 foreach ( $nav as $_nav ) { 113 if ( 'foo' === $_nav->css_id ) { 114 $found = $_nav; 115 break; 116 } 117 } 118 119 $this->assertSame( 'Bar', $found->name ); 120 } 121 122 public function test_bp_options_nav_isset() { 123 $this->create_nav_items(); 124 125 $bp = buddypress(); 126 127 $this->assertTrue( isset( $bp->bp_options_nav ) ); 128 $this->assertTrue( isset( $bp->bp_options_nav['foo'] ) ); 129 $this->assertTrue( isset( $bp->bp_options_nav['foo']['foo-subnav'] ) ); 130 $this->assertTrue( isset( $bp->bp_options_nav['foo']['foo-subnav']['name'] ) ); 131 } 132 133 public function test_bp_options_nav_unset() { 134 $this->create_nav_items(); 135 136 $bp = buddypress(); 137 138 // No support for this - it would create a malformed nav item. 139 /* 140 unset( $bp->bp_options_nav['foo']['foo-subnav']['user_has_access'] ); 141 $this->assertFalse( isset( $bp->bp_options_nav['foo']['foo-subnav']['user_has_access'] ) ); 142 */ 143 144 unset( $bp->bp_options_nav['foo']['foo-subnav'] ); 145 $this->assertFalse( isset( $bp->bp_options_nav['foo']['foo-subnav'] ) ); 146 147 // Make sure the parent nav hasn't been wiped out. 148 $this->assertTrue( isset( $bp->bp_options_nav['foo'] ) ); 149 150 unset( $bp->bp_options_nav['foo'] ); 151 $this->assertFalse( isset( $bp->bp_options_nav['foo'] ) ); 152 } 153 154 public function test_bp_options_nav_get() { 155 $this->create_nav_items(); 156 157 $bp = buddypress(); 158 159 $foo_subnav = $bp->bp_options_nav['foo']['foo-subnav']; 160 $this->assertSame( 'Foo Subnav', $foo_subnav['name'] ); 161 162 $this->assertSame( 'Foo Subnav', $bp->bp_options_nav['foo']['foo-subnav']['name'] ); 163 } 164 165 public function test_bp_options_nav_set() { 166 $this->create_nav_items(); 167 168 $bp = buddypress(); 169 170 $bp->bp_options_nav['foo']['foo-subnav']['name'] = 'Bar'; 171 $nav = bp_get_nav_menu_items(); 172 173 foreach ( $nav as $_nav ) { 174 if ( 'foo-subnav' === $_nav->css_id ) { 175 $found = $_nav; 176 break; 177 } 178 } 179 180 $this->assertSame( 'Bar', $found->name ); 181 182 $subnav = array( 183 'name' => 'Bar', 184 'css_id' => 'bar-id', 185 'link' => 'bar-link', 186 'slug' => 'bar-slug', 187 'user_has_access' => true, 188 ); 189 $bp->bp_options_nav['foo']['foo-subnav'] = $subnav; 190 $nav = bp_get_nav_menu_items(); 191 192 foreach ( $nav as $_nav ) { 193 if ( 'bar-id' === $_nav->css_id ) { 194 $found = $_nav; 195 break; 196 } 197 } 198 199 $this->assertSame( 'Bar', $found->name ); 200 } 201 202 /** 203 * @group groups 204 */ 205 public function test_bp_options_nav_isset_group_nav() { 206 $this->set_up_group(); 207 208 $bp = buddypress(); 209 210 $this->assertTrue( isset( $bp->bp_options_nav ) ); 211 $this->assertTrue( isset( $bp->bp_options_nav['testgroup'] ) ); 212 $this->assertTrue( isset( $bp->bp_options_nav['testgroup']['foo'] ) ); 213 $this->assertTrue( isset( $bp->bp_options_nav['testgroup']['foo']['name'] ) ); 214 } 215 216 /** 217 * @group groups 218 */ 219 public function test_bp_options_nav_unset_group_nav() { 220 $this->set_up_group(); 221 222 $bp = buddypress(); 223 224 // No support for this - it would create a malformed nav item. 225 /* 226 unset( $bp->bp_options_nav['testgroup']['foo']['user_has_access'] ); 227 $this->assertFalse( isset( $bp->bp_options_nav['testgroup']['foo']['user_has_access'] ) ); 228 */ 229 230 unset( $bp->bp_options_nav['testgroup']['foo'] ); 231 $this->assertFalse( isset( $bp->bp_options_nav['testgroup']['foo'] ) ); 232 233 unset( $bp->bp_options_nav['testgroup'] ); 234 $this->assertFalse( isset( $bp->bp_options_nav['testgroup'] ) ); 235 } 236 237 /** 238 * @group groups 239 */ 240 public function test_bp_options_nav_get_group_nav() { 241 $this->set_up_group(); 242 243 $bp = buddypress(); 244 245 $foo = $bp->bp_options_nav['testgroup']['foo']; 246 $this->assertSame( 'Foo', $foo['name'] ); 247 248 $this->assertSame( 'Foo', $bp->bp_options_nav['testgroup']['foo']['name'] ); 249 } 250 251 /** 252 * @group groups 253 */ 254 public function test_bp_options_nav_set_group_nav() { 255 $this->set_up_group(); 256 257 $bp = buddypress(); 258 259 $bp->bp_options_nav['testgroup']['foo']['name'] = 'Bar'; 260 $nav = bp_get_nav_menu_items( 'groups' ); 261 262 foreach ( $nav as $_nav ) { 263 if ( 'foo' === $_nav->css_id ) { 264 $found = $_nav; 265 break; 266 } 267 } 268 269 $this->assertSame( 'Bar', $found->name ); 270 271 $subnav = array( 272 'name' => 'Bar', 273 'css_id' => 'bar-id', 274 'link' => 'bar-link', 275 'slug' => 'bar-slug', 276 'user_has_access' => true, 277 ); 278 $bp->bp_options_nav['testgroup']['foo'] = $subnav; 279 $nav = bp_get_nav_menu_items( 'groups' ); 280 281 foreach ( $nav as $_nav ) { 282 if ( 'bar-id' === $_nav->css_id ) { 283 $found = $_nav; 284 break; 285 } 286 } 287 288 $this->assertSame( 'Bar', $found->name ); 289 } 290 291 /** 292 * @group groups 293 */ 294 public function test_bp_core_new_subnav_item_should_work_in_group_context() { 295 $this->set_up_group(); 296 297 bp_core_new_subnav_item( array( 298 'name' => 'Foo Subnav', 299 'slug' => 'foo-subnav', 300 'parent_slug' => bp_get_current_group_slug(), 301 'parent_url' => bp_get_group_permalink( groups_get_current_group() ), 302 'screen_function' => 'foo_subnav', 303 ) ); 304 305 $bp = buddypress(); 306 307 // Touch bp_nav since we told PHPUnit it was expectedDeprecated. 308 $f = $bp->bp_options_nav[ bp_get_current_group_slug() ]; 309 310 $nav = bp_get_nav_menu_items( 'groups' ); 311 312 foreach ( $nav as $_nav ) { 313 if ( 'foo-subnav' === $_nav->css_id ) { 314 $found = $_nav; 315 break; 316 } 317 } 318 319 $this->assertSame( 'Foo Subnav', $found->name ); 320 } 321 } -
tests/phpunit/testcases/core/nav/bpCoreMaybeHookNewSubnavScreenFunction.php
diff --git tests/phpunit/testcases/core/nav/bpCoreMaybeHookNewSubnavScreenFunction.php tests/phpunit/testcases/core/nav/bpCoreMaybeHookNewSubnavScreenFunction.php index 2ebc74c..41fed2a 100644
class BP_Tests_Core_Nav_BpCoreMaybeHookNewSubnavScreenFunction extends BP_UnitTe 82 82 $old_bp_nav = buddypress()->bp_nav; 83 83 $old_default_component = buddypress()->default_component; 84 84 buddypress()->default_component = 'foo'; 85 buddypress()->bp_nav = array( 86 'foo' => array( 87 'show_for_displayed_user' => true, 88 ), 89 ); 85 86 bp_core_new_nav_item( array( 87 'slug' => 'foo', 88 'name' => 'Foo', 89 'screen_function' => 'foo', 90 'default_subnav_item' => 'bar', 91 ) ); 90 92 91 93 $subnav_item = array( 92 94 'user_has_access' => false, … … class BP_Tests_Core_Nav_BpCoreMaybeHookNewSubnavScreenFunction extends BP_UnitTe 94 96 95 97 // Just test relevant info 96 98 $found = bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ); 97 $this->assertSame( 'failure', $found['status'] );98 $this->assertSame( bp_core_get_user_domain( $u2 ), $found['redirect_args']['root'] );99 99 100 100 // Clean up 101 101 $this->set_current_user( $old_current_user ); 102 102 buddypress()->default_component = $old_default_component; 103 103 buddypress()->bp_nav = $old_bp_nav; 104 105 $this->assertSame( 'failure', $found['status'] ); 106 $this->assertSame( bp_core_get_user_domain( $u2 ), $found['redirect_args']['root'] ); 104 107 } 105 108 106 109 public function test_user_has_access_false_user_logged_in_others_profile_default_component_not_accessible() { … … class BP_Tests_Core_Nav_BpCoreMaybeHookNewSubnavScreenFunction extends BP_UnitTe 114 117 $old_bp_nav = buddypress()->bp_nav; 115 118 $old_default_component = buddypress()->default_component; 116 119 buddypress()->default_component = 'foo'; 117 buddypress()->bp_nav = array( 118 'foo' => array( 119 'show_for_displayed_user' => false, 120 ), 121 ); 120 121 bp_core_new_nav_item( array( 122 'slug' => 'foo', 123 'name' => 'Foo', 124 'screen_function' => 'foo', 125 'default_subnav_item' => 'bar', 126 'show_for_displayed_user' => false, 127 ) ); 122 128 123 129 $subnav_item = array( 124 130 'user_has_access' => false, … … class BP_Tests_Core_Nav_BpCoreMaybeHookNewSubnavScreenFunction extends BP_UnitTe 126 132 127 133 // Just test relevant info 128 134 $found = bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ); 129 $this->assertSame( 'failure', $found['status'] );130 $this->assertSame( bp_core_get_user_domain( $u2 ) . bp_get_activity_slug() . '/', $found['redirect_args']['root'] );131 135 132 136 // Clean up 133 137 $this->set_current_user( $old_current_user ); 134 138 buddypress()->default_component = $old_default_component; 135 139 buddypress()->bp_nav = $old_bp_nav; 140 141 $this->assertSame( 'failure', $found['status'] ); 142 $this->assertSame( bp_core_get_user_domain( $u2 ) . bp_get_activity_slug() . '/', $found['redirect_args']['root'] ); 136 143 } 137 144 138 145 public function test_user_has_access_false_user_logged_in_group() { -
tests/phpunit/testcases/core/nav/bpCoreNewNavItem.php
diff --git tests/phpunit/testcases/core/nav/bpCoreNewNavItem.php tests/phpunit/testcases/core/nav/bpCoreNewNavItem.php index b6f6439..884a8a8 100644
5 5 */ 6 6 class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 7 7 8 /** 9 * @expectedIncorrectUsage bp_nav 10 */ 8 11 public function test_user_nav() { 9 12 $bp_nav = buddypress()->bp_nav; 10 13 … … class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 33 36 'default_subnav_slug' => 'foo-sub' 34 37 ); 35 38 36 $this->assertSame( buddypress()->bp_nav['foo'], $expected ); 39 foreach ( $expected as $k => $v ) { 40 $this->assertEquals( $v, buddypress()->bp_nav['foo'][ $k ] ); 41 } 37 42 38 43 // Clean up 39 44 buddypress()->bp_nav = $bp_nav; 40 45 $this->set_current_user( $old_current_user ); 41 46 } 42 47 48 /** 49 * @expectedIncorrectUsage bp_nav 50 */ 43 51 public function test_group_nav() { 44 52 $bp_nav = buddypress()->bp_nav; 45 53 … … class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 89 97 $this->assertFalse( bp_core_new_nav_item( $args ) ); 90 98 } 91 99 100 /** 101 * @expectedIncorrectUsage bp_nav 102 */ 92 103 public function test_css_id_should_fall_back_on_slug() { 93 104 $args = array( 94 105 'name' => 'Foo', … … class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 99 110 $this->assertSame( 'foo', buddypress()->bp_nav['foo']['css_id'] ); 100 111 } 101 112 113 /** 114 * @expectedIncorrectUsage bp_nav 115 */ 102 116 public function test_css_id_should_be_respected() { 103 117 $args = array( 104 118 'name' => 'Foo', … … class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 124 138 $this->assertFalse( $retval ); 125 139 } 126 140 141 /** 142 * @expectedIncorrectUsage bp_nav 143 */ 127 144 public function test_existence_of_access_protected_user_nav() { 128 145 $bp_nav = buddypress()->bp_nav; 129 146 … … class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 145 162 'default_subnav_slug' => 'general' 146 163 ); 147 164 148 $this->assertSame( buddypress()->bp_nav['settings'], $expected ); 165 foreach ( $expected as $k => $v ) { 166 $this->assertEquals( $v, buddypress()->bp_nav['settings'][ $k ] ); 167 } 149 168 150 169 // Clean up 151 170 buddypress()->bp_nav = $bp_nav; 152 171 $this->set_current_user( $old_current_user ); 153 172 } 154 173 174 /** 175 * @expectedIncorrectUsage bp_nav 176 */ 155 177 public function test_creation_of_access_protected_user_nav() { 156 178 // The nav item must be added to bp_nav, even if the current user 157 179 // can't visit that nav item. … … class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 184 206 'default_subnav_slug' => 'woof-one' 185 207 ); 186 208 187 $this->assertSame( buddypress()->bp_nav['woof'], $expected ); 209 foreach ( $expected as $k => $v ) { 210 $this->assertEquals( $v, buddypress()->bp_nav['woof'][ $k ] ); 211 } 188 212 189 213 // Clean up 190 214 buddypress()->bp_nav = $bp_nav; -
tests/phpunit/testcases/core/nav/bpCoreNewSubnavItem.php
diff --git tests/phpunit/testcases/core/nav/bpCoreNewSubnavItem.php tests/phpunit/testcases/core/nav/bpCoreNewSubnavItem.php index cf07a2f..45ce3c5 100644
5 5 */ 6 6 class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 7 7 8 /** 9 * @expectedIncorrectUsage bp_nav 10 */ 8 11 public function test_user_subnav() { 9 12 $bp_options_nav = buddypress()->bp_options_nav; 10 13 … … class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 16 19 17 20 $this->go_to( $user_domain ); 18 21 22 bp_core_new_nav_item( array( 23 'name' => 'Foo Parent', 24 'slug' => 'foo-parent', 25 'link' => trailingslashit( $user_domain . 'foo-parent' ), 26 'screen_function' => 'foo_screen_function', 27 'position' => 10, 28 ) ); 29 19 30 bp_core_new_subnav_item( array( 20 31 'name' => 'Foo', 21 32 'slug' => 'foo', 22 'parent_url' => trailingslashit( $user_domain . 'foo ' ),23 'parent_slug' => 'foo ',33 'parent_url' => trailingslashit( $user_domain . 'foo-parent' ), 34 'parent_slug' => 'foo-parent', 24 35 'screen_function' => 'foo_screen_function', 25 36 'position' => 10 26 37 ) ); 27 38 28 39 $expected = array( 29 40 'name' => 'Foo', 30 'link' => trailingslashit( $user_domain . 'foo /foo' ),41 'link' => trailingslashit( $user_domain . 'foo-parent/foo' ), 31 42 'slug' => 'foo', 32 43 'css_id' => 'foo', 33 44 'position' => 10, … … class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 37 48 'show_in_admin_bar' => false, 38 49 ); 39 50 40 $this->assertSame( buddypress()->bp_options_nav['foo']['foo'], $expected ); 51 foreach ( $expected as $k => $v ) { 52 $this->assertSame( $v, buddypress()->bp_options_nav['foo-parent']['foo'][ $k ] ); 53 } 41 54 42 55 // Clean up 43 56 buddypress()->bp_options_nav = $bp_options_nav; … … class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 102 115 $this->set_current_user( $old_current_user ); 103 116 } 104 117 118 /** 119 * @expectedIncorrectUsage bp_nav 120 */ 105 121 public function test_link_provided() { 106 122 $bp_options_nav = buddypress()->bp_options_nav; 107 123 124 bp_core_new_nav_item( array( 125 'name' => 'Foo', 126 'slug' => 'foo', 127 'screen_function' => 'foo', 128 'link' => 'https://buddypress.org/', 129 ) ); 130 108 131 bp_core_new_subnav_item( array( 109 132 'name' => 'bar', 110 133 'slug' => 'bar', … … class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 119 142 buddypress()->bp_options_nav = $bp_options_nav; 120 143 } 121 144 145 /** 146 * @expectedIncorrectUsage bp_nav 147 */ 122 148 public function test_link_built_from_parent_url_and_slug() { 123 149 $bp_options_nav = buddypress()->bp_options_nav; 124 150 151 bp_core_new_nav_item( array( 152 'name' => 'Foo', 153 'slug' => 'foo', 154 'screen_function' => 'foo', 155 'link' => 'https://buddypress.org/', 156 ) ); 157 125 158 bp_core_new_subnav_item( array( 126 159 'name' => 'bar', 127 160 'slug' => 'bar', … … class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 135 168 buddypress()->bp_options_nav = $bp_options_nav; 136 169 } 137 170 171 /** 172 * @expectedIncorrectUsage bp_nav 173 */ 138 174 public function test_link_built_from_parent_url_and_slug_where_slug_is_default() { 139 175 $bp_nav = buddypress()->bp_nav; 140 176 $bp_options_nav = buddypress()->bp_options_nav; 141 177 142 // fake the parent143 buddypress()->bp_nav = array(144 ' foo' => array(145 'default_subnav_slug' => 'bar',146 ),147 ) ;178 bp_core_new_nav_item( array( 179 'name' => 'Foo', 180 'slug' => 'foo', 181 'screen_function' => 'foo', 182 'default_subnav_slug' => 'bar', 183 ) ); 148 184 149 185 bp_core_new_subnav_item( array( 150 186 'name' => 'bar', … … class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 161 197 buddypress()->bp_options_nav = $bp_options_nav; 162 198 } 163 199 200 /** 201 * @expectedIncorrectUsage bp_nav 202 */ 164 203 public function test_should_trailingslash_link_when_link_is_autogenerated_using_slug() { 204 bp_core_new_nav_item( array( 205 'name' => 'Foo', 206 'slug' => 'foo', 207 'screen_function' => 'foo', 208 'link' => 'https://buddypress.org/', 209 ) ); 210 165 211 bp_core_new_subnav_item( array( 166 212 'name' => 'bar', 167 213 'slug' => 'bar', … … class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 174 220 $this->assertSame( $expected, buddypress()->bp_options_nav['foo']['bar']['link'] ); 175 221 } 176 222 223 /** 224 * @expectedIncorrectUsage bp_nav 225 */ 177 226 public function test_should_trailingslash_link_when_link_is_autogenerated_not_using_slug() { 178 227 bp_core_new_nav_item( array( 179 228 'name' => 'foo', … … class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 187 236 'name' => 'bar', 188 237 'slug' => 'bar', 189 238 'parent_slug' => 'foo-parent', 190 'parent_url' => bp_get_root_domain() . ' foo-parent/',239 'parent_url' => bp_get_root_domain() . '/foo-parent/', 191 240 'screen_function' => 'bar', 192 241 ) ); 193 242 194 $expected = bp_get_root_domain() . ' foo-parent/';243 $expected = bp_get_root_domain() . '/foo-parent/'; 195 244 $this->assertSame( $expected, buddypress()->bp_options_nav['foo-parent']['bar']['link'] ); 196 245 } 197 246 198 247 /** 199 248 * @ticket BP6353 249 * @expectedIncorrectUsage bp_nav 200 250 */ 201 251 public function test_link_should_not_trailingslash_link_explicit_link() { 202 252 $link = 'http://example.com/foo/bar/blah/?action=edit&id=30'; 203 253 254 bp_core_new_nav_item( array( 255 'name' => 'Foo', 256 'slug' => 'foo', 257 'screen_function' => 'foo', 258 'link' => 'http://example.com/foo/', 259 ) ); 260 204 261 bp_core_new_subnav_item( array( 205 262 'name' => 'bar', 206 263 'slug' => 'bar', … … class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 214 271 } 215 272 216 273 public function test_should_return_false_if_site_admin_only_and_current_user_cannot_bp_moderate() { 274 bp_core_new_nav_item( array( 275 'name' => 'Foo', 276 'slug' => 'foo', 277 'screen_function' => 'foo', 278 ) ); 279 217 280 // Should already be set to a 0 user. 218 281 $this->assertFalse( bp_current_user_can( 'bp_moderate' ) ); 219 282 $args = array( … … class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 228 291 $this->assertFalse( bp_core_new_subnav_item( $args ) ); 229 292 } 230 293 294 /** 295 * @expectedIncorrectUsage bp_nav 296 */ 231 297 public function test_css_id_should_fall_back_on_slug() { 298 bp_core_new_nav_item( array( 299 'name' => 'Parent', 300 'slug' => 'parent', 301 'screen_function' => 'foo', 302 ) ); 303 232 304 $args = array( 233 305 'name' => 'Foo', 234 306 'slug' => 'foo', … … class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 241 313 $this->assertSame( 'foo', buddypress()->bp_options_nav['parent']['foo']['css_id'] ); 242 314 } 243 315 316 /** 317 * @expectedIncorrectUsage bp_nav 318 */ 244 319 public function test_css_id_should_be_respected() { 320 bp_core_new_nav_item( array( 321 'name' => 'Parent', 322 'slug' => 'parent', 323 'screen_function' => 'foo', 324 ) ); 325 245 326 $args = array( 246 327 'name' => 'Foo', 247 328 'slug' => 'foo', -
tests/phpunit/testcases/groups/class-bp-group-extension.php
diff --git tests/phpunit/testcases/groups/class-bp-group-extension.php tests/phpunit/testcases/groups/class-bp-group-extension.php index 55b12e5..e421c91 100644
class BP_Tests_Group_Extension_TestCases extends BP_UnitTestCase { 217 217 218 218 /** 219 219 * @group enable_nav_item 220 * @expectedIncorrectUsage bp_nav 220 221 */ 221 222 public function test_enable_nav_item_true() { 222 223 $old_options_nav = buddypress()->bp_options_nav; … … class BP_Tests_Group_Extension_TestCases extends BP_UnitTestCase { 239 240 240 241 /** 241 242 * @group enable_nav_item 243 * @expectedIncorrectUsage bp_nav 242 244 */ 243 245 public function test_enable_nav_item_false() { 244 246 $old_options_nav = buddypress()->bp_options_nav; … … class BP_Tests_Group_Extension_TestCases extends BP_UnitTestCase { 261 263 262 264 /** 263 265 * @group visibility 266 * @expectedIncorrectUsage bp_nav 264 267 */ 265 268 public function test_visibility_private() { 266 269 $old_options_nav = buddypress()->bp_options_nav; … … class BP_Tests_Group_Extension_TestCases extends BP_UnitTestCase { 298 301 299 302 /** 300 303 * @group visibility 304 * @expectedIncorrectUsage bp_nav 301 305 * 302 306 * visibility=public + status=private results in adding the item to 303 307 * the nav. However, BP_Groups_Component::setup_globals() bounces the -
tests/phpunit/testcases/routing/anonymous.php
diff --git tests/phpunit/testcases/routing/anonymous.php tests/phpunit/testcases/routing/anonymous.php index e83776f..a5234a8 100644
class BP_Tests_Routing_Anonymous extends BP_UnitTestCase { 10 10 11 11 function test_nav_menu() { 12 12 $this->go_to( '/' ); 13 $this->assertEmpty( buddypress()->bp_nav ); 13 $nav = buddypress()->members->nav->get_item_nav(); 14 $this->assertEmpty( $nav ); 14 15 } 15 16 } -
tests/phpunit/testcases/routing/core.php
diff --git tests/phpunit/testcases/routing/core.php tests/phpunit/testcases/routing/core.php index 30f9a8e..fcb4a32 100644
class BP_Tests_Routing_Core extends BP_UnitTestCase { 22 22 $this->assertEmpty( bp_current_component() ); 23 23 } 24 24 25 /** 26 * @expectedIncorrectUsage bp_nav 27 */ 25 28 function test_nav_menu() { 26 29 $this->go_to( '/' ); 27 30 $this->assertArrayHasKey( 'activity', buddypress()->bp_nav );