Skip to:
Content

BuddyPress.org


Ignore:
Timestamp:
05/12/2016 05:19:06 PM (8 years ago)
Author:
boonebgorges
Message:

Introduce new API for BuddyPress navigation.

The new BP_Core_Nav overhauls the way that BuddyPress registers, stores, and
renders navigation items. Navigations are now component-specific, eliminating
the potential for confusion and conflict between navigation items with similar
names in different components, and opening the possibility of generating navs
for separate objects of the same type on a single pageload.

The new nav API replaces the old bp_nav and bp_options_nav system, which
dates from the earliest days of BuddyPress. These global properties were
responsible for handling nav and subnav across all of BP's components. The data
structure of bp_nav and bp_options_nav was simultaneously too opaque (in the
sense of being difficult to approach for developers and not having a complete
interface for programmatic modification) and too transparent (forcing devs to
manipulate the global arrays directly in order to customize navigation). The
new system eliminates most of these problems, by removing direct access to the
underlying navigation data, while providing a full-fledged API for accessing
and modifying that data.

An abstraction layer provides backward compatibility for most legacy uses of
bp_nav and bp_options_nav. Plugins that read data from the globals, modify
the data (eg $bp->bp_nav['foo']['name'] = 'Bar'), and unset nav items via
bp_nav and bp_options_nav should all continue to work as before. Anyone
accessing the globals in this way will see a _doing_it_wrong() notice. This
backward compatibility layer requires SPL (Standard PHP Library), which means
that it will not be enabled on certain configurations running PHP 5.2.x. (SPL
cannot be disabled in PHP 5.3+, and is on by default for earlier versions.)

The new system breaks backward compatibility in a number of small ways. Our
research suggests that these breaks will affect very few customizations, but
we list them here for posterity:

  • Some array functions, such as sort(), will no longer work to modify the nav globals.
  • Subnav items added to nonexistent parents can no longer be successfully registered. Previously, they could be loaded into the global, but were never displayed on the front end.
  • Manual management of group navigation items previously worked by passing the group slug as the parent_slug parameter to the bp_core_*_subnav_item() functions. The new API requires specifying a $component ('members', 'groups') when accessing nav items. To provide compatibility with legacy use - where $component was not required - we make some educated guesses about whether a nav item is "meant" to be attached to a group. This could result in unpredictable behavior in cases where a group slug clashes with a Members navigation item. This has always been broken - see #5103 - but may break in different ways after this changeset.

