Skip to:
Content

BuddyPress.org

Ticket #6503: 6503.01.patch

File 6503.01.patch, 18.0 KB (added by dcavins, 11 years ago)

Minimum change to separate the functions.

  • src/bp-core/bp-core-buddybar.php

    diff --git src/bp-core/bp-core-buddybar.php src/bp-core/bp-core-buddybar.php
    index ca87d9a..e64e960 100644
    function bp_core_new_nav_item( $args = '' ) { 
    5050        );
    5151
    5252        $r = wp_parse_args( $args, $defaults );
    53         extract( $r, EXTR_SKIP );
    5453
    5554        // If we don't have the required info we need, don't create this subnav item
    56         if ( empty( $name ) || empty( $slug ) )
     55        if ( empty( $r['name'] ) || empty( $r['slug'] ) ) {
    5756                return false;
     57        }
    5858
    5959        // If this is for site admins only and the user is not one, don't create the subnav item
    60         if ( !empty( $site_admin_only ) && !bp_current_user_can( 'bp_moderate' ) )
     60        if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) {
    6161                return false;
     62        }
    6263
    63         if ( empty( $item_css_id ) )
    64                 $item_css_id = $slug;
    65 
    66         $bp->bp_nav[$slug] = array(
    67                 'name'                    => $name,
    68                 'slug'                    => $slug,
    69                 'link'                    => trailingslashit( bp_loggedin_user_domain() . $slug ),
    70                 'css_id'                  => $item_css_id,
    71                 'show_for_displayed_user' => $show_for_displayed_user,
    72                 'position'                => $position,
    73                 'screen_function'         => &$screen_function,
    74                 'default_subnav_slug'     => $default_subnav_slug
     64        if ( empty( $r['item_css_id'] ) )
     65                $r['item_css_id'] = $r['slug'];
     66
     67        $bp->bp_nav[$r['slug']] = array(
     68                'name'                    => $r['name'],
     69                'slug'                    => $r['slug'],
     70                'link'                    => trailingslashit( bp_loggedin_user_domain() . $r['slug'] ),
     71                'css_id'                  => $r['item_css_id'],
     72                'show_for_displayed_user' => $r['show_for_displayed_user'],
     73                'position'                => $r['position'],
     74                'screen_function'         => &$r['screen_function'],
     75                'default_subnav_slug'     => $r['default_subnav_slug']
    7576        );
    7677
    7778        /**
    function bp_core_new_nav_item( $args = '' ) { 
    7980         * the logged in user is not the displayed user
    8081         * looking at their own profile, don't create the nav item.
    8182         */
    82         if ( empty( $show_for_displayed_user ) && !bp_user_has_access() )
     83        if ( empty( $r['show_for_displayed_user'] ) && ! bp_user_has_access() ) {
    8384                return false;
     85        }
    8486
    8587        /**
    8688         * If the nav item is visible, we are not viewing a user, and this is a root
    8789         * component, don't attach the default subnav function so we can display a
    8890         * directory or something else.
    8991         */
    90         if ( ( -1 != $position ) && bp_is_root_component( $slug ) && !bp_displayed_user_id() )
     92        if ( ( -1 != $r['position'] ) && bp_is_root_component( $r['slug'] ) && ! bp_displayed_user_id() )
    9193                return;
    9294
    9395        // Look for current component
    94         if ( bp_is_current_component( $slug ) || bp_is_current_item( $slug ) ) {
     96        if ( bp_is_current_component( $r['slug'] ) || bp_is_current_item( $r['slug'] ) ) {
    9597
    9698                // The requested URL has explicitly included the default subnav
    9799                // (eg: http://example.com/members/membername/activity/just-me/)
    98100                // The canonical version will not contain this subnav slug.
    99                 if ( !empty( $default_subnav_slug ) && bp_is_current_action( $default_subnav_slug ) && !bp_action_variable( 0 ) ) {
     101                if ( ! empty( $r['default_subnav_slug'] ) && bp_is_current_action( $r['default_subnav_slug'] ) && !bp_action_variable( 0 ) ) {
    100102                        unset( $bp->canonical_stack['action'] );
    101103                } elseif ( ! bp_current_action() ) {
    102104
    103105                        // Add our screen hook if screen function is callable
    104                         if ( is_callable( $screen_function ) ) {
    105                                 add_action( 'bp_screens', $screen_function, 3 );
     106                        if ( is_callable( $r['screen_function'] ) ) {
     107                                add_action( 'bp_screens', $r['screen_function'], 3 );
    106108                        }
    107109
    108                         if ( !empty( $default_subnav_slug ) ) {
     110                        if ( ! empty( $r['default_subnav_slug'] ) ) {
    109111
    110112                                /**
    111113                                 * Filters the default component subnav item.
    function bp_core_new_nav_item( $args = '' ) { 
    116118                                 *                                    to select when clicked.
    117119                                 * @param array  $r                   Parsed arguments for the nav item.
    118120                                 */
    119                                 $bp->current_action = apply_filters( 'bp_default_component_subnav', $default_subnav_slug, $r );
     121                                $bp->current_action = apply_filters( 'bp_default_component_subnav', $r['default_subnav_slug'], $r );
    120122                        }
    121123                }
    122124        }
    function bp_core_new_nav_default( $args = '' ) { 
    154156        );
    155157
    156158        $r = wp_parse_args( $args, $defaults );
    157         extract( $r, EXTR_SKIP );
    158159
    159         if ( $function = $bp->bp_nav[$parent_slug]['screen_function'] ) {
     160        if ( $function = $bp->bp_nav[$r['parent_slug']]['screen_function'] ) {
    160161                // Remove our screen hook if screen function is callable
    161162                if ( is_callable( $function ) ) {
    162163                        remove_action( 'bp_screens', $function, 3 );
    163164                }
    164165        }
    165166
    166         $bp->bp_nav[$parent_slug]['screen_function'] = &$screen_function;
     167        $bp->bp_nav[$r['parent_slug']]['screen_function'] = &$r['screen_function'];
    167168
    168         if ( bp_is_current_component( $parent_slug ) ) {
     169        if ( bp_is_current_component( $r['parent_slug'] ) ) {
    169170
    170171                // The only way to tell whether to set the subnav is to peek at the unfiltered_uri
    171172                // Find the component
    172                 $component_uri_key = array_search( $parent_slug, $bp->unfiltered_uri );
     173                $component_uri_key = array_search( $r['parent_slug'], $bp->unfiltered_uri );
    173174
    174175                if ( false !== $component_uri_key ) {
    175                         if ( !empty( $bp->unfiltered_uri[$component_uri_key + 1] ) ) {
     176                        if ( ! empty( $bp->unfiltered_uri[$component_uri_key + 1] ) ) {
    176177                                $unfiltered_action = $bp->unfiltered_uri[$component_uri_key + 1];
    177178                        }
    178179                }
    179180
    180181                // No subnav item has been requested in the URL, so set a new nav default
    181182                if ( empty( $unfiltered_action ) ) {
    182                         if ( !bp_is_current_action( $subnav_slug ) ) {
    183                                 if ( is_callable( $screen_function ) ) {
    184                                         add_action( 'bp_screens', $screen_function, 3 );
     183                        if ( ! bp_is_current_action( $r['subnav_slug'] ) ) {
     184                                if ( is_callable( $r['screen_function'] ) ) {
     185                                        add_action( 'bp_screens', $r['screen_function'], 3 );
    185186                                }
    186187
    187                                 $bp->current_action = $subnav_slug;
     188                                $bp->current_action = $r['subnav_slug'];
    188189                                unset( $bp->canonical_stack['action'] );
    189190                        }
    190191
    191192                // The URL is explicitly requesting the new subnav item, but should be
    192193                // directed to the canonical URL
    193                 } elseif ( $unfiltered_action == $subnav_slug ) {
     194                } elseif ( $unfiltered_action == $r['subnav_slug'] ) {
    194195                        unset( $bp->canonical_stack['action'] );
    195196
    196197                // In all other cases (including the case where the original subnav item
    function bp_core_new_subnav_item( $args = '' ) { 
    359360}
    360361
    361362/**
     363 * Add a subnav link to the BuddyPress navigation.
     364 *
     365 * @param array $args {
     366 *     Array describing the new subnav item.
     367 *     @type string $name Display name for the subnav item.
     368 *     @type string $slug Unique URL slug for the subnav item.
     369 *     @type string $parent_slug Slug of the top-level nav item under which the
     370 *           new subnav item should be added.
     371 *     @type string $parent_url URL of the parent nav item.
     372 *     @type bool|string $item_css_id Optional. 'id' attribute for the nav
     373 *           item. Default: the value of $slug.
     374 *     @type bool $user_has_access Optional. True if the logged-in user has
     375 *           access to the subnav item, otherwise false. Can be set dynamically
     376 *           when registering the subnav; eg, use bp_is_my_profile() to restrict
     377 *           access to profile owners only. Default: true.
     378 *     @type bool $site_admin_only Optional. Whether the nav item should be
     379 *           visible only to site admins (those with the 'bp_moderate' cap).
     380 *           Default: false.
     381 *     @type int $position Optional. Numerical index specifying where the item
     382 *           should appear in the subnav array. Default: 90.
     383 *     @type callable $screen_function The callback function that will run
     384 *           when the nav item is clicked.
     385 *     @type string $link Optional. The URL that the subnav item should point
     386 *           to. Defaults to a value generated from the $parent_url + $slug.
     387 *     @type bool $show_in_admin_bar Optional. Whether the nav item should be
     388 *           added into the group's "Edit" Admin Bar menu for group admins.
     389 *           Default: false.
     390 * }
     391 * @return bool|null Returns false on failure.
     392 */
     393function bp_core_create_subnav_link( $args = '' ) {
     394        $bp = buddypress();
     395
     396        $r = wp_parse_args( $args, array(
     397                'name'              => false, // Display name for the nav item
     398                'slug'              => false, // URL slug for the nav item
     399                'parent_slug'       => false, // URL slug of the parent nav item
     400                'parent_url'        => false, // URL of the parent item
     401                'item_css_id'       => false, // The CSS ID to apply to the HTML of the nav item
     402                'user_has_access'   => true,  // Can the logged in user see this nav item?
     403                'no_access_url'     => '',
     404                'site_admin_only'   => false, // Can only site admins see this nav item?
     405                'position'          => 90,    // Index of where this nav item should be positioned
     406                'screen_function'   => false, // The name of the function to run when clicked
     407                'link'              => '',    // The link for the subnav item; optional, not usually required.
     408                'show_in_admin_bar' => false, // Show the Manage link in the current group's "Edit" Admin Bar menu
     409        ) );
     410
     411        // If we don't have the required info we need, don't create this subnav item
     412        if ( empty( $r['name'] ) || empty( $r['slug'] ) || empty( $r['parent_slug'] ) || empty( $r['parent_url'] ) || empty( $r['screen_function'] ) )
     413                return false;
     414
     415        // Link was not forced, so create one
     416        if ( empty( $r['link'] ) ) {
     417                $r['link'] = trailingslashit( $r['parent_url'] . $r['slug'] );
     418
     419                // If this sub item is the default for its parent, skip the slug
     420                if ( ! empty( $bp->bp_nav[$r['parent_slug']]['default_subnav_slug'] ) && $r['slug'] == $bp->bp_nav[$r['parent_slug']]['default_subnav_slug'] ) {
     421                        $r['link'] = trailingslashit( $r['parent_url'] );
     422                }
     423        }
     424
     425        // If this is for site admins only and the user is not one, don't create the subnav item
     426        if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) {
     427                return false;
     428        }
     429
     430        if ( empty( $r['item_css_id'] ) ) {
     431                $r['item_css_id'] = $r['slug'];
     432        }
     433
     434        $subnav_item = array(
     435                'name'              => $r['name'],
     436                'link'              => $r['link'],
     437                'slug'              => $r['slug'],
     438                'css_id'            => $r['item_css_id'],
     439                'position'          => $r['position'],
     440                'user_has_access'   => $r['user_has_access'],
     441                'no_access_url'     => $r['no_access_url'],
     442                'screen_function'   => &$r['screen_function'],
     443                'show_in_admin_bar' => (bool) $r['show_in_admin_bar'],
     444        );
     445
     446        $bp->bp_options_nav[$r['parent_slug']][$r['slug']] = $subnav_item;
     447}
     448
     449/**
     450 * Register a screen function, whether or not a related subnav link exists.
     451 *
     452 * @param array $args {
     453 *     Array describing the new subnav item.
     454 *     @type string $slug Unique URL slug for the subnav item.
     455 *     @type string $parent_slug Slug of the top-level nav item under which the
     456 *           new subnav item should be added.
     457 *     @type string $parent_url URL of the parent nav item.
     458 *     @type bool $user_has_access Optional. True if the logged-in user has
     459 *           access to the subnav item, otherwise false. Can be set dynamically
     460 *           when registering the subnav; eg, use bp_is_my_profile() to restrict
     461 *           access to profile owners only. Default: true.
     462 *     @type bool $site_admin_only Optional. Whether the nav item should be
     463 *           visible only to site admins (those with the 'bp_moderate' cap).
     464 *           Default: false.
     465 *     @type int $position Optional. Numerical index specifying where the item
     466 *           should appear in the subnav array. Default: 90.
     467 *     @type callable $screen_function The callback function that will run
     468 *           when the nav item is clicked.
     469 *     @type string $link Optional. The URL that the subnav item should point
     470 *           to. Defaults to a value generated from the $parent_url + $slug.
     471 *     @type bool $show_in_admin_bar Optional. Whether the nav item should be
     472 *           added into the group's "Edit" Admin Bar menu for group admins.
     473 *           Default: false.
     474 * }
     475 * @return bool|null Returns false on failure.
     476 */
     477function bp_core_register_subnav_screen_function( $args = '' ) {
     478        $r = wp_parse_args( $args, array(
     479                'slug'              => false, // URL slug for the screen
     480                'parent_slug'       => false, // URL slug of the parent screen
     481                'user_has_access'   => true,  // Can the user visit this screen?
     482                'no_access_url'     => '',
     483                'site_admin_only'   => false, // Can only site admins visit this screen?
     484                'screen_function'   => false, // The name of the function to run when clicked
     485        ) );
     486
     487        /**
     488         * Hook the screen function for the added subnav item. But this only needs to
     489         * be done if this subnav item is the current view, and the user has access to the
     490         * subnav item. We figure out whether we're currently viewing this subnav by
     491         * checking the following two conditions:
     492         *   (1) Either:
     493         *           (a) the parent slug matches the current_component, or
     494         *           (b) the parent slug matches the current_item
     495         *   (2) And either:
     496         *           (a) the current_action matches $slug, or
     497         *       (b) there is no current_action (ie, this is the default subnav for the parent nav)
     498         *           and this subnav item is the default for the parent item (which we check by
     499         *           comparing this subnav item's screen function with the screen function of the
     500         *           parent nav item in $bp->bp_nav). This condition only arises when viewing a
     501         *           user, since groups should always have an action set.
     502         */
     503
     504        // If we *don't* meet condition (1), return
     505        if ( ! bp_is_current_component( $r['parent_slug'] ) && ! bp_is_current_item( $r['parent_slug'] ) ) {
     506                return;
     507        }
     508
     509        // If we *do* meet condition (2), then the added subnav item is currently being requested
     510        if ( ( bp_current_action() && bp_is_current_action( $r['slug'] ) ) || ( bp_is_user() && ! bp_current_action() && ( $r['screen_function'] == $bp->bp_nav[$parent_slug]['screen_function'] ) ) ) {
     511
     512                // If this is for site admins only and the user is not one, don't create the subnav item
     513                if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) {
     514                        return false;
     515                }
     516
     517                $hooked = bp_core_maybe_hook_new_subnav_screen_function( $r );
     518
     519                // If redirect args have been returned, perform the redirect now
     520                if ( ! empty( $hooked['status'] ) && 'failure' === $hooked['status'] && isset( $hooked['redirect_args'] ) ) {
     521                        bp_core_no_access( $hooked['redirect_args'] );
     522                }
     523        }
     524
     525}
     526
     527/**
    362528 * For a given subnav item, either hook the screen function or generate redirect arguments, as necessary.
    363529 *
    364530 * @since BuddyPress (2.1.0)
    function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ) { 
    372538                'status' => '',
    373539        );
    374540
     541        // Is this accessible by site admins only?
     542        $site_admin_restricted = false;
     543        if ( ! empty( $subnav_item['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) {
     544                $site_admin_restricted = true;
     545        }
     546
    375547        // User has access, so let's try to hook the display callback
    376         if ( ! empty( $subnav_item['user_has_access'] ) ) {
     548        if ( ! empty( $subnav_item['user_has_access'] ) && ! $site_admin_restricted ) {
    377549
    378550                // Screen function is invalid
    379551                if ( ! is_callable( $subnav_item['screen_function'] ) ) {
  • src/bp-core/bp-core-component.php

    diff --git src/bp-core/bp-core-component.php src/bp-core/bp-core-component.php
    index a24de99..6775cb7 100644
    class BP_Component { 
    469469                        // Sub nav items are not required
    470470                        if ( !empty( $sub_nav ) ) {
    471471                                foreach( (array) $sub_nav as $nav ) {
    472                                         bp_core_new_subnav_item( $nav );
     472                                        bp_core_create_subnav_link( $nav );
     473                                        bp_core_register_subnav_screen_function( $nav );
    473474                                }
    474475                        }
    475476                }
  • 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 02374dd..8f36af6 100644
    class BP_Group_Extension { 
    735735                        return;
    736736                }
    737737
     738                // If the user can see the nav item, we create it.
    738739                $user_can_see_nav_item = $this->user_can_see_nav_item();
    739740
    740741                if ( $user_can_see_nav_item ) {
    741742                        $group_permalink = bp_get_group_permalink( groups_get_current_group() );
    742743
    743                         bp_core_new_subnav_item( array(
     744                        bp_core_create_subnav_link( array(
    744745                                'name'            => ! $this->nav_item_name ? $this->name : $this->nav_item_name,
    745746                                'slug'            => $this->slug,
    746747                                'parent_slug'     => bp_get_current_group_slug(),
    class BP_Group_Extension { 
    751752                                'user_has_access' => $user_can_see_nav_item,
    752753                                'no_access_url'   => $group_permalink,
    753754                        ) );
     755                }
     756
     757                // If the user can visit the screen, we register it.
     758                $user_can_visit = $this->user_can_visit();
     759
     760                if ( $user_can_visit ) {
     761                        $group_permalink = bp_get_group_permalink( groups_get_current_group() );
     762
     763                        bp_core_register_subnav_screen_function( array(
     764                                'slug'            => $this->slug,
     765                                'parent_slug'     => bp_get_current_group_slug(),
     766                                'screen_function' => array( &$this, '_display_hook' ),
     767                                'user_has_access' => $user_can_visit,
     768                                'no_access_url'   => $group_permalink,
     769                        ) );
    754770
    755771                        // When we are viewing the extension display page, set the title and options title
    756772                        if ( bp_is_current_action( $this->slug ) ) {
  • src/bp-xprofile/bp-xprofile-loader.php

    diff --git src/bp-xprofile/bp-xprofile-loader.php src/bp-xprofile/bp-xprofile-loader.php
    index a38b21b..b9f9dac 100644
    class BP_XProfile_Component extends BP_Component { 
    260260                // Get the settings slug
    261261                $settings_slug = bp_get_settings_slug();
    262262
    263                 bp_core_new_subnav_item( array(
     263                $nav_args = array(
    264264                        'name'            => _x( 'Profile Visibility', 'Profile settings sub nav', 'buddypress' ),
    265265                        'slug'            => 'profile',
    266266                        'parent_url'      => trailingslashit( $user_domain . $settings_slug ),
    class BP_XProfile_Component extends BP_Component { 
    268268                        'screen_function' => 'bp_xprofile_screen_settings',
    269269                        'position'        => 30,
    270270                        'user_has_access' => bp_core_can_edit_settings()
    271                 ) );
     271                );
     272
     273                bp_core_create_subnav_link( $nav_args );
     274                bp_core_register_subnav_screen_function( $nav_args );
    272275        }
    273276
    274277        /**