Skip to:
Content

BuddyPress.org

Ticket #6534: 6534.02.patch

File 6534.02.patch, 57.0 KB (added by imath, 8 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..e676c00 100644
    defined( 'ABSPATH' ) || exit; 
    1616 * Add an item to the main BuddyPress navigation array.
    1717 *
    1818 * @since 1.1.0
     19 * @since 2.6.0 Adds the $nav parameter.
    1920 *
    2021 * @param array|string $args {
    2122 *     Array describing the new nav item.
    defined( 'ABSPATH' ) || exit; 
    3233 *     @type bool|string $default_subnav_slug     Optional. The slug of the default subnav item to select when the nav
    3334 *                                                item is clicked.
    3435 * }
     36 * @param  BP_Core_Item_Nav $nav The specific main nav to use. Optional.
    3537 * @return bool|null Returns false on failure.
    3638 */
    37 function bp_core_new_nav_item( $args = '' ) {
     39function bp_core_new_nav_item( $args = '', $nav = null ) {
    3840
    3941        $defaults = array(
    4042                'name'                    => false, // Display name for the nav item.
    function bp_core_new_nav_item( $args = '' ) { 
    5052        $r = wp_parse_args( $args, $defaults );
    5153
    5254        // First, add the nav item link to the bp_nav array.
    53         $created = bp_core_create_nav_link( $r );
     55        $created = bp_core_create_nav_link( $r, $nav );
    5456
    5557        // To mimic the existing behavior, if bp_core_create_nav_link()
    5658        // returns false, we make an early exit and don't attempt to register
    function bp_core_new_nav_item( $args = '' ) { 
    8486 * Add a link to the main BuddyPress navigation array.
    8587 *
    8688 * @since 2.4.0
     89 * @since 2.6.0 Adds the $nav parameter.
    8790 *
    8891 * @param array|string $args {
    8992 *     Array describing the new nav item.
    function bp_core_new_nav_item( $args = '' ) { 
    100103 *     @type bool|string $default_subnav_slug     Optional. The slug of the default subnav item to select when the nav
    101104 *                                                item is clicked.
    102105 * }
     106 * @param  BP_Core_Item_Nav $nav The specific main nav to use. Optional.
    103107 * @return bool|null Returns false on failure.
    104108 */
    105 function bp_core_create_nav_link( $args = '' ) {
     109function bp_core_create_nav_link( $args = '', $nav = null ) {
    106110        $bp = buddypress();
    107111
     112        if ( ! is_a( $nav, 'BP_Core_Item_Nav' ) ) {
     113                $nav = $bp->bp_nav;
     114        }
     115
    108116        $defaults = array(
    109117                'name'                    => false, // Display name for the nav item.
    110118                'slug'                    => false, // URL slug for the nav item.
    function bp_core_create_nav_link( $args = '' ) { 
    132140                $r['item_css_id'] = $r['slug'];
    133141        }
    134142
    135         $bp->bp_nav[$r['slug']] = array(
     143        $nav->{ $r['slug'] } = array(
    136144                'name'                    => $r['name'],
    137145                'slug'                    => $r['slug'],
    138146                'link'                    => trailingslashit( bp_loggedin_user_domain() . $r['slug'] ),
    function bp_core_new_nav_default( $args = '' ) { 
    290298
    291299        $r = wp_parse_args( $args, $defaults );
    292300
    293         if ( $function = $bp->bp_nav[$r['parent_slug']]['screen_function'] ) {
     301        if ( $function = $bp->bp_nav->{ $r['parent_slug'] }['screen_function'] ) {
    294302                // Remove our screen hook if screen function is callable.
    295303                if ( is_callable( $function ) ) {
    296304                        remove_action( 'bp_screens', $function, 3 );
    297305                }
    298306        }
    299307
    300         $bp->bp_nav[$r['parent_slug']]['screen_function'] = &$r['screen_function'];
     308        $reset_item = $bp->bp_nav->{ $r['parent_slug'] };
     309        $reset_item['screen_function'] = &$r['screen_function'];
     310
     311        $bp->bp_nav->reset( $reset_item, $r['parent_slug'] );
    301312
    302313        if ( bp_is_current_component( $r['parent_slug'] ) ) {
    303314
    function bp_core_new_nav_default( $args = '' ) { 
    351362function bp_core_sort_nav_items() {
    352363        $bp = buddypress();
    353364
    354         if ( empty( $bp->bp_nav ) || ! is_array( $bp->bp_nav ) ) {
     365        if ( empty( $bp->bp_nav ) || ! is_a( $bp->bp_nav, 'BP_Core_Item_Nav' ) ) {
    355366                return false;
    356367        }
    357368
    358369        $temp = array();
    359370
    360         foreach ( (array) $bp->bp_nav as $slug => $nav_item ) {
     371        foreach ( (array) $bp->bp_nav->get() as $slug => $nav_item ) {
    361372                if ( empty( $temp[$nav_item['position']] ) ) {
    362373                        $temp[$nav_item['position']] = $nav_item;
    363374                } else {
    function bp_core_sort_nav_items() { 
    371382        }
    372383
    373384        ksort( $temp );
    374         $bp->bp_nav = &$temp;
     385        $bp->bp_nav->reset( $temp );
    375386}
    376387add_action( 'wp_head',    'bp_core_sort_nav_items' );
    377388add_action( 'admin_head', 'bp_core_sort_nav_items' );
    add_action( 'admin_head', 'bp_core_sort_nav_items' ); 
    380391 * Add a subnav item to the BuddyPress navigation.
    381392 *
    382393 * @since 1.1.0
     394 * @since 2.6.0 Adds the $subnav & $nav parameters.
    383395 *
    384396 * @param array|string $args {
    385397 *     Array describing the new subnav item.
    add_action( 'admin_head', 'bp_core_sort_nav_items' ); 
    403415 *     @type bool        $show_in_admin_bar Optional. Whether the nav item should be added into the group's "Edit"
    404416 *                                          Admin Bar menu for group admins. Default: false.
    405417 * }
     418 * @param  BP_Core_Item_Nav $subnav The specific subnav to use. Optional.
     419 * @param  BP_Core_Item_Nav $nav    The specific main nav to use. Optional.
    406420 * @return bool|null Returns false on failure.
    407421 */
    408 function bp_core_new_subnav_item( $args = '' ) {
     422function bp_core_new_subnav_item( $args = '', $subnav = null, $nav = null ) {
    409423
    410424        // First, add the subnav item link to the bp_options_nav array.
    411         $created = bp_core_create_subnav_link( $args );
     425        $created = bp_core_create_subnav_link( $args, $subnav, $nav );
    412426
    413427        // To mimic the existing behavior, if bp_core_create_subnav_link()
    414428        // returns false, we make an early exit and don't attempt to register
    function bp_core_new_subnav_item( $args = '' ) { 
    418432        }
    419433
    420434        // Then, hook the screen function for the added subnav item.
    421         $hooked = bp_core_register_subnav_screen_function( $args );
     435        $hooked = bp_core_register_subnav_screen_function( $args, $nav );
    422436        if ( false === $hooked ) {
    423437                return false;
    424438        }
    function bp_core_new_subnav_item( $args = '' ) { 
    428442 * Add a subnav link to the BuddyPress navigation.
    429443 *
    430444 * @since 2.4.0
     445 * @since 2.6.0 Adds the $subnav & $nav parameters.
    431446 *
    432447 * @param array|string $args {
    433448 *     Array describing the new subnav item.
    function bp_core_new_subnav_item( $args = '' ) { 
    455470 *                                          the group's "Edit" Admin Bar menu for group admins.
    456471 *                                          Default: false.
    457472 * }
     473 * @param  BP_Core_Item_Nav $subnav The specific subnav to use. Optional.
     474 * @param  BP_Core_Item_Nav $nav    The specific main nav to use. Optional.
    458475 * @return bool|null Returns false on failure.
    459476 */
    460 function bp_core_create_subnav_link( $args = '' ) {
     477function bp_core_create_subnav_link( $args = '', $subnav = null, $nav = null ) {
    461478        $bp = buddypress();
    462479
     480        if ( ! is_a( $subnav, 'BP_Core_Item_Nav' ) ) {
     481                $subnav = $bp->bp_options_nav;
     482        }
     483
     484        if ( ! is_a( $nav, 'BP_Core_Item_Nav' ) ) {
     485                $nav = $bp->bp_nav;
     486        }
     487
    463488        $r = wp_parse_args( $args, array(
    464489                'name'              => false, // Display name for the nav item.
    465490                'slug'              => false, // URL slug for the nav item.
    function bp_core_create_subnav_link( $args = '' ) { 
    484509                $r['link'] = trailingslashit( $r['parent_url'] . $r['slug'] );
    485510
    486511                // 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'] ) {
     512                if ( ! empty( $nav->{ $r['parent_slug'] }['default_subnav_slug'] ) && $r['slug'] == $nav->{ $r['parent_slug'] }['default_subnav_slug'] ) {
    488513                        $r['link'] = trailingslashit( $r['parent_url'] );
    489514                }
    490515        }
    function bp_core_create_subnav_link( $args = '' ) { 
    510535                'show_in_admin_bar' => (bool) $r['show_in_admin_bar'],
    511536        );
    512537
    513         $bp->bp_options_nav[$r['parent_slug']][$r['slug']] = $subnav_item;
     538        $subnav->add_subitem( $r['parent_slug'], $r['slug'], $subnav_item );
    514539}
    515540
    516541/**
    517542 * Register a screen function, whether or not a related subnav link exists.
    518543 *
    519544 * @since 2.4.0
     545 * @since 2.6.0 Adds the $nav parameters.
    520546 *
    521547 * @param array|string $args {
    522548 *     Array describing the new subnav item.
    function bp_core_create_subnav_link( $args = '' ) { 
    541567 *                                       the group's "Edit" Admin Bar menu for group admins.
    542568 *                                       Default: false.
    543569 * }
     570 * @param  BP_Core_Item_Nav $nav The specific main nav to use. Optional.
    544571 * @return bool|null Returns false on failure.
    545572 */
    546 function bp_core_register_subnav_screen_function( $args = '' ) {
     573function bp_core_register_subnav_screen_function( $args = '', $nav = null ) {
    547574        $bp = buddypress();
    548575
     576        if ( ! is_a( $nav, 'BP_Core_Item_Nav' ) ) {
     577                $nav = $bp->bp_nav;
     578        }
     579
    549580        $r = wp_parse_args( $args, array(
    550581                'slug'              => false, // URL slug for the screen.
    551582                'parent_slug'       => false, // URL slug of the parent screen.
    function bp_core_register_subnav_screen_function( $args = '' ) { 
    578609        }
    579610
    580611        // 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'] ) ) ) {
     612        if ( ( bp_current_action() && bp_is_current_action( $r['slug'] ) ) || ( bp_is_user() && ! bp_current_action() && ( $r['screen_function'] == $nav->{ $r['parent_slug'] }['screen_function'] ) ) ) {
    582613
    583614                // If this is for site admins only and the user is not one, don't create the subnav item.
    584615                if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) {
    585616                        return false;
    586617                }
    587618
    588                 $hooked = bp_core_maybe_hook_new_subnav_screen_function( $r );
     619                $hooked = bp_core_maybe_hook_new_subnav_screen_function( $r, $nav );
    589620
    590621                // If redirect args have been returned, perform the redirect now.
    591622                if ( ! empty( $hooked['status'] ) && 'failure' === $hooked['status'] && isset( $hooked['redirect_args'] ) ) {
    function bp_core_register_subnav_screen_function( $args = '' ) { 
    598629 * For a given subnav item, either hook the screen function or generate redirect arguments, as necessary.
    599630 *
    600631 * @since 2.1.0
     632 * @since 2.6.0 Adds the $nav parameters.
    601633 *
    602  * @param array $subnav_item The subnav array added to bp_options_nav in `bp_core_new_subnav_item()`.
     634 * @param array            $subnav_item The subnav array added to bp_options_nav in `bp_core_new_subnav_item()`.
     635 * @param BP_Core_Item_Nav $nav         The specific main nav to use. Optional.
    603636 * @return array
    604637 */
    605 function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ) {
     638function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item, $nav = null ) {
    606639        $retval = array(
    607640                'status' => '',
    608641        );
    function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ) { 
    635668
    636669                        $bp = buddypress();
    637670
     671                        if ( ! is_a( $nav, 'BP_Core_Item_Nav' ) ) {
     672                                $nav = $bp->bp_nav;
     673                        }
     674
    638675                        // If a redirect URL has been passed to the subnav
    639676                        // item, respect it.
    640677                        if ( ! empty( $subnav_item['no_access_url'] ) ) {
    function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ) { 
    648685                                // Redirect to the displayed user's default
    649686                                // component, as long as that component is
    650687                                // publicly accessible.
    651                                 if ( bp_is_my_profile() || ! empty( $bp->bp_nav[ $bp->default_component ]['show_for_displayed_user'] ) ) {
     688                                if ( bp_is_my_profile() || ! empty( $nav->{ $bp->default_component }['show_for_displayed_user'] ) ) {
    652689                                        $message     = __( 'You do not have access to this page.', 'buddypress' );
    653690                                        $redirect_to = bp_displayed_user_domain();
    654691
    function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ) { 
    691728}
    692729
    693730/**
     731 * Sort subnav items by position
     732 *
     733 * @since  2.6.0
     734 *
     735 * @param  array $subnav_items The subnav items to sort.
     736 * @return array               The sorted subnav items.
     737 */
     738function bp_core_sort_get_sorted_subnav_by_position( $subnav_items ) {
     739        $temp = array();
     740
     741        if ( empty( $subnav_items ) ) {
     742                return $temp;
     743        }
     744
     745        foreach ( (array) $subnav_items as $subnav_item ) {
     746                if ( empty( $temp[ $subnav_item['position'] ] ) ) {
     747                        $temp[ $subnav_item['position'] ] = $subnav_item;
     748                } else {
     749                        // Increase numbers here to fit new items in.
     750                        do {
     751                                $subnav_item['position']++;
     752                        } while ( ! empty( $temp[ $subnav_item['position'] ] ) );
     753
     754                        $temp[ $subnav_item['position'] ] = $subnav_item;
     755                }
     756        }
     757
     758        return $temp;
     759}
     760
     761/**
    694762 * Sort all subnavigation arrays.
    695763 *
    696764 * @since 1.1.0
    function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ) { 
    700768function bp_core_sort_subnav_items() {
    701769        $bp = buddypress();
    702770
    703         if ( empty( $bp->bp_options_nav ) || !is_array( $bp->bp_options_nav ) )
     771        if ( empty( $bp->bp_options_nav ) || ! is_a( $bp->bp_options_nav, 'BP_Core_Item_Nav' ) ) {
    704772                return false;
     773        }
    705774
    706         foreach ( (array) $bp->bp_options_nav as $parent_slug => $subnav_items ) {
    707                 if ( !is_array( $subnav_items ) )
     775        foreach ( (array) $bp->bp_options_nav->get() as $parent_slug => $subnav_items ) {
     776                if ( ! is_array( $subnav_items ) ) {
    708777                        continue;
     778                }
    709779
    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']] ) );
     780                $temp = bp_core_sort_get_sorted_subnav_by_position( $subnav_items );
    718781
    719                                 $temp[$subnav_item['position']] = $subnav_item;
    720                         }
    721                 }
    722782                ksort( $temp );
    723                 $bp->bp_options_nav[$parent_slug] = &$temp;
     783                $bp->bp_options_nav->reset( $temp, $parent_slug );
    724784                unset( $temp );
    725785        }
    726786}
    add_action( 'admin_head', 'bp_core_sort_subnav_items' ); 
    731791 * Check whether a given nav item has subnav items.
    732792 *
    733793 * @since 1.5.0
     794 * @since 2.6.0 Add the subnav parameter.
    734795 *
    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.
     796 * @param string           $nav_item The slug of the top-level nav item whose subnav items you're checking.
     797 *                                   Default: the current component slug.
     798 * @param BP_Core_Item_Nav $subnav   The Nav object to check upon. Optional.
     799 *                                   Default Legacy's buddypress()->bp_options_nav
    737800 * @return bool $has_subnav True if the nav item is found and has subnav items; false otherwise.
    738801 */
    739 function bp_nav_item_has_subnav( $nav_item = '' ) {
     802function bp_nav_item_has_subnav( $nav_item = '', $subnav = null ) {
    740803        $bp = buddypress();
    741804
    742         if ( !$nav_item )
     805        if ( ! is_a( $subnav, 'BP_Core_Item_Nav' ) ) {
     806                $subnav = $bp->bp_options_nav;
     807        }
     808
     809        if ( ! $nav_item ) {
    743810                $nav_item = bp_current_component();
     811        }
    744812
    745         $has_subnav = isset( $bp->bp_options_nav[$nav_item] ) && count( $bp->bp_options_nav[$nav_item] ) > 0;
     813        $has_subnav = isset( $subnav->{ $nav_item } ) && count( $subnav->{ $nav_item } ) > 0;
    746814
    747815        /**
    748816         * Filters whether or not a given nav item has subnav items.
    function bp_nav_item_has_subnav( $nav_item = '' ) { 
    759827 * Remove a nav item from the navigation array.
    760828 *
    761829 * @since 1.0.0
     830 * @since 2.6.0 Adds the $nav & $subnav parameters.
    762831 *
    763  * @param int $parent_id The slug of the parent navigation item.
     832 * @param int              $parent_id The slug of the parent navigation item.
     833 * @param BP_Core_Item_Nav $nav       The specific main nav to use. Optional.
     834 * @param BP_Core_Item_Nav $subnav    The specific subnav to use. Optional.
    764835 * @return bool Returns false on failure, ie if the nav item can't be found.
    765836 */
    766 function bp_core_remove_nav_item( $parent_id ) {
     837function bp_core_remove_nav_item( $parent_id, $nav = null, $subnav = null ) {
    767838        $bp = buddypress();
    768839
     840        if ( ! is_a( $nav, 'BP_Core_Item_Nav' ) ) {
     841                $nav = $bp->bp_nav;
     842        }
     843
     844        if ( ! is_a( $subnav, 'BP_Core_Item_Nav' ) ) {
     845                $subnav = $bp->bp_options_nav;
     846        }
     847
    769848        // 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'] );
     849        if ( isset( $subnav->{ $parent_id } ) && is_array( $subnav->{ $parent_id } ) ) {
     850                foreach( (array) $subnav->{ $parent_id } as $subnav_item ) {
     851                        bp_core_remove_subnav_item( $parent_id, $subnav_item['slug'], $subnav );
    773852                }
    774853        }
    775854
    776         if ( empty( $bp->bp_nav[ $parent_id ] ) )
     855        if ( empty( $nav->{ $parent_id } ) ) {
    777856                return false;
     857        }
    778858
    779         if ( $function = $bp->bp_nav[$parent_id]['screen_function'] ) {
     859        if ( $function = $nav->{ $parent_id }['screen_function'] ) {
    780860                // Remove our screen hook if screen function is callable.
    781861                if ( is_callable( $function ) ) {
    782862                        remove_action( 'bp_screens', $function, 3 );
    783863                }
    784864        }
    785865
    786         unset( $bp->bp_nav[$parent_id] );
     866        $nav->delete( $parent_id );
    787867}
    788868
    789869/**
    790870 * Remove a subnav item from the navigation array.
    791871 *
    792872 * @since 1.0.0
     873 * @since 2.6.0 Adds the $subnav parameter.
    793874 *
    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.
     875 * @param string           $parent_id The slug of the parent navigation item.
     876 * @param string           $slug      The slug of the subnav item to be removed.
     877 * @param BP_Core_Item_Nav $subnav    The specific subnav to use. Optional.
    796878 */
    797 function bp_core_remove_subnav_item( $parent_id, $slug ) {
     879function bp_core_remove_subnav_item( $parent_id, $slug, $subnav = null ) {
    798880        $bp = buddypress();
    799881
    800         $screen_function = isset( $bp->bp_options_nav[$parent_id][$slug]['screen_function'] )
    801                 ? $bp->bp_options_nav[$parent_id][$slug]['screen_function']
     882        if ( ! is_a( $subnav, 'BP_Core_Item_Nav' ) ) {
     883                $subnav = $bp->bp_options_nav;
     884        }
     885
     886        $screen_function = isset( $subnav->{ $parent_id }[ $slug ]['screen_function'] )
     887                ? $subnav->{ $parent_id }[ $slug ]['screen_function']
    802888                : false;
    803889
    804890        if ( ! empty( $screen_function ) ) {
    function bp_core_remove_subnav_item( $parent_id, $slug ) { 
    808894                }
    809895        }
    810896
    811         unset( $bp->bp_options_nav[$parent_id][$slug] );
     897        $subnav->delete( $parent_id, $slug );
    812898
    813         if ( isset( $bp->bp_options_nav[$parent_id] ) && !count( $bp->bp_options_nav[$parent_id] ) )
    814                 unset($bp->bp_options_nav[$parent_id]);
     899        if ( isset( $subnav->{ $parent_id } ) && ! count( $subnav->{ $parent_id } ) ) {
     900                $subnav->delete( $parent_id );
     901        }
    815902}
    816903
    817904/**
    818905 * Clear all subnav items from a specific nav item.
    819906 *
    820907 * @since 1.0.0
     908 * @since 2.6.0 Adds the $subnav parameter.
    821909 *
    822  * @param string $parent_slug The slug of the parent navigation item.
     910 * @param string           $parent_slug The slug of the parent navigation item.
     911 * @param BP_Core_Item_Nav $subnav      The specific subnav to use. Optional.
    823912 */
    824 function bp_core_reset_subnav_items( $parent_slug ) {
     913function bp_core_reset_subnav_items( $parent_slug, $subnav = null ) {
    825914        $bp = buddypress();
    826915
    827         unset( $bp->bp_options_nav[$parent_slug] );
     916        if ( ! is_a( $subnav, 'BP_Core_Item_Nav' ) ) {
     917                $subnav = $bp->bp_options_nav;
     918        }
     919
     920        $subnav->delete( $parent_slug );;
    828921}
    829922
    830923
  • 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..1bd97b9 100644
    require dirname( __FILE__ ) . '/classes/class-bp-email-recipient.php'; 
    3030require dirname( __FILE__ ) . '/classes/class-bp-email.php';
    3131require dirname( __FILE__ ) . '/classes/class-bp-email-delivery.php';
    3232require dirname( __FILE__ ) . '/classes/class-bp-phpmailer.php';
     33require dirname( __FILE__ ) . '/classes/class-bp-core-item-nav.php';
  • src/bp-core/bp-core-functions.php

    diff --git src/bp-core/bp-core-functions.php src/bp-core/bp-core-functions.php
    index 227237b..9f19a2a 100644
    function bp_nav_menu_get_loggedin_pages() { 
    23592359        }
    23602360
    23612361        // Pull up a list of items registered in BP's top-level nav array.
    2362         $bp_menu_items = buddypress()->bp_nav;
     2362        $bp_menu_items = buddypress()->bp_nav->get();
    23632363
    23642364        // Alphabetize.
    23652365        $bp_menu_items = bp_alpha_sort_by_key( $bp_menu_items, 'name' );
  • 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..b52756b 100644
    function bp_get_options_nav( $parent_slug = '' ) { 
    4040        $component_index = !empty( $bp->displayed_user ) ? bp_current_component() : bp_get_root_slug( bp_current_component() );
    4141        $selected_item   = bp_current_action();
    4242
     43        // Default nav & list type
     44        $nav = $bp->bp_options_nav;
     45        $list_type = 'personal';
     46
     47        if ( bp_is_group() ) {
     48                $nav       = $bp->groups->sub_nav;
     49                $list_type = 'groups';
     50        }
     51
    4352        if ( ! bp_is_single_item() ) {
    44                 if ( !isset( $bp->bp_options_nav[$component_index] ) || count( $bp->bp_options_nav[$component_index] ) < 1 ) {
     53                if ( !isset( $nav->{ $component_index } ) || count( $nav->{ $component_index } ) < 1 ) {
    4554                        return false;
    4655                } else {
    4756                        $the_index = $component_index;
    function bp_get_options_nav( $parent_slug = '' ) { 
    5463                        $selected_item = bp_action_variable( 0 );
    5564                }
    5665
    57                 if ( !isset( $bp->bp_options_nav[$current_item] ) || count( $bp->bp_options_nav[$current_item] ) < 1 ) {
     66                if ( !isset( $nav->{ $current_item } ) || count( $nav->{ $current_item } ) < 1 ) {
    5867                        return false;
    5968                } else {
    6069                        $the_index = $current_item;
    function bp_get_options_nav( $parent_slug = '' ) { 
    6271        }
    6372
    6473        // Loop through each navigation item.
    65         foreach ( (array) $bp->bp_options_nav[$the_index] as $subnav_item ) {
     74        foreach ( (array) $nav->{ $the_index } as $subnav_item ) {
    6675                if ( empty( $subnav_item['user_has_access'] ) ) {
    6776                        continue;
    6877                }
    function bp_get_options_nav( $parent_slug = '' ) { 
    7483                        $selected = '';
    7584                }
    7685
    77                 // List type depends on our current component.
    78                 $list_type = bp_is_group() ? 'groups' : 'personal';
     86
    7987
    8088                /**
    8189                 * Filters the "options nav", the secondary-level single item navigation menu.
    function bp_get_title_parts( $seplocation = 'right' ) { 
    30113019                $component_subnav_name = '';
    30123020
    30133021                // 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'] );
     3022                if ( ! empty( $bp->bp_nav->{ $component_id } ) ) {
     3023                        $component_name = _bp_strip_spans_from_title( $bp->bp_nav->{ $component_id }['name'] );
    30163024
    30173025                // Fall back on the component ID.
    30183026                } elseif ( ! empty( $bp->{$component_id}->id ) ) {
    function bp_get_title_parts( $seplocation = 'right' ) { 
    30203028                }
    30213029
    30223030                // 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' );
     3031                if ( ! empty( $bp->bp_options_nav->{ $component_id } ) && ! empty( $bp->canonical_stack['action'] ) ) {
     3032                        $component_subnav_name = wp_filter_object_list( $bp->bp_options_nav->{ $component_id }, array( 'slug' => bp_current_action() ), 'and', 'name' );
    30253033
    30263034                        if ( ! empty( $component_subnav_name ) ) {
    30273035                                $component_subnav_name = array_shift( $component_subnav_name );
    function bp_get_title_parts( $seplocation = 'right' ) { 
    30463054                }
    30473055
    30483056        // 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'] : '';
     3057        } elseif ( bp_is_active( 'groups' ) && ! empty( $bp->groups->current_group ) && ! empty( $bp->groups->sub_nav->{ $bp->groups->current_group->slug } ) ) {
     3058                $subnav      = isset( $bp->groups->sub_nav->{ $bp->groups->current_group->slug }[ bp_current_action() ]['name'] ) ? $bp->groups->sub_nav->{ $bp->groups->current_group->slug }[ bp_current_action() ]['name'] : '';
    30513059                $bp_title_parts = array( $bp->bp_options_title, $subnav );
    30523060
    30533061        // A single item from a component other than groups.
    30543062        } 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'] );
     3063                $bp_title_parts = array( $bp->bp_options_title, $bp->bp_options_nav->{ bp_current_item() }[ bp_current_action() ]['name'] );
    30563064
    30573065        // An index or directory.
    30583066        } elseif ( bp_is_directory() ) {
    function bp_get_nav_menu_items() { 
    34353443        $menus = $selected_menus = array();
    34363444
    34373445        // Get the second level menus.
    3438         foreach ( (array) buddypress()->bp_options_nav as $parent_menu => $sub_menus ) {
     3446        foreach ( (array) buddypress()->bp_options_nav->get() as $parent_menu => $sub_menus ) {
    34393447
    34403448                // The root menu's ID is "xprofile", but the Profile submenus are using "profile". See BP_Core::setup_nav().
    34413449                if ( 'profile' === $parent_menu ) {
  • src/bp-core/classes/class-bp-core-item-nav.php

    diff --git src/bp-core/classes/class-bp-core-item-nav.php src/bp-core/classes/class-bp-core-item-nav.php
    index e69de29..fede9f2 100644
     
     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.
     11defined( 'ABSPATH' ) || exit;
     12
     13/**
     14 * BuddyPress Item Nav.
     15 *
     16 * This class is used to store the Single Items nav
     17 *
     18 * @since 2.6.0
     19 */
     20class BP_Core_Item_Nav {
     21        /**
     22         * An associative array containing the nav items for the Item ID
     23         *
     24         * @var array
     25         */
     26        private $nav;
     27
     28        /**
     29         * The Current Item ID
     30         *
     31         * @var int
     32         */
     33        private $item_id;
     34
     35        /**
     36         * Init the Nav for the given Item ID
     37         *
     38         * @since 2.6.0
     39         *
     40         * @param int $item_id The item ID to build the nav for. Optional.
     41         *                     Default: The displayed user ID
     42         */
     43        public function __construct( $item_id = 0 ) {
     44                if ( empty( $item_id ) ) {
     45                        $this->item_id = (int) bp_displayed_user_id();
     46                } else {
     47                        $this->item_id = (int) $item_id;
     48                }
     49
     50                $this->nav[ $this->item_id ] = array();
     51        }
     52
     53        /**
     54         * Checks if a nav attribute is set.
     55         *
     56         * @since 2.6.0
     57         *
     58         * @param  string  $key The requested nav slug
     59         * @return bool    True if the nav attribute is set, false otherwise.
     60         */
     61        public function __isset( $key ) {
     62                return isset( $this->nav[ $this->item_id ][ $key ] );
     63        }
     64
     65        /**
     66         * Gets a nav attribute.
     67         *
     68         * @since 2.6.0
     69         *
     70         * @param  string  $key The requested nav slug.
     71         * @return mixed   The value corresponding to the requested attribute.
     72         */
     73        public function __get( $key ) {
     74                if ( ! isset( $this->nav[ $this->item_id ][ $key ] ) ) {
     75                        $this->nav[ $this->item_id ][ $key ] = null;
     76                }
     77
     78                return $this->nav[ $this->item_id ][ $key ];
     79        }
     80
     81        /**
     82         * Sets a nav attribute.
     83         *
     84         * @since 2.6.0
     85         *
     86         * @param  string  $key   The requested nav slug.
     87         * @param  mixed   $value The value of the attribute.
     88         */
     89        public function __set( $key, $value ) {
     90                $this->nav[ $this->item_id ][ $key ] = $value;
     91        }
     92
     93        /**
     94         * Gets a specific Item Nav attribute or all attributes.
     95         *
     96         * @since 2.6.0
     97         *
     98         * @param  string $key The attribute to get. Optional.
     99         * @return mixed       An array of attribute(s), null if not found.
     100         */
     101        public function get( $key = '' ) {
     102                $return = null;
     103
     104                // Return the requested nav item attribute
     105                if ( ! empty( $key ) ) {
     106                        if ( ! isset( $this->nav[ $this->item_id ][ $key ] ) ) {
     107                                $return = null;
     108                        } else {
     109                                $return = $this->nav[ $this->item_id ][ $key ];
     110                        }
     111
     112                // Return all nav item attributes
     113                } else {
     114                        $return = $this->nav[ $this->item_id ];
     115                }
     116
     117                return $return;
     118        }
     119
     120        /**
     121         * Completely resets the nav or a specific attribute of the nav.
     122         *
     123         * NB: This is used when sorting the nav items.
     124         *
     125         * @since 2.6.0
     126         *
     127         * @param  array $args The arguments to update with. Required.
     128         * @param  string $key The specific attribute to update. Optional.
     129         */
     130        public function reset( $args, $key = '' ) {
     131                if ( empty( $key ) ) {
     132                        $this->nav[ $this->item_id ] = $args;
     133                } elseif ( isset( $this->nav[ $this->item_id ][ $key ] ) ) {
     134                        $this->nav[ $this->item_id ][ $key ] = $args;
     135                }
     136        }
     137
     138        /**
     139         * Unset an item or a subitem of the nav.
     140         *
     141         * @since 2.6.0
     142         *
     143         * @param  string $key     The slug of the main item.
     144         * @param  string $sub_key The slug of the sub item.
     145         */
     146        public function delete( $key, $sub_key = '' ) {
     147                if ( isset( $this->nav[ $this->item_id ][ $key ] ) ) {
     148                        if ( ! empty( $sub_key ) ) {
     149                                unset( $this->nav[ $this->item_id ][ $key ][ $sub_key ] );
     150                        } else {
     151                                unset( $this->nav[ $this->item_id ][ $key ] );
     152                        }
     153                }
     154        }
     155
     156        /**
     157         * Adds one or more subitems to the nav.
     158         *
     159         * @since 2.6.0
     160         *
     161         * @param  string $key       The slug of the main item.
     162         * @param  string $sub_key   The slug of the sub item.
     163         * @param  array  $sub_value The value of the sub item.
     164         */
     165        public function add_subitem( $key, $sub_key, $sub_value ) {
     166                if ( ! empty( $this->nav[ $this->item_id ][ $key ] ) ) {
     167                        $this->nav[ $this->item_id ][ $key ][ $sub_key ] = $sub_value;
     168                } else {
     169                        $this->nav[ $this->item_id ][ $key ] = array(  $sub_key => $sub_value );
     170                }
     171        }
     172}
  • src/bp-groups/bp-groups-actions.php

    diff --git src/bp-groups/bp-groups-actions.php src/bp-groups/bp-groups-actions.php
    index 2190cec..7a75fc3 100644
    function groups_action_group_feed() { 
    551551        ) );
    552552}
    553553add_action( 'bp_actions', 'groups_action_group_feed' );
     554
     555
     556/**
     557 * Sort all subnavigation arrays.
     558 *
     559 * @since 2.6.0
     560 *
     561 * @return bool|null Returns false on failure.
     562 */
     563function bp_groups_sort_subnav_items() {
     564        $bp = buddypress();
     565
     566        if ( ! bp_is_group() || empty( $bp->groups->sub_nav ) || ! is_a( $bp->groups->sub_nav, 'BP_Core_Item_Nav' ) ) {
     567                return false;
     568        }
     569
     570        foreach ( (array) $bp->groups->sub_nav->get() as $parent_slug => $subnav_items ) {
     571                if ( ! is_array( $subnav_items ) ) {
     572                        continue;
     573                }
     574
     575                $temp = bp_core_sort_get_sorted_subnav_by_position( $subnav_items );
     576
     577                ksort( $temp );
     578                $bp->groups->sub_nav->reset( $temp, $parent_slug );
     579                unset( $temp );
     580        }
     581}
     582add_action( 'wp_head', 'bp_groups_sort_subnav_items' );
  • 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..174f84f 100644
    function bp_groups_group_admin_menu() { 
    5050        $nav_index = $bp->groups->current_group->slug . '_manage';
    5151
    5252        // Check if current group has Manage tabs.
    53         if ( empty( $bp->bp_options_nav[ $nav_index ] ) ) {
     53        if ( empty( $bp->groups->sub_nav->{ $nav_index } ) ) {
    5454                return;
    5555        }
    5656
    5757        // Build the Group Admin menus.
    58         foreach ( $bp->bp_options_nav[ $nav_index ] as $menu ) {
     58        foreach ( $bp->groups->sub_nav->{ $nav_index } as $menu ) {
    5959                /**
    6060                 * Should we add the current manage link in the Group's "Edit" Admin Bar menu ?
    6161                 *
  • 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..69b168d 100644
    class BP_Group_Extension { 
    737737                                'screen_function' => array( &$this, '_display_hook' ),
    738738                                'user_has_access' => $user_can_see_nav_item,
    739739                                'no_access_url'   => $group_permalink,
    740                         ) );
     740                        ), buddypress()->groups->sub_nav );
    741741                }
    742742
    743743                // If the user can visit the screen, we register it.
    class BP_Group_Extension { 
    967967                }
    968968
    969969                // Add the tab to the manage navigation.
    970                 bp_core_new_subnav_item( $subnav_args );
     970                bp_core_new_subnav_item( $subnav_args, buddypress()->groups->sub_nav );
    971971
    972972                // Catch the edit screen and forward it to the plugin template.
    973973                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..d46ba34 100644
    class BP_Groups_Component extends BP_Component { 
    253253                        // Check once if the current group has a custom front template.
    254254                        $this->current_group->front_template = bp_groups_get_front_template( $this->current_group );
    255255
     256                        /**
     257                         * Since 2.6.0 The Groups single items are using their own navigation to avoid slug
     258                         * collisions with the displayed user options nav (buddypress()->bp_options_nav)
     259                         * and for more flexibility in future releases.
     260                         */
     261
     262                        // Current Group's Primary Nav
     263                        $this->nav = new BP_Core_Item_Nav( $this->current_group->id );
     264
     265                        // Current Group's Secondary Nav
     266                        $this->sub_nav = new BP_Core_Item_Nav( $this->current_group->id );
     267
    256268                // Set current_group to 0 to prevent debug errors.
    257269                } else {
    258270                        $this->current_group = 0;
    class BP_Groups_Component extends BP_Component { 
    492504                }
    493505
    494506                if ( bp_is_groups_component() && bp_is_single_item() ) {
    495 
    496507                        // Reset sub nav.
    497508                        $sub_nav = array();
    498509
    499                         // Add 'Groups' to the main navigation.
    500                         $main_nav = array(
     510                        /**
     511                         * Set the Current Group's main navigation
     512                         *
     513                         * Since 2.6.0 it's now using its own navigation by passing it
     514                         * as the second argument of bp_core_new_nav_item()
     515                         */
     516                        bp_core_new_nav_item( array(
    501517                                'name'                => __( 'Memberships', 'buddypress' ),
    502518                                'slug'                => $this->current_group->slug,
    503519                                'position'            => -1, // Do not show in BuddyBar.
    504520                                'screen_function'     => 'groups_screen_group_home',
    505521                                'default_subnav_slug' => $this->default_extension,
    506522                                'item_css_id'         => $this->id
    507                         );
     523                        ), $this->nav );
    508524
    509525                        $group_link = bp_get_group_permalink( $this->current_group );
    510526
    class BP_Groups_Component extends BP_Component { 
    675691                                ), $default_params );
    676692                        }
    677693
    678                         parent::setup_nav( $main_nav, $sub_nav );
     694                        foreach( $sub_nav as $nav ) {
     695                                /**
     696                                 * Set the Current Group's sub navigation
     697                                 *
     698                                 * Since 2.6.0 it's now using its own sub navigation by passing it
     699                                 * as the second argument of bp_core_new_subnav_item()
     700                                 */
     701                                bp_core_new_subnav_item( $nav, $this->sub_nav );
     702                        }
    679703                }
    680704
    681705                if ( isset( $this->current_group->user_has_access ) ) {
  • src/bp-loader.php

    diff --git src/bp-loader.php src/bp-loader.php
    index f7b3f3f..2ace4e8 100644
    class BuddyPress { 
    5454        /** Not Magic *************************************************************/
    5555
    5656        /**
    57          * @var array Primary BuddyPress navigation.
     57         * @var object Primary BuddyPress navigation.
    5858         */
    59         public $bp_nav = array();
     59        public $bp_nav = null;
    6060
    6161        /**
    62          * @var array Secondary BuddyPress navigation to $bp_nav.
     62         * @var object Secondary BuddyPress navigation to $bp_nav.
    6363         */
    64         public $bp_options_nav = array();
     64        public $bp_options_nav = null;
    6565
    6666        /**
    6767         * @var array The unfiltered URI broken down into chunks.
  • 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..939d859 100644
    function bp_get_loggedin_user_nav() { 
    13331333function bp_get_displayed_user_nav() {
    13341334        $bp = buddypress();
    13351335
    1336         foreach ( (array) $bp->bp_nav as $user_nav_item ) {
     1336        foreach ( (array) $bp->bp_nav->get() as $user_nav_item ) {
    13371337                if ( empty( $user_nav_item['show_for_displayed_user'] ) && !bp_is_my_profile() )
    13381338                        continue;
    13391339
  • 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..63bb928 100644
    class BP_Members_Component extends BP_Component { 
    150150                // The domain for the user currently being displayed.
    151151                $bp->displayed_user->domain   = bp_core_get_user_domain( bp_displayed_user_id() );
    152152
     153                // Set User's primary nav
     154                $bp->bp_nav = new BP_Core_Item_Nav( bp_displayed_user_id() );
     155
     156                // Set User's secondary nav
     157                $bp->bp_options_nav = new BP_Core_Item_Nav( bp_displayed_user_id() );
     158
    153159                /** Signup ***********************************************************
    154160                 */
    155161
  • tests/phpunit/includes/testcase.php

    diff --git tests/phpunit/includes/testcase.php tests/phpunit/includes/testcase.php
    index 1e8bcb4..e3e3d6d 100644
    class BP_UnitTestCase extends WP_UnitTestCase { 
    9191        }
    9292
    9393        function clean_up_global_scope() {
    94                 buddypress()->bp_nav                = buddypress()->bp_options_nav = buddypress()->action_variables = buddypress()->canonical_stack = buddypress()->unfiltered_uri = $GLOBALS['bp_unfiltered_uri'] = array();
     94                buddypress()->bp_nav                = buddypress()->bp_options_nav = null;
     95                buddypress()->action_variables      = buddypress()->canonical_stack = buddypress()->unfiltered_uri = $GLOBALS['bp_unfiltered_uri'] = array();
    9596                buddypress()->current_component     = buddypress()->current_item = buddypress()->current_action = buddypress()->current_member_type = '';
    9697                buddypress()->unfiltered_uri_offset = 0;
    9798                buddypress()->is_single_item        = false;
  • tests/phpunit/testcases/blogs/activity.php

    diff --git tests/phpunit/testcases/blogs/activity.php tests/phpunit/testcases/blogs/activity.php
    index d7595ef..38c9dc6 100644
    class BP_Tests_Blogs_Activity extends BP_UnitTestCase { 
    618618        /**
    619619         * @group bp_blogs_sync_activity_edit_to_post_comment
    620620         * @group post_type_comment_activities
    621          * @group imath
    622621         */
    623622        public function test_bp_blogs_sync_activity_edit_to_post_comment_trash_comment_ham_activity() {
    624623                $old_user = get_current_user_id();
  • tests/phpunit/testcases/core/nav.php

    diff --git tests/phpunit/testcases/core/nav.php tests/phpunit/testcases/core/nav.php
    index 721217d..84fdfe7 100644
    class BP_Tests_Core_Nav extends BP_UnitTestCase { 
    3939
    4040                bp_core_sort_nav_items();
    4141
    42                 $this->assertSame( buddypress()->bp_nav[25], $expected );
     42
     43                $this->assertSame( buddypress()->bp_nav->get()[25], $expected );
    4344
    4445                // Clean up
    4546                buddypress()->bp_nav = $bp_nav;
    class BP_Tests_Core_Nav extends BP_UnitTestCase { 
    8384                        'show_in_admin_bar' => false,
    8485                );
    8586
    86                 $this->assertSame( buddypress()->bp_options_nav['foo'][10], $expected );
     87                $this->assertSame( buddypress()->bp_options_nav->get()['foo'][10], $expected );
    8788
    8889                // Clean up
    8990                buddypress()->bp_options_nav = $bp_options_nav;
    9091                $this->set_current_user( $old_current_user );
    9192        }
     93
     94        /**
     95         * @ticket BP5103
     96         */
     97        public function test_bp_core_new_subnav_item_group_slug_collision() {
     98                $u = $this->factory->user->create();
     99                $old_current_user = get_current_user_id();
     100                $this->set_current_user( $u );
     101
     102                $g = $this->factory->group->create( array( 'creator_id' => $u, 'slug' => 'profile' ) );
     103                $group     = groups_get_group( array( 'group_id' => $g ) );
     104                $group_url = bp_get_group_permalink( $group );
     105
     106                $not_group_menu_item = array();
     107
     108                $this->go_to( $group_url );
     109
     110                ob_start();
     111                bp_get_options_nav( $group->slug );
     112                $output = ob_get_clean();
     113
     114                preg_match_all( '/href=["\']?([^"\']*)["\' ]/is', $output, $hrefs );
     115
     116                foreach ( $hrefs[1] as $href ) {
     117                        if ( false === strpos( $href, $group_url ) ) {
     118                                $not_group_menu_item[] = $href;
     119                        }
     120                }
     121
     122                $this->assertEmpty( $not_group_menu_item );
     123
     124                // Clean up
     125                $this->set_current_user( $old_current_user );
     126        }
     127
     128        /**
     129         * @ticket BP6534
     130         * @group bp_core_new_nav_default
     131         */
     132        public function test_bp_core_new_nav_default() {
     133                $bp = buddypress();
     134                $bp_options_nav = $bp->bp_options_nav;
     135                $bp_nav = $bp->bp_nav;
     136
     137                $u = $this->factory->user->create();
     138                $old_current_user = get_current_user_id();
     139                $this->set_current_user( $u );
     140
     141                $user_domain = bp_core_get_user_domain( $u );
     142
     143                $this->go_to( trailingslashit( $user_domain ) . 'activity/mentions' );
     144
     145                $this->assertTrue( 'mentions' === $bp->canonical_stack['action'] );
     146
     147                bp_core_new_nav_default( array( 'parent_slug' => 'activity', 'subnav_slug' => 'mentions' ) );
     148
     149                $this->assertTrue( ! isset( $bp->canonical_stack['action'] ) );
     150
     151                // Clean up
     152                $bp->bp_options_nav = $bp_options_nav;
     153                $bp->bp_nav = $bp_nav;
     154                $this->set_current_user( $old_current_user );
     155        }
     156
     157        /**
     158         * @ticket BP6534
     159         * @group bp_nav_item_has_subnav
     160         */
     161        public function test_bp_nav_item_has_subnav() {
     162                $bp = buddypress();
     163                $bp_options_nav = $bp->bp_options_nav;
     164                $bp_nav = $bp->bp_nav;
     165
     166                $u = $this->factory->user->create();
     167                $old_current_user = get_current_user_id();
     168                $this->set_current_user( $u );
     169
     170                $user_domain = bp_core_get_user_domain( $u );
     171
     172                $this->go_to( $user_domain );
     173
     174                bp_core_new_subnav_item( array(
     175                        'name'            => 'Bar',
     176                        'slug'            => 'bar',
     177                        'parent_url'      => trailingslashit( $user_domain . 'bar' ),
     178                        'parent_slug'     => 'bar',
     179                        'screen_function' => 'bar_screen_function',
     180                        'position'        => 10
     181                ) );
     182
     183                $this->assertTrue( bp_nav_item_has_subnav( 'bar' ) );
     184
     185                // Clean up
     186                $bp->bp_options_nav = $bp_options_nav;
     187                $bp->bp_nav = $bp_nav;
     188                $this->set_current_user( $old_current_user );
     189        }
     190
     191        /**
     192         * @ticket BP6534
     193         * @group bp_core_remove_nav_item
     194         * @group bp_core_remove_subnav_item
     195         * @group bp_nav_item_has_subnav
     196         */
     197        public function test_bp_core_remove_nav_item() {
     198                $bp = buddypress();
     199                $bp_options_nav = $bp->bp_options_nav;
     200                $bp_nav = $bp->bp_nav;
     201
     202                $u = $this->factory->user->create();
     203                $old_current_user = get_current_user_id();
     204                $this->set_current_user( $u );
     205
     206                $user_domain = bp_core_get_user_domain( $u );
     207
     208                $this->go_to( $user_domain );
     209
     210                bp_core_new_nav_item( array(
     211                        'name'                    => 'Foo',
     212                        'slug'                    => 'foo',
     213                        'position'                => 80,
     214                        'screen_function'         => 'foo_screen_function',
     215                        'default_subnav_slug'     => 'bar'
     216                ) );
     217
     218                bp_core_new_subnav_item( array(
     219                        'name'            => 'Bar',
     220                        'slug'            => 'bar',
     221                        'parent_url'      => trailingslashit( $user_domain . 'bar' ),
     222                        'parent_slug'     => 'foo',
     223                        'screen_function' => 'bar_screen_function',
     224                        'position'        => 10
     225                ) );
     226
     227                bp_core_remove_nav_item( 'foo' );
     228
     229                $this->assertFalse( bp_nav_item_has_subnav( 'bar' ) );
     230
     231                // Clean up
     232                $bp->bp_options_nav = $bp_options_nav;
     233                $bp->bp_nav = $bp_nav;
     234                $this->set_current_user( $old_current_user );
     235        }
     236
     237        /**
     238         * @ticket BP6534
     239         * @group bp_core_reset_subnav_items
     240         */
     241        public function test_bp_core_reset_subnav_items() {
     242                $bp = buddypress();
     243                $bp_options_nav = $bp->bp_options_nav;
     244                $bp_nav = $bp->bp_nav;
     245
     246                $u = $this->factory->user->create();
     247                $old_current_user = get_current_user_id();
     248                $this->set_current_user( $u );
     249
     250                $user_domain = bp_core_get_user_domain( $u );
     251
     252                $this->go_to( $user_domain );
     253
     254                bp_core_new_subnav_item( array(
     255                        'name'            => 'Bar',
     256                        'slug'            => 'bar',
     257                        'parent_url'      => trailingslashit( $user_domain . 'bar' ),
     258                        'parent_slug'     => 'bar',
     259                        'screen_function' => 'bar_screen_function',
     260                        'position'        => 10
     261                ) );
     262
     263                $this->assertTrue( bp_nav_item_has_subnav( 'bar' ) );
     264
     265                bp_core_reset_subnav_items( 'bar' );
     266
     267                $this->assertFalse( bp_nav_item_has_subnav( 'bar' ) );
     268
     269                // Clean up
     270                $bp->bp_options_nav = $bp_options_nav;
     271                $bp->bp_nav = $bp_nav;
     272                $this->set_current_user( $old_current_user );
     273        }
    92274}
  • 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..5aa4b24 100644
    class BP_Tests_Core_Nav_BpCoreMaybeHookNewSubnavScreenFunction extends BP_UnitTe 
    8282                $old_bp_nav = buddypress()->bp_nav;
    8383                $old_default_component = buddypress()->default_component;
    8484                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                        'name' => 'Foo',
     88                        'slug' => 'foo',
     89                ) );
    9090
    9191                $subnav_item = array(
    9292                        'user_has_access' => false,
    class BP_Tests_Core_Nav_BpCoreMaybeHookNewSubnavScreenFunction extends BP_UnitTe 
    9494
    9595                // Just test relevant info
    9696                $found = bp_core_maybe_hook_new_subnav_screen_function( $subnav_item );
     97
    9798                $this->assertSame( 'failure', $found['status'] );
    9899                $this->assertSame( bp_core_get_user_domain( $u2 ), $found['redirect_args']['root'] );
    99100
    class BP_Tests_Core_Nav_BpCoreMaybeHookNewSubnavScreenFunction extends BP_UnitTe 
    114115                $old_bp_nav = buddypress()->bp_nav;
    115116                $old_default_component = buddypress()->default_component;
    116117                buddypress()->default_component = 'foo';
    117                 buddypress()->bp_nav = array(
    118                         'foo' => array(
    119                                 'show_for_displayed_user' => false,
    120                         ),
    121                 );
     118
     119                bp_core_new_nav_item( array(
     120                        'name'                    => 'Foo',
     121                        'slug'                    => 'foo',
     122                        'show_for_displayed_user' => false,
     123                ) );
    122124
    123125                $subnav_item = array(
    124126                        'user_has_access' => false,
  • 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..7e13def 100644
    class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 
    3333                        'default_subnav_slug'     => 'foo-sub'
    3434                );
    3535
    36                 $this->assertSame( buddypress()->bp_nav['foo'], $expected );
     36                $this->assertSame( buddypress()->bp_nav->get()['foo'], $expected );
    3737
    3838                // Clean up
    3939                buddypress()->bp_nav = $bp_nav;
    class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 
    4141        }
    4242
    4343        public function test_group_nav() {
    44                 $bp_nav = buddypress()->bp_nav;
    45 
    4644                $u = $this->factory->user->create();
    4745                $g = $this->factory->group->create();
    4846                $old_current_user = get_current_user_id();
    class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 
    5452
    5553                $this->go_to( bp_get_group_permalink( $group ) );
    5654
    57                 $this->assertTrue( buddypress()->bp_nav[ $group->slug ]['position'] === -1 );
     55                $this->assertTrue( buddypress()->groups->nav->{ $group->slug }['position'] === -1 );
    5856
    5957                // Clean up
    60                 buddypress()->bp_nav = $bp_nav;
    6158                $this->set_current_user( $old_current_user );
    6259        }
    6360
    class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 
    9693                );
    9794                bp_core_new_nav_item( $args );
    9895
    99                 $this->assertSame( 'foo', buddypress()->bp_nav['foo']['css_id'] );
     96                $this->assertSame( 'foo', buddypress()->bp_nav->get()['foo']['css_id'] );
    10097        }
    10198
    10299        public function test_css_id_should_be_respected() {
    class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 
    107104                );
    108105                bp_core_new_nav_item( $args );
    109106
    110                 $this->assertSame( 'bar', buddypress()->bp_nav['foo']['css_id'] );
     107                $this->assertSame( 'bar', buddypress()->bp_nav->get()['foo']['css_id'] );
    111108        }
    112109
    113110        public function test_show_for_displayed_user_false_should_force_function_to_return_false_when_bp_user_has_access_is_also_false() {
    class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 
    145142                        'default_subnav_slug'     => 'general'
    146143                );
    147144
    148                 $this->assertSame( buddypress()->bp_nav['settings'], $expected );
     145                $this->assertSame( buddypress()->bp_nav->settings, $expected );
    149146
    150147                // Clean up
    151148                buddypress()->bp_nav = $bp_nav;
    class BP_Tests_Core_Nav_BpCoreNewNavItem extends BP_UnitTestCase { 
    184181                        'default_subnav_slug'     => 'woof-one'
    185182                );
    186183
    187                 $this->assertSame( buddypress()->bp_nav['woof'], $expected );
     184                $this->assertSame( buddypress()->bp_nav->woof, $expected );
    188185
    189186                // Clean up
    190187                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..e88413a 100644
    class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 
    3737                        'show_in_admin_bar' => false,
    3838                );
    3939
    40                 $this->assertSame( buddypress()->bp_options_nav['foo']['foo'], $expected );
     40                $this->assertSame( buddypress()->bp_options_nav->foo['foo'], $expected );
    4141
    4242                // Clean up
    4343                buddypress()->bp_options_nav = $bp_options_nav;
    class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 
    114114                        'link' => 'https://buddypress.org/',
    115115                ) );
    116116
    117                 $this->assertSame( 'https://buddypress.org/', buddypress()->bp_options_nav['foo']['bar']['link'] );
     117                $this->assertSame( 'https://buddypress.org/', buddypress()->bp_options_nav->foo['bar']['link'] );
    118118
    119119                buddypress()->bp_options_nav = $bp_options_nav;
    120120        }
    class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 
    130130                        'screen_function' => 'foo',
    131131                ) );
    132132
    133                 $this->assertSame( 'http://example.com/foo/bar/', buddypress()->bp_options_nav['foo']['bar']['link'] );
     133                $this->assertSame( 'http://example.com/foo/bar/', buddypress()->bp_options_nav->foo['bar']['link'] );
    134134
    135135                buddypress()->bp_options_nav = $bp_options_nav;
    136136        }
    class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 
    140140                $bp_options_nav = buddypress()->bp_options_nav;
    141141
    142142                // fake the parent
    143                 buddypress()->bp_nav = array(
    144                         'foo' => array(
    145                                 'default_subnav_slug' => 'bar',
    146                         ),
    147                 );
     143                bp_core_new_nav_item( array(
     144                        'name'                    => 'Foo',
     145                        'slug'                    => 'foo',
     146                        'position'                => 25,
     147                        'screen_function'         => 'foo',
     148                        'default_subnav_slug'     => 'bar'
     149                ) );
    148150
    149151                bp_core_new_subnav_item( array(
    150152                        'name' => 'bar',
    class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 
    154156                        'screen_function' => 'foo',
    155157                ) );
    156158
    157                 $this->assertSame( 'http://example.com/foo/', buddypress()->bp_options_nav['foo']['bar']['link'] );
     159                $this->assertSame( 'http://example.com/foo/', buddypress()->bp_options_nav->foo['bar']['link'] );
    158160
    159161                // clean up
    160162                buddypress()->bp_nav = $bp_nav;
    class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 
    171173                ) );
    172174
    173175                $expected = bp_get_root_domain() . 'foo/bar/';
    174                 $this->assertSame( $expected, buddypress()->bp_options_nav['foo']['bar']['link'] );
     176                $this->assertSame( $expected, buddypress()->bp_options_nav->foo['bar']['link'] );
    175177        }
    176178
    177179        public function test_should_trailingslash_link_when_link_is_autogenerated_not_using_slug() {
    class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 
    192194                ) );
    193195
    194196                $expected = bp_get_root_domain() . 'foo-parent/';
    195                 $this->assertSame( $expected, buddypress()->bp_options_nav['foo-parent']['bar']['link'] );
     197                $this->assertSame( $expected, buddypress()->bp_options_nav->get()['foo-parent']['bar']['link'] );
    196198        }
    197199
    198200        /**
    class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 
    210212                        'link' => $link,
    211213                ) );
    212214
    213                 $this->assertSame( $link, buddypress()->bp_options_nav['foo']['bar']['link'] );
     215                $this->assertSame( $link, buddypress()->bp_options_nav->foo['bar']['link'] );
    214216        }
    215217
    216218        public function test_should_return_false_if_site_admin_only_and_current_user_cannot_bp_moderate() {
    class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 
    238240                );
    239241                bp_core_new_subnav_item( $args );
    240242
    241                 $this->assertSame( 'foo', buddypress()->bp_options_nav['parent']['foo']['css_id'] );
     243                $this->assertSame( 'foo', buddypress()->bp_options_nav->parent['foo']['css_id'] );
    242244        }
    243245
    244246        public function test_css_id_should_be_respected() {
    class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase { 
    252254                );
    253255                bp_core_new_subnav_item( $args );
    254256
    255                 $this->assertSame( 'bar', buddypress()->bp_options_nav['parent']['foo']['css_id'] );
     257                $this->assertSame( 'bar', buddypress()->bp_options_nav->parent['foo']['css_id'] );
    256258        }
    257259}
  • 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..b66fd0c 100644
    class BP_Tests_Group_Extension_TestCases extends BP_UnitTestCase { 
    219219         * @group enable_nav_item
    220220         */
    221221        public function test_enable_nav_item_true() {
    222                 $old_options_nav = buddypress()->bp_options_nav;
    223 
    224222                $g = $this->factory->group->create();
    225223                $g_obj = groups_get_group( array( 'group_id' => $g ) );
    226224
    class BP_Tests_Group_Extension_TestCases extends BP_UnitTestCase { 
    231229
    232230                $e->_register();
    233231
    234                 $this->assertTrue( isset( buddypress()->bp_options_nav[ $g_obj->slug ][ $e->slug ] ) );
    235 
    236                 // Clean up
    237                 buddypress()->bp_options_nav = $old_options_nav;
     232                $this->assertTrue( isset( buddypress()->groups->sub_nav->{ $g_obj->slug }[ $e->slug ] ) );
    238233        }
    239234
    240235        /**
    241236         * @group enable_nav_item
    242237         */
    243238        public function test_enable_nav_item_false() {
    244                 $old_options_nav = buddypress()->bp_options_nav;
    245 
    246239                $g = $this->factory->group->create();
    247240                $g_obj = groups_get_group( array( 'group_id' => $g ) );
    248241
    class BP_Tests_Group_Extension_TestCases extends BP_UnitTestCase { 
    253246
    254247                $e->_register();
    255248
    256                 $this->assertFalse( isset( buddypress()->bp_options_nav[ $g_obj->slug ][ $e->slug ] ) );
    257 
    258                 // Clean up
    259                 buddypress()->bp_options_nav = $old_options_nav;
     249                $this->assertFalse( isset( buddypress()->groups->sub_nav->{ $g_obj->slug }[ $e->slug ] ) );
    260250        }
    261251
    262252        /**
    263253         * @group visibility
    264254         */
    265255        public function test_visibility_private() {
    266                 $old_options_nav = buddypress()->bp_options_nav;
    267256                $old_current_user = get_current_user_id();
    268257
    269258                $g = $this->factory->group->create( array(
    class BP_Tests_Group_Extension_TestCases extends BP_UnitTestCase { 
    278267                $this->set_current_user( 0 );
    279268                $this->go_to( bp_get_group_permalink( $g_obj ) );
    280269                $e->_register();
    281                 $this->assertFalse( isset( buddypress()->bp_options_nav[ $g_obj->slug ][ $e->slug ] ) );
    282 
    283                 // Clean up
    284                 buddypress()->bp_options_nav = $old_options_nav;
     270                $this->assertFalse( isset( buddypress()->groups->sub_nav->{ $g_obj->slug }[ $e->slug ] ) );
    285271
    286272                // Test as group member
    287273                $u = $this->factory->user->create();
    class BP_Tests_Group_Extension_TestCases extends BP_UnitTestCase { 
    289275                $this->add_user_to_group( $u, $g );
    290276                $this->go_to( bp_get_group_permalink( $g_obj ) );
    291277                $e->_register();
    292                 $this->assertTrue( isset( buddypress()->bp_options_nav[ $g_obj->slug ][ $e->slug ] ) );
     278                $this->assertTrue( isset( buddypress()->groups->sub_nav->{ $g_obj->slug }[ $e->slug ] ) );
    293279
    294280                // Clean up
    295                 buddypress()->bp_options_nav = $old_options_nav;
    296281                $this->set_current_user( $old_current_user );
    297282        }
    298283
    class BP_Tests_Group_Extension_TestCases extends BP_UnitTestCase { 
    306291         * @see https://buddypress.trac.wordpress.org/ticket/4785
    307292         */
    308293        public function test_visibility_public() {
    309                 $old_options_nav = buddypress()->bp_options_nav;
    310294                $old_current_user = get_current_user_id();
    311295
    312296                $g = $this->factory->group->create( array(
    class BP_Tests_Group_Extension_TestCases extends BP_UnitTestCase { 
    321305                $this->set_current_user( 0 );
    322306                $this->go_to( bp_get_group_permalink( $g_obj ) );
    323307                $e->_register();
    324                 $this->assertTrue( isset( buddypress()->bp_options_nav[ $g_obj->slug ][ $e->slug ] ) );
    325 
    326                 // Clean up
    327                 buddypress()->bp_options_nav = $old_options_nav;
     308                $this->assertTrue( isset( buddypress()->groups->sub_nav->{ $g_obj->slug }[ $e->slug ] ) );
    328309
    329310                // Test as group member
    330311                $u = $this->factory->user->create();
    class BP_Tests_Group_Extension_TestCases extends BP_UnitTestCase { 
    332313                $this->add_user_to_group( $u, $g );
    333314                $this->go_to( bp_get_group_permalink( $g_obj ) );
    334315                $e->_register();
    335                 $this->assertTrue( isset( buddypress()->bp_options_nav[ $g_obj->slug ][ $e->slug ] ) );
     316                $this->assertTrue( isset( buddypress()->groups->sub_nav->{ $g_obj->slug }[ $e->slug ] ) );
    336317
    337318                // Clean up
    338                 buddypress()->bp_options_nav = $old_options_nav;
    339319                $this->set_current_user( $old_current_user );
    340320        }
    341321
  • tests/phpunit/testcases/routing/anonymous.php

    diff --git tests/phpunit/testcases/routing/anonymous.php tests/phpunit/testcases/routing/anonymous.php
    index e83776f..130b338 100644
    class BP_Tests_Routing_Anonymous extends BP_UnitTestCase { 
    1010
    1111        function test_nav_menu() {
    1212                $this->go_to( '/' );
    13                 $this->assertEmpty( buddypress()->bp_nav );
     13                $this->assertEmpty( buddypress()->bp_nav->get() );
    1414        }
    1515}
  • tests/phpunit/testcases/routing/core.php

    diff --git tests/phpunit/testcases/routing/core.php tests/phpunit/testcases/routing/core.php
    index 30f9a8e..e703ea0 100644
    class BP_Tests_Routing_Core extends BP_UnitTestCase { 
    2424
    2525        function test_nav_menu() {
    2626                $this->go_to( '/' );
    27                 $this->assertArrayHasKey( 'activity', buddypress()->bp_nav );
    28                 $this->assertArrayHasKey( 'profile',  buddypress()->bp_nav );
     27                $this->assertArrayHasKey( 'activity', buddypress()->bp_nav->get() );
     28                $this->assertArrayHasKey( 'profile',  buddypress()->bp_nav->get() );
    2929        }
    3030}