Props imath, boonebgorges, r-a-y.
Fixes #5103. Fixes #6534.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/testcases/core/nav/bpCoreNewSubnavItem.php

    r9991 r10745  
    66class BP_Tests_Core_Nav_BpCoreNewSubnavItem extends BP_UnitTestCase {
    77
     8    /**
     9     * @expectedIncorrectUsage bp_nav
     10     */
    811    public function test_user_subnav() {
    912        $bp_options_nav = buddypress()->bp_options_nav;
     
    1720        $this->go_to( $user_domain );
    1821
     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
    1930        bp_core_new_subnav_item( array(
    2031            'name'            => 'Foo',
    2132            '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',
    2435            'screen_function' => 'foo_screen_function',
    2536            'position'        => 10
     
    2839        $expected = array(
    2940            'name'              => 'Foo',
    30             'link'              => trailingslashit( $user_domain . 'foo/foo' ),
     41            'link'              => trailingslashit( $user_domain . 'foo-parent/foo' ),
    3142            'slug'              => 'foo',
    3243            'css_id'            => 'foo',
     
    3849        );
    3950
    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        }
    4154
    4255        // Clean up
     
    103116    }
    104117
     118    /**
     119     * @expectedIncorrectUsage bp_nav
     120     */
    105121    public function test_link_provided() {
    106122        $bp_options_nav = buddypress()->bp_options_nav;
    107123
    108         bp_core_new_subnav_item( array(
    109             'name' => 'bar',
    110             'slug' => 'bar',
    111             'parent_slug' => 'foo',
    112             'parent_url' => 'foo',
     124        bp_core_new_nav_item( array(
     125            'name' => 'Foo',
     126            'slug' => 'foo',
    113127            'screen_function' => 'foo',
    114128            'link' => 'https://buddypress.org/',
    115129        ) );
    116130
     131        bp_core_new_subnav_item( array(
     132            'name' => 'bar',
     133            'slug' => 'bar',
     134            'parent_slug' => 'foo',
     135            'parent_url' => 'foo',
     136            'screen_function' => 'foo',
     137            'link' => 'https://buddypress.org/',
     138        ) );
     139
    117140        $this->assertSame( 'https://buddypress.org/', buddypress()->bp_options_nav['foo']['bar']['link'] );
    118141
     
    120143    }
    121144
     145    /**
     146     * @expectedIncorrectUsage bp_nav
     147     */
    122148    public function test_link_built_from_parent_url_and_slug() {
    123149        $bp_options_nav = buddypress()->bp_options_nav;
    124150
     151        bp_core_new_nav_item( array(
     152            'name' => 'Foo',
     153            'slug' => 'foo',
     154            'screen_function' => 'foo',
     155            'link' => 'https://buddypress.org/',
     156        ) );
     157
    125158        bp_core_new_subnav_item( array(
    126159            'name' => 'bar',
     
    136169    }
    137170
     171    /**
     172     * @expectedIncorrectUsage bp_nav
     173     */
    138174    public function test_link_built_from_parent_url_and_slug_where_slug_is_default() {
    139175        $bp_nav = buddypress()->bp_nav;
    140176        $bp_options_nav = buddypress()->bp_options_nav;
    141177
    142         // fake the parent
    143         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        ) );
    148184
    149185        bp_core_new_subnav_item( array(
     
    162198    }
    163199
     200    /**
     201     * @expectedIncorrectUsage bp_nav
     202     */
    164203    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
    165211        bp_core_new_subnav_item( array(
    166212            'name' => 'bar',
     
    175221    }
    176222
     223    /**
     224     * @expectedIncorrectUsage bp_nav
     225     */
    177226    public function test_should_trailingslash_link_when_link_is_autogenerated_not_using_slug() {
    178227        bp_core_new_nav_item( array(
     
    188237            'slug' => 'bar',
    189238            'parent_slug' => 'foo-parent',
    190             'parent_url' => bp_get_root_domain() . 'foo-parent/',
     239            'parent_url' => bp_get_root_domain() . '/foo-parent/',
    191240            'screen_function' => 'bar',
    192241        ) );
    193242
    194         $expected = bp_get_root_domain() . 'foo-parent/';
     243        $expected = bp_get_root_domain() . '/foo-parent/';
    195244        $this->assertSame( $expected, buddypress()->bp_options_nav['foo-parent']['bar']['link'] );
    196245    }
     
    198247    /**
    199248     * @ticket BP6353
     249     * @expectedIncorrectUsage bp_nav
    200250     */
    201251    public function test_link_should_not_trailingslash_link_explicit_link() {
    202252        $link = 'http://example.com/foo/bar/blah/?action=edit&id=30';
    203253
     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
    204261        bp_core_new_subnav_item( array(
    205262            'name' => 'bar',
     
    215272
    216273    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
    217280        // Should already be set to a 0 user.
    218281        $this->assertFalse( bp_current_user_can( 'bp_moderate' ) );
     
    229292    }
    230293
     294    /**
     295     * @expectedIncorrectUsage bp_nav
     296     */
    231297    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
    232304        $args = array(
    233305            'name' => 'Foo',
     
    242314    }
    243315
     316    /**
     317     * @expectedIncorrectUsage bp_nav
     318     */
    244319    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
    245326        $args = array(
    246327            'name' => 'Foo',
Note: See TracChangeset for help on using the changeset viewer.