false, // Display name for the nav item. 'slug' => false, // URL slug for the nav item. 'component_id' => '', // ID of the component registering the nav item. 'item_css_id' => false, // The CSS ID to apply to the HTML of the nav item. 'show_for_displayed_user' => true, // When viewing another user does this nav item show up? 'site_admin_only' => false, // Can only site admins see this nav item? 'position' => 99, // Index of where this nav item should be positioned. 'screen_function' => false, // The name of the function to run when clicked. 'default_subnav_slug' => false, // The slug of the default subnav item to select when clicked. ); $r = bp_parse_args( $args, $defaults ); // Validate nav link data. $nav_item = bp_core_create_nav_link( $r, $component ); /* * To mimic legacy behavior, if bp_core_create_nav_link() returns false, we make * an early exit and don't attempt to register the screen function. */ if ( false === $nav_item ) { return false; } // Then, hook the screen function for the added nav item. $hooked = bp_core_register_nav_screen_function( $nav_item ); if ( false === $hooked ){ return false; } /** * Fires after adding an item to the main BuddyPress navigation array. * Note that, when possible, the more specific action hooks * `bp_core_create_nav_link` or `bp_core_register_nav_screen_function` * should be used. * * @since 1.5.0 * * @param array $r Parsed arguments for the nav item. * @param array $args Originally passed in arguments for the nav item. * @param array $defaults Default arguments for a nav item. */ do_action( 'bp_core_new_nav_item', $r, $args, $defaults ); } /** * Add a link to the main BuddyPress navigation. * * @since 2.4.0 * @since 2.6.0 Introduced the `$component` parameter. Began returning a BP_Core_Nav_Item * object on success. * @since 4.0.0 Introduced `$component_id` argument. * * @param array|string $args { * Array describing the new nav item. * @type string $component_id Optional. The ID of the component registering this nav item. Defaults to the * the value of `$slug`. * @type string $name Display name for the nav item. * @type string $slug Unique URL slug for the nav item. * @type bool|string $item_css_id Optional. 'id' attribute for the nav item. Default: the value of `$slug`. * @type bool $show_for_displayed_user Optional. Whether the nav item should be visible when viewing a * member profile other than your own. Default: true. * @type bool $site_admin_only Optional. Whether the nav item should be visible only to site admins * (those with the 'bp_moderate' cap). Default: false. * @type int $position Optional. Numerical index specifying where the item should appear in * the nav array. Default: 99. * @type callable $screen_function The callback function that will run when the nav item is clicked. * @type bool|string $default_subnav_slug Optional. The slug of the default subnav item to select when the nav * item is clicked. * } * @param string $component Optional. Component that the nav belongs to. * @return false|array Returns false on failure, new nav item on success. */ function bp_core_create_nav_link( $args = '', $component = 'members' ) { $bp = buddypress(); $defaults = array( 'component_id' => '', // The component ID registering this nav item. 'name' => false, // Display name for the nav item. 'slug' => false, // URL slug for the nav item. 'item_css_id' => false, // The CSS ID to apply to the HTML of the nav item. 'show_for_displayed_user' => true, // When viewing another user does this nav item show up? 'site_admin_only' => false, // Can only site admins see this nav item? 'position' => 99, // Index of where this nav item should be positioned. 'screen_function' => false, // The name of the function to run when clicked. 'default_subnav_slug' => false // The slug of the default subnav item to select when clicked. ); $r = bp_parse_args( $args, $defaults ); // If we don't have the required info we need, don't create this nav item. if ( empty( $r['name'] ) || empty( $r['slug'] ) ) { return false; } // If this is for site admins only and the user is not one, don't create the nav item. if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) { return false; } if ( empty( $r['component_id'] ) ) { $r['component_id'] = $r['slug']; } if ( empty( $r['item_css_id'] ) ) { $r['item_css_id'] = $r['slug']; } $nav_item = array( 'component_id' => $r['component_id'], 'name' => $r['name'], 'slug' => $r['slug'], 'link' => trailingslashit( bp_loggedin_user_domain() . $r['slug'] ), 'css_id' => $r['item_css_id'], 'show_for_displayed_user' => $r['show_for_displayed_user'], 'position' => $r['position'], 'screen_function' => &$r['screen_function'], 'default_subnav_slug' => $r['default_subnav_slug'] ); // Add the item to the nav. buddypress()->{$component}->nav->add_nav( $nav_item ); /** * Fires after a link is added to the main BuddyPress nav. * * @since 2.4.0 * @since 2.6.0 Added `$component` parameter. * * @param array $r Parsed arguments for the nav item. * @param array $args Originally passed in arguments for the nav item. * @param array $defaults Default arguments for a nav item. * @param string $component Component that the nav belongs to. */ do_action( 'bp_core_create_nav_link', $r, $args, $defaults, $component ); return $nav_item; } /** * Register a screen function for an item in the main nav array. * * @since 2.4.0 * * @param array|string $args { * Array describing the new nav item. * @type string $name Display name for the nav item. * @type string $slug Unique URL slug for the nav item. * @type bool|string $item_css_id Optional. 'id' attribute for the nav item. Default: the value of `$slug`. * @type bool $show_for_displayed_user Optional. Whether the nav item should be visible when viewing a * member profile other than your own. Default: true. * @type bool $site_admin_only Optional. Whether the nav item should be visible only to site admins * (those with the 'bp_moderate' cap). Default: false. * @type int $position Optional. Numerical index specifying where the item should appear in * the nav array. Default: 99. * @type callable $screen_function The callback function that will run when the nav item is clicked. * @type bool|string $default_subnav_slug Optional. The slug of the default subnav item to select when the nav * item is clicked. * } * @return false|null Returns false on failure. */ function bp_core_register_nav_screen_function( $args = '' ) { $bp = buddypress(); $defaults = array( 'name' => false, // Display name for the nav item. 'slug' => false, // URL slug for the nav item. 'item_css_id' => false, // The CSS ID to apply to the HTML of the nav item. 'show_for_displayed_user' => true, // When viewing another user does this nav item show up? 'site_admin_only' => false, // Can only site admins see this nav item? 'position' => 99, // Index of where this nav item should be positioned. 'screen_function' => false, // The name of the function to run when clicked. 'default_subnav_slug' => false // The slug of the default subnav item to select when clicked. ); $r = bp_parse_args( $args, $defaults ); // If we don't have the required info we need, don't register this screen function. if ( empty( $r['slug'] ) ) { return false; } /** * If this is for site admins only and the user is not one, * don't register this screen function. */ if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) { return false; } /** * If this nav item is hidden for the displayed user, and * the logged in user is not the displayed user * looking at their own profile, don't don't register this screen function. */ if ( empty( $r['show_for_displayed_user'] ) && ! bp_user_has_access() ) { return false; } /** * If the nav item is visible, we are not viewing a user, and this is a root * component, don't attach the default subnav function so we can display a * directory or something else. */ if ( ( -1 != $r['position'] ) && bp_is_root_component( $r['slug'] ) && ! bp_displayed_user_id() ) { return; } // Look for current component. if ( bp_is_current_component( $r['slug'] ) || bp_is_current_item( $r['slug'] ) ) { // The requested URL has explicitly included the default subnav // (eg: http://example.com/members/membername/activity/just-me/) // The canonical version will not contain this subnav slug. if ( ! empty( $r['default_subnav_slug'] ) && bp_is_current_action( $r['default_subnav_slug'] ) && ! bp_action_variable( 0 ) ) { unset( $bp->canonical_stack['action'] ); } elseif ( ! bp_current_action() ) { // Add our screen hook if screen function is callable. if ( is_callable( $r['screen_function'] ) ) { add_action( 'bp_screens', $r['screen_function'], 3 ); } if ( ! empty( $r['default_subnav_slug'] ) ) { /** * Filters the default component subnav item. * * @since 1.5.0 * * @param string $value The slug of the default subnav item * to select when clicked. * @param array $r Parsed arguments for the nav item. */ $bp->current_action = apply_filters( 'bp_default_component_subnav', $r['default_subnav_slug'], $r ); } } } /** * Fires after the screen function for an item in the BuddyPress main * navigation is registered. * * @since 2.4.0 * * @param array $r Parsed arguments for the nav item. * @param array $args Originally passed in arguments for the nav item. * @param array $defaults Default arguments for a nav item. */ do_action( 'bp_core_register_nav_screen_function', $r, $args, $defaults ); } /** * Modify the default subnav item that loads when a top level nav item is clicked. * * @since 1.1.0 * * @param array|string $args { * @type string $parent_slug The slug of the nav item whose default is being changed. * @type callable $screen_function The new default callback function that will run when the nav item is clicked. * @type string $subnav_slug The slug of the new default subnav item. * } */ function bp_core_new_nav_default( $args = '' ) { $bp = buddypress(); $defaults = array( 'parent_slug' => false, // Slug of the parent. 'screen_function' => false, // The name of the function to run when clicked. 'subnav_slug' => false // The slug of the subnav item to select when clicked. ); $r = bp_parse_args( $args, $defaults ); // This is specific to Members - it's not available in Groups. $parent_nav = $bp->members->nav->get_primary( array( 'slug' => $r['parent_slug'] ), false ); if ( ! $parent_nav ) { return ; } $parent_nav = reset( $parent_nav ); // Edit the screen function for the parent nav. $bp->members->nav->edit_nav( array( 'screen_function' => &$r['screen_function'], 'default_subnav_slug' => $r['subnav_slug'], ), $parent_nav->slug ); /** * Update secondary nav items: * - The previous default nav item needs to have its slug added to its link property. * - The new default nav item needs to have its slug removed from its link property. */ $previous_default_subnav = $bp->members->nav->get( $parent_nav->slug . '/' . $parent_nav->default_subnav_slug ); // Edit the link of the previous default nav item. $bp->members->nav->edit_nav( array( 'link' => trailingslashit( $previous_default_subnav->link . $previous_default_subnav->slug ), ), $previous_default_subnav->slug, $parent_nav->slug ); $new_default_subnav = $bp->members->nav->get( $parent_nav->slug . '/' . $r['subnav_slug'] ); // Edit the link of the new default nav item. $bp->members->nav->edit_nav( array( 'link' => rtrim( untrailingslashit( $new_default_subnav->link ), $new_default_subnav->slug ), ), $new_default_subnav->slug, $parent_nav->slug ); if ( bp_is_current_component( $parent_nav->slug ) ) { // The only way to tell whether to set the subnav is to peek at the unfiltered_uri // Find the component. $component_uri_key = array_search( $parent_nav->slug, $bp->unfiltered_uri ); if ( false !== $component_uri_key ) { if ( ! empty( $bp->unfiltered_uri[$component_uri_key + 1] ) ) { $unfiltered_action = $bp->unfiltered_uri[$component_uri_key + 1]; } } // No subnav item has been requested in the URL, so set a new nav default. if ( empty( $unfiltered_action ) ) { if ( ! bp_is_current_action( $r['subnav_slug'] ) ) { /* * If the screen function isn't available, attempt to find it. * * This is due to our conditional-loading code since v3.0.0. */ if ( ! is_callable( $r['screen_function'] ) && ! empty( $parent_nav->component_id ) ) { $file = $bp->core->path . 'bp-' . $parent_nav->component_id . '/screens/' . $r['subnav_slug'] . '.php'; $file_path = realpath( $file ); // Found the file, so require it. if ( $file === $file_path && file_exists( $file ) ) { require_once $file; } } if ( is_callable( $r['screen_function'] ) ) { add_action( 'bp_screens', $r['screen_function'], 3 ); } $bp->current_action = $r['subnav_slug']; unset( $bp->canonical_stack['action'] ); } // The URL is explicitly requesting the new subnav item, but should be // directed to the canonical URL. } elseif ( $unfiltered_action == $r['subnav_slug'] ) { unset( $bp->canonical_stack['action'] ); // In all other cases (including the case where the original subnav item // is explicitly called in the URL), the canonical URL will contain the // subnav slug. } else { $bp->canonical_stack['action'] = bp_current_action(); } } return; } /** * Add an item to secondary navigation of the specified component. * * @since 1.1.0 * @since 2.6.0 Introduced the `$component` parameter. * * @param array|string $args { * Array describing the new subnav item. * @type string $name Display name for the subnav item. * @type string $slug Unique URL slug for the subnav item. * @type string $parent_slug Slug of the top-level nav item under which the new subnav item should * be added. * @type string $parent_url URL of the parent nav item. * @type bool|string $item_css_id Optional. 'id' attribute for the nav item. Default: the value of `$slug`. * @type bool $user_has_access Optional. True if the logged-in user has access to the subnav item, * otherwise false. Can be set dynamically when registering the subnav; * eg, use `bp_is_my_profile()` to restrict access to profile owners only. * Default: true. * @type bool $site_admin_only Optional. Whether the nav item should be visible only to site admins * (those with the 'bp_moderate' cap). Default: false. * @type int $position Optional. Numerical index specifying where the item should appear in the * subnav array. Default: 90. * @type callable $screen_function The callback function that will run when the nav item is clicked. * @type string $link Optional. The URL that the subnav item should point to. Defaults to a value * generated from the `$parent_url` + `$slug`. * @type bool $show_in_admin_bar Optional. Whether the nav item should be added into the group's "Edit" * Admin Bar menu for group admins. Default: false. * } * @param string|null $component The component the navigation is attached to. Defaults to 'members'. * @return null|false Returns false on failure. */ function bp_core_new_subnav_item( $args, $component = null ) { // Backward compatibility for plugins using `bp_core_new_subnav_item()` without `$component` // to add group subnav items. if ( null === $component && bp_is_active( 'groups' ) && bp_is_group() && isset( $args['parent_slug'] ) ) { /* * Assume that this item is intended to belong to the current group if: * a) the 'parent_slug' is the same as the slug of the current group, or * b) the 'parent_slug' starts with the slug of the current group, and the members nav doesn't have * a primary item with that slug. */ $group_slug = bp_get_current_group_slug(); if ( $group_slug === $args['parent_slug'] || ( 0 === strpos( $args['parent_slug'], $group_slug ) && ! buddypress()->members->nav->get_primary( array( 'slug' => $args['parent_slug'] ), false ) ) ) { $component = 'groups'; } } if ( ! $component ) { $component = 'members'; } if ( ! bp_is_active( $component ) ) { return; } // First, register the subnav item in the nav. $subnav_item = bp_core_create_subnav_link( $args, $component ); /* * To mimic legacy behavior, if bp_core_create_subnav_link() returns false, we make an * early exit and don't attempt to register the screen function. */ if ( false === $subnav_item ) { return false; } // Then, hook the screen function for the added subnav item. $hooked = bp_core_register_subnav_screen_function( $subnav_item, $component ); if ( false === $hooked ) { return false; } } /** * Add a subnav link to the BuddyPress navigation. * * @since 2.4.0 * @since 2.6.0 Introduced the `$component` parameter. Began returning a BP_Core_Nav_Item object on success. * * @param array|string $args { * Array describing the new subnav item. * @type string $name Display name for the subnav item. * @type string $slug Unique URL slug for the subnav item. * @type string $parent_slug Slug of the top-level nav item under which the * new subnav item should be added. * @type string $parent_url URL of the parent nav item. * @type bool|string $item_css_id Optional. 'id' attribute for the nav * item. Default: the value of $slug. * @type bool $user_has_access Optional. True if the logged-in user has access to the * subnav item, otherwise false. Can be set dynamically * when registering the subnav; eg, use bp_is_my_profile() * to restrict access to profile owners only. Default: true. * @type bool $site_admin_only Optional. Whether the nav item should be visible only * to site admins (those with the 'bp_moderate' cap). * Default: false. * @type int $position Optional. Numerical index specifying where the item * should appear in the subnav array. Default: 90. * @type callable $screen_function The callback function that will run * when the nav item is clicked. * @type string $link Optional. The URL that the subnav item should point * to. Defaults to a value generated from the $parent_url + $slug. * @type bool $show_in_admin_bar Optional. Whether the nav item should be added into * the group's "Edit" Admin Bar menu for group admins. * Default: false. * } * @param string $component The component the navigation is attached to. Defaults to 'members'. * @return false|array Returns false on failure, new BP_Core_Nav_Item instance on success. */ function bp_core_create_subnav_link( $args = '', $component = 'members' ) { $bp = buddypress(); $r = bp_parse_args( $args, array( 'name' => false, // Display name for the nav item. 'slug' => false, // URL slug for the nav item. 'parent_slug' => false, // URL slug of the parent nav item. 'parent_url' => false, // URL of the parent item. 'item_css_id' => false, // The CSS ID to apply to the HTML of the nav item. 'user_has_access' => true, // Can the logged in user see this nav item? 'no_access_url' => '', 'site_admin_only' => false, // Can only site admins see this nav item? 'position' => 90, // Index of where this nav item should be positioned. 'screen_function' => false, // The name of the function to run when clicked. 'link' => '', // The link for the subnav item; optional, not usually required. 'show_in_admin_bar' => false, // Show the Manage link in the current group's "Edit" Admin Bar menu. ) ); // If we don't have the required info we need, don't create this subnav item. if ( empty( $r['name'] ) || empty( $r['slug'] ) || empty( $r['parent_slug'] ) || empty( $r['parent_url'] ) || empty( $r['screen_function'] ) ) return false; // Link was not forced, so create one. if ( empty( $r['link'] ) ) { $r['link'] = trailingslashit( $r['parent_url'] . $r['slug'] ); $parent_nav = $bp->{$component}->nav->get_primary( array( 'slug' => $r['parent_slug'] ), false ); // If this sub item is the default for its parent, skip the slug. if ( $parent_nav ) { $parent_nav_item = reset( $parent_nav ); if ( ! empty( $parent_nav_item->default_subnav_slug ) && $r['slug'] === $parent_nav_item->default_subnav_slug ) { $r['link'] = trailingslashit( $r['parent_url'] ); } } } // If this is for site admins only and the user is not one, don't create the subnav item. if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) { return false; } if ( empty( $r['item_css_id'] ) ) { $r['item_css_id'] = $r['slug']; } $subnav_item = array( 'name' => $r['name'], 'link' => $r['link'], 'slug' => $r['slug'], 'parent_slug' => $r['parent_slug'], 'css_id' => $r['item_css_id'], 'position' => $r['position'], 'user_has_access' => $r['user_has_access'], 'no_access_url' => $r['no_access_url'], 'screen_function' => &$r['screen_function'], 'show_in_admin_bar' => (bool) $r['show_in_admin_bar'], ); buddypress()->{$component}->nav->add_nav( $subnav_item ); return $subnav_item; } /** * Register a screen function, whether or not a related subnav link exists. * * @since 2.4.0 * @since 2.6.0 Introduced the `$component` parameter. * * @param array|string $args { * Array describing the new subnav item. * @type string $slug Unique URL slug for the subnav item. * @type string $parent_slug Slug of the top-level nav item under which the * new subnav item should be added. * @type string $parent_url URL of the parent nav item. * @type bool $user_has_access Optional. True if the logged-in user has access to the * subnav item, otherwise false. Can be set dynamically * when registering the subnav; eg, use bp_is_my_profile() * to restrict access to profile owners only. Default: true. * @type bool $site_admin_only Optional. Whether the nav item should be visible * only to site admins (those with the 'bp_moderate' cap). * Default: false. * @type int $position Optional. Numerical index specifying where the item * should appear in the subnav array. Default: 90. * @type callable $screen_function The callback function that will run * when the nav item is clicked. * @type string $link Optional. The URL that the subnav item should point to. * Defaults to a value generated from the $parent_url + $slug. * @type bool $show_in_admin_bar Optional. Whether the nav item should be added into * the group's "Edit" Admin Bar menu for group admins. * Default: false. * } * @param string $component The component the navigation is attached to. Defaults to 'members'. * @return null|false Returns false on failure. */ function bp_core_register_subnav_screen_function( $args = '', $component = 'members' ) { $bp = buddypress(); $r = bp_parse_args( $args, array( 'slug' => false, // URL slug for the screen. 'parent_slug' => false, // URL slug of the parent screen. 'user_has_access' => true, // Can the user visit this screen? 'no_access_url' => '', 'site_admin_only' => false, // Can only site admins visit this screen? 'screen_function' => false, // The name of the function to run when clicked. ) ); /* * Hook the screen function for the added subnav item. But this only needs to * be done if this subnav item is the current view, and the user has access to the * subnav item. We figure out whether we're currently viewing this subnav by * checking the following two conditions: * (1) Either: * (a) the parent slug matches the current_component, or * (b) the parent slug matches the current_item * (2) And either: * (a) the current_action matches $slug, or * (b) there is no current_action (ie, this is the default subnav for the parent nav) * and this subnav item is the default for the parent item (which we check by * comparing this subnav item's screen function with the screen function of the * parent nav item in the component's primary nav). This condition only arises * when viewing a user, since groups should always have an action set. */ // If we *don't* meet condition (1), return. if ( ! bp_is_current_component( $r['parent_slug'] ) && ! bp_is_current_item( $r['parent_slug'] ) ) { return; } $parent_nav = $bp->{$component}->nav->get_primary( array( 'slug' => $r['parent_slug'] ), false ); if ( is_array( $parent_nav ) ) { $parent_nav = reset( $parent_nav ); } // If we *do* meet condition (2), then the added subnav item is currently being requested. if ( ( bp_current_action() && bp_is_current_action( $r['slug'] ) ) || ( bp_is_user() && ! bp_current_action() && ! empty( $parent_nav->screen_function ) && $r['screen_function'] == $parent_nav->screen_function ) ) { // If this is for site admins only and the user is not one, don't create the subnav item. if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) { return false; } $hooked = bp_core_maybe_hook_new_subnav_screen_function( $r, $component ); // If redirect args have been returned, perform the redirect now. if ( ! empty( $hooked['status'] ) && 'failure' === $hooked['status'] && isset( $hooked['redirect_args'] ) ) { bp_core_no_access( $hooked['redirect_args'] ); } } } /** * For a given subnav item, either hook the screen function or generate redirect arguments, as necessary. * * @since 2.1.0 * @since 2.6.0 Introduced the `$component` parameter. * * @param array $subnav_item The subnav array added to the secondary navigation of * the component in bp_core_new_subnav_item(). * @param string $component The component the navigation is attached to. Defaults to 'members'. * @return array */ function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item, $component = 'members' ) { $retval = array( 'status' => '', ); // Is this accessible by site admins only? $site_admin_restricted = false; if ( ! empty( $subnav_item['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) { $site_admin_restricted = true; } // User has access, so let's try to hook the display callback. if ( ! empty( $subnav_item['user_has_access'] ) && ! $site_admin_restricted ) { // Screen function is invalid. if ( ! is_callable( $subnav_item['screen_function'] ) ) { $retval['status'] = 'failure'; // Success - hook to bp_screens. } else { add_action( 'bp_screens', $subnav_item['screen_function'], 3 ); $retval['status'] = 'success'; } // User doesn't have access. Determine redirect arguments based on // user status. } else { $retval['status'] = 'failure'; if ( is_user_logged_in() ) { $bp = buddypress(); // If a redirect URL has been passed to the subnav item, respect it. if ( ! empty( $subnav_item['no_access_url'] ) ) { $message = __( 'You do not have access to that page.', 'buddypress' ); $redirect_to = trailingslashit( $subnav_item['no_access_url'] ); // In the case of a user page, we try to assume a // redirect URL. } elseif ( bp_is_user() ) { $parent_nav_default = $bp->{$component}->nav->get_primary( array( 'slug' => $bp->default_component ), false ); if ( $parent_nav_default ) { $parent_nav_default_item = reset( $parent_nav_default ); } // Redirect to the displayed user's default // component, as long as that component is // publicly accessible. if ( bp_is_my_profile() || ( isset( $parent_nav_default_item ) && $parent_nav_default_item->show_for_displayed_user ) ) { $message = __( 'You do not have access to that page.', 'buddypress' ); $redirect_to = bp_displayed_user_domain(); // In some cases, the default tab is not accessible to // the logged-in user. So we fall back on a tab that we // know will be accessible. } else { // Try 'activity' first. if ( bp_is_active( 'activity' ) && isset( $bp->pages->activity ) ) { $redirect_to = trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() ); // Then try 'profile'. } else { $redirect_to = trailingslashit( bp_displayed_user_domain() . ( 'xprofile' == $bp->profile->id ? 'profile' : $bp->profile->id ) ); } $message = ''; } // Fall back to the home page. } else { $message = __( 'You do not have access to this page.', 'buddypress' ); $redirect_to = bp_get_root_domain(); } $retval['redirect_args'] = array( 'message' => $message, 'root' => $redirect_to, 'redirect' => false, 'mode' => 1 ); } else { // When the user is logged out, pass an empty array // This indicates that the default arguments should be // used in bp_core_no_access(). $retval['redirect_args'] = array(); } } return $retval; } /** * Check whether a given nav item has subnav items. * * @since 1.5.0 * @since 2.6.0 Introduced the `$component` parameter. * * @param string $nav_item The slug of the top-level nav item whose subnav items you're checking. * Default: the current component slug. * @param string $component The component the navigation is attached to. Defaults to 'members'. * @return bool $has_subnav True if the nav item is found and has subnav items; false otherwise. */ function bp_nav_item_has_subnav( $nav_item = '', $component = 'members' ) { $bp = buddypress(); if ( ! isset( $bp->{$component}->nav ) ) { return false; } if ( ! $nav_item ) { $nav_item = bp_current_component(); if ( bp_is_group() ) { $nav_item = bp_current_item(); } } $has_subnav = (bool) $bp->{$component}->nav->get_secondary( array( 'parent_slug' => $nav_item ), false ); /** * Filters whether or not a given nav item has subnav items. * * @since 1.5.0 * * @param bool $has_subnav Whether or not there is any subnav items. * @param string $nav_item The slug of the top-level nav item whose subnav items you're checking. */ return apply_filters( 'bp_nav_item_has_subnav', $has_subnav, $nav_item ); } /** * Deletes an item from the primary navigation of the specified component. * * @since 1.0.0 * @since 2.6.0 Introduced the `$component` parameter. * * @param string $slug The slug of the primary navigation item. * @param string|null $component The component the navigation is attached to. Defaults to 'members'. * @return bool Returns false on failure, True on success. */ function bp_core_remove_nav_item( $slug, $component = null ) { $bp = buddypress(); // Backward compatibility for removing group nav items using the group slug as `$parent_slug`. if ( ! $component && bp_is_active( 'groups' ) && isset( $bp->groups->nav ) ) { if ( $bp->groups->nav->get_primary( array( 'slug' => $slug ) ) ) { $component = 'groups'; } } if ( ! $component ) { $component = 'members'; } if ( ! isset( $bp->{$component}->nav ) ) { return false; } $screen_functions = $bp->{$component}->nav->delete_nav( $slug ); // Reset backcompat nav items so that subsequent references will be correct. $bp->bp_nav->reset(); $bp->bp_options_nav->reset(); if ( ! is_array( $screen_functions ) ) { return false; } foreach ( $screen_functions as $screen_function ) { // Remove our screen hook if screen function is callable. if ( is_callable( $screen_function ) ) { remove_action( 'bp_screens', $screen_function, 3 ); } } return true; } /** * Deletes an item from the secondary navigation of the specified component. * * @since 1.0.0 * @since 2.6.0 Introduced the `$component` parameter. * * @param string $parent_slug The slug of the primary navigation item. * @param string $slug The slug of the secondary item to be removed. * @param string|null $component The component the navigation is attached to. Defaults to 'members'. * @return bool Returns false on failure, True on success. */ function bp_core_remove_subnav_item( $parent_slug, $slug, $component = null ) { $bp = buddypress(); // Backward compatibility for removing group nav items using the group slug as `$parent_slug`. if ( ! $component && bp_is_active( 'groups' ) && isset( $bp->groups->nav ) ) { if ( $bp->groups->nav->get_primary( array( 'slug' => $parent_slug ) ) ) { $component = 'groups'; } } if ( ! $component ) { $component = 'members'; } if ( ! isset( $bp->{$component}->nav ) ) { return false; } $screen_functions = $bp->{$component}->nav->delete_nav( $slug, $parent_slug ); // Reset backcompat nav items so that subsequent references will be correct. $bp->bp_nav->reset(); $bp->bp_options_nav->reset(); if ( ! is_array( $screen_functions ) ) { return false; } $screen_function = reset( $screen_functions ); // Remove our screen hook if screen function is callable. if ( is_callable( $screen_function ) ) { remove_action( 'bp_screens', $screen_function, 3 ); } return true; } /** * Clear all subnav items from a specific nav item. * * @since 1.0.0 * @since 2.6.0 Introduced the `$component` parameter. * * @param string $parent_slug The slug of the parent navigation item. * @param string $component The component the navigation is attached to. Defaults to 'members'. */ function bp_core_reset_subnav_items( $parent_slug, $component = 'members' ) { $bp = buddypress(); if ( ! isset( $bp->{$component}->nav ) ) { return; } $subnav_items = $bp->{$component}->nav->get_secondary( array( 'parent_slug' => $parent_slug ), false ); if ( ! $subnav_items ) { return; } foreach( $subnav_items as $subnav_item ) { $bp->{$component}->nav->delete_nav( $subnav_item->slug, $parent_slug ); } } /** * Retrieve the Toolbar display preference of a user based on context. * * This is a direct copy of WP's private _get_admin_bar_pref() * * @since 1.5.0 * * @param string $context Context of this preference check. 'admin' or 'front'. * @param int $user Optional. ID of the user to check. Default: 0 (which falls back to the logged-in user's ID). * @return bool True if the toolbar should be showing for this user. */ function bp_get_admin_bar_pref( $context, $user = 0 ) { $pref = get_user_option( "show_admin_bar_{$context}", $user ); if ( false === $pref ) return true; return 'true' === $pref; }