/** * Should BuddyPress appear in network admin (vs a single site Dashboard)? * * Because BuddyPress can be installed in multiple ways and with multiple * configurations, we need to check a few things to be confident about where * to hook into certain areas of WordPress's admin. * * @since BuddyPress (1.5.0) * * @uses bp_is_network_activated() * @uses bp_is_multiblog_mode() * * @return bool True if the BP admin screen should appear in the Network Admin, * otherwise false. */ function bp_core_do_network_admin() { // Default $retval = bp_is_network_activated(); if (bp_is_multiblog_mode()) { $retval = false; } return (bool) apply_filters('bp_core_do_network_admin', $retval); }
/** * Set admin-related actions and filters. * * @since 2.0.0 */ private function setup_actions() { /** Extended Profile ************************************************* */ // Enqueue all admin JS and CSS. add_action('bp_admin_enqueue_scripts', array($this, 'enqueue_scripts')); // Add some page specific output to the <head>. add_action('bp_admin_head', array($this, 'admin_head'), 999); // Add menu item to all users menu. add_action('admin_menu', array($this, 'admin_menus'), 5); add_action('network_admin_menu', array($this, 'admin_menus'), 5); add_action('user_admin_menu', array($this, 'user_profile_menu'), 5); // Create the Profile Navigation (Profile/Extended Profile). add_action('edit_user_profile', array($this, 'profile_nav'), 99, 1); add_action('show_user_profile', array($this, 'profile_nav'), 99, 1); // Editing users of a specific site. add_action("admin_head-site-users.php", array($this, 'profile_admin_head')); // Add a row action to users listing. if (bp_core_do_network_admin()) { add_filter('ms_user_row_actions', array($this, 'row_actions'), 10, 2); add_action('admin_init', array($this, 'add_edit_profile_url_filter')); add_action('wp_after_admin_bar_render', array($this, 'remove_edit_profile_url_filter')); } // Add user row actions for single site. add_filter('user_row_actions', array($this, 'row_actions'), 10, 2); // Process changes to member type. add_action('bp_members_admin_load', array($this, 'process_member_type_update')); /** Signups ********************************************************** */ if (is_admin()) { // Filter non multisite user query to remove sign-up users. if (!is_multisite()) { add_action('pre_user_query', array($this, 'remove_signups_from_user_query'), 10, 1); } // Reorganise the views navigation in users.php and signups page. if (current_user_can($this->capability)) { $user_screen = $this->users_screen; /** * Users screen on multiblog is users, but signups * need to be managed in the network for this case */ if (bp_is_network_activated() && bp_is_multiblog_mode() && false === strpos($user_screen, '-network')) { $user_screen .= '-network'; } add_filter("views_{$user_screen}", array($this, 'signup_filter_view'), 10, 1); add_filter('set-screen-option', array($this, 'signup_screen_options'), 10, 3); } // Registration is turned on. add_action('update_site_option_registration', array($this, 'multisite_registration_on'), 10, 2); add_action('update_option_users_can_register', array($this, 'single_site_registration_on'), 10, 2); } /** Users List - Members Types *************************************** */ if (is_admin() && bp_get_member_types()) { // Add "Change type" <select> to WP admin users list table and process bulk members type changes. add_action('restrict_manage_users', array($this, 'users_table_output_type_change_select')); add_action('load-users.php', array($this, 'users_table_process_bulk_type_change')); // Add the member type column to the WP admin users list table. add_filter('manage_users_columns', array($this, 'users_table_add_type_column')); add_filter('manage_users_custom_column', array($this, 'users_table_populate_type_cell'), 10, 3); // Filter WP admin users list table to include users of the specified type. add_filter('pre_get_users', array($this, 'users_table_filter_by_type')); } }
/** * Analyze the URI and break it down into BuddyPress-usable chunks. * * BuddyPress can use complete custom friendly URIs without the user having to * add new rewrite rules. Custom components are able to use their own custom * URI structures with very little work. * * The URIs are broken down as follows: * - http:// example.com / members / andy / [current_component] / [current_action] / [action_variables] / [action_variables] / ... * - OUTSIDE ROOT: http:// example.com / sites / buddypress / members / andy / [current_component] / [current_action] / [action_variables] / [action_variables] / ... * * Example: * - http://example.com/members/andy/profile/edit/group/5/ * - $bp->current_component: string 'xprofile' * - $bp->current_action: string 'edit' * - $bp->action_variables: array ['group', 5] * * @since 1.0.0 */ function bp_core_set_uri_globals() { global $current_blog, $wp_rewrite; // Don't catch URIs on non-root blogs unless multiblog mode is on. if (!bp_is_root_blog() && !bp_is_multiblog_mode()) { return false; } $bp = buddypress(); // Define local variables. $root_profile = $match = false; $key_slugs = $matches = $uri_chunks = array(); // Fetch all the WP page names for each component. if (empty($bp->pages)) { $bp->pages = bp_core_get_directory_pages(); } // Ajax or not? if (defined('DOING_AJAX') && DOING_AJAX || strpos($_SERVER['REQUEST_URI'], 'wp-load.php')) { $path = bp_get_referer_path(); } else { $path = esc_url($_SERVER['REQUEST_URI']); } /** * Filters the BuddyPress global URI path. * * @since 1.0.0 * * @param string $path Path to set. */ $path = apply_filters('bp_uri', $path); // Take GET variables off the URL to avoid problems. $path = strtok($path, '?'); // Fetch current URI and explode each part separated by '/' into an array. $bp_uri = explode('/', $path); // Loop and remove empties. foreach ((array) $bp_uri as $key => $uri_chunk) { if (empty($bp_uri[$key])) { unset($bp_uri[$key]); } } // If running off blog other than root, any subdirectory names must be // removed from $bp_uri. This includes two cases: // // 1. when WP is installed in a subdirectory, // 2. when BP is running on secondary blog of a subdirectory // multisite installation. Phew! if (is_multisite() && !is_subdomain_install() && (bp_is_multiblog_mode() || 1 != bp_get_root_blog_id())) { // Blow chunks. $chunks = explode('/', $current_blog->path); // If chunks exist... if (!empty($chunks)) { // ...loop through them... foreach ($chunks as $key => $chunk) { $bkey = array_search($chunk, $bp_uri); // ...and unset offending keys if (false !== $bkey) { unset($bp_uri[$bkey]); } $bp_uri = array_values($bp_uri); } } } // Get site path items. $paths = explode('/', bp_core_get_site_path()); // Take empties off the end of path. if (empty($paths[count($paths) - 1])) { array_pop($paths); } // Take empties off the start of path. if (empty($paths[0])) { array_shift($paths); } // Reset indexes. $bp_uri = array_values($bp_uri); $paths = array_values($paths); // Unset URI indices if they intersect with the paths. foreach ((array) $bp_uri as $key => $uri_chunk) { if (isset($paths[$key]) && $uri_chunk == $paths[$key]) { unset($bp_uri[$key]); } } // Reset the keys by merging with an empty array. $bp_uri = array_merge(array(), $bp_uri); // If a component is set to the front page, force its name into $bp_uri // so that $current_component is populated (unless a specific WP post is being requested // via a URL parameter, usually signifying Preview mode). if ('page' == get_option('show_on_front') && get_option('page_on_front') && empty($bp_uri) && empty($_GET['p']) && empty($_GET['page_id'])) { $post = get_post(get_option('page_on_front')); if (!empty($post)) { $bp_uri[0] = $post->post_name; } } // Keep the unfiltered URI safe. $bp->unfiltered_uri = $bp_uri; // Don't use $bp_unfiltered_uri, this is only for backpat with old plugins. Use $bp->unfiltered_uri. $GLOBALS['bp_unfiltered_uri'] =& $bp->unfiltered_uri; // Get slugs of pages into array. foreach ((array) $bp->pages as $page_key => $bp_page) { $key_slugs[$page_key] = trailingslashit('/' . $bp_page->slug); } // Bail if keyslugs are empty, as BP is not setup correct. if (empty($key_slugs)) { return; } // Loop through page slugs and look for exact match to path. foreach ($key_slugs as $key => $slug) { if ($slug == $path) { $match = $bp->pages->{$key}; $match->key = $key; $matches[] = 1; break; } } // No exact match, so look for partials. if (empty($match)) { // Loop through each page in the $bp->pages global. foreach ((array) $bp->pages as $page_key => $bp_page) { // Look for a match (check members first). if (in_array($bp_page->name, (array) $bp_uri)) { // Match found, now match the slug to make sure. $uri_chunks = explode('/', $bp_page->slug); // Loop through uri_chunks. foreach ((array) $uri_chunks as $key => $uri_chunk) { // Make sure chunk is in the correct position. if (!empty($bp_uri[$key]) && $bp_uri[$key] == $uri_chunk) { $matches[] = 1; // No match. } else { $matches[] = 0; } } // Have a match. if (!in_array(0, (array) $matches)) { $match = $bp_page; $match->key = $page_key; break; } // Unset matches. unset($matches); } // Unset uri chunks. unset($uri_chunks); } } // URLs with BP_ENABLE_ROOT_PROFILES enabled won't be caught above. if (empty($matches) && bp_core_enable_root_profiles()) { // Switch field based on compat. $field = bp_is_username_compatibility_mode() ? 'login' : 'slug'; // Make sure there's a user corresponding to $bp_uri[0]. if (!empty($bp->pages->members) && !empty($bp_uri[0]) && ($root_profile = get_user_by($field, $bp_uri[0]))) { // Force BP to recognize that this is a members page. $matches[] = 1; $match = $bp->pages->members; $match->key = 'members'; } } // Search doesn't have an associated page, so we check for it separately. if (!empty($bp_uri[0]) && bp_get_search_slug() == $bp_uri[0]) { $matches[] = 1; $match = new stdClass(); $match->key = 'search'; $match->slug = bp_get_search_slug(); } // This is not a BuddyPress page, so just return. if (empty($matches)) { return false; } $wp_rewrite->use_verbose_page_rules = false; // Find the offset. With $root_profile set, we fudge the offset down so later parsing works. $slug = !empty($match) ? explode('/', $match->slug) : ''; $uri_offset = empty($root_profile) ? 0 : -1; // Rejig the offset. if (!empty($slug) && 1 < count($slug)) { // Only offset if not on a root profile. Fixes issue when Members page is nested. if (false === $root_profile) { array_pop($slug); $uri_offset = count($slug); } } // Global the unfiltered offset to use in bp_core_load_template(). // To avoid PHP warnings in bp_core_load_template(), it must always be >= 0. $bp->unfiltered_uri_offset = $uri_offset >= 0 ? $uri_offset : 0; // We have an exact match. if (isset($match->key)) { // Set current component to matched key. $bp->current_component = $match->key; // If members component, do more work to find the actual component. if ('members' == $match->key) { $after_member_slug = false; if (!empty($bp_uri[$uri_offset + 1])) { $after_member_slug = $bp_uri[$uri_offset + 1]; } // Are we viewing a specific user? if ($after_member_slug) { // If root profile, we've already queried for the user. if ($root_profile instanceof WP_User) { $bp->displayed_user->id = $root_profile->ID; // Switch the displayed_user based on compatibility mode. } elseif (bp_is_username_compatibility_mode()) { $bp->displayed_user->id = (int) bp_core_get_userid(urldecode($after_member_slug)); } else { $bp->displayed_user->id = (int) bp_core_get_userid_from_nicename($after_member_slug); } } // Is this a member type directory? if (!bp_displayed_user_id() && $after_member_slug === apply_filters('bp_members_member_type_base', _x('type', 'member type URL base', 'buddypress')) && !empty($bp_uri[$uri_offset + 2])) { $matched_types = bp_get_member_types(array('has_directory' => true, 'directory_slug' => $bp_uri[$uri_offset + 2])); if (!empty($matched_types)) { $bp->current_member_type = reset($matched_types); unset($bp_uri[$uri_offset + 1]); } } // If the slug matches neither a member type nor a specific member, 404. if (!bp_displayed_user_id() && !bp_get_current_member_type() && $after_member_slug) { // Prevent components from loading their templates. $bp->current_component = ''; bp_do_404(); return; } // If the displayed user is marked as a spammer, 404 (unless logged-in user is a super admin). if (bp_displayed_user_id() && bp_is_user_spammer(bp_displayed_user_id())) { if (bp_current_user_can('bp_moderate')) { bp_core_add_message(__('This user has been marked as a spammer. Only site admins can view this profile.', 'buddypress'), 'warning'); } else { bp_do_404(); return; } } // Bump the offset. if (bp_displayed_user_id()) { if (isset($bp_uri[$uri_offset + 2])) { $bp_uri = array_merge(array(), array_slice($bp_uri, $uri_offset + 2)); $bp->current_component = $bp_uri[0]; // No component, so default will be picked later. } else { $bp_uri = array_merge(array(), array_slice($bp_uri, $uri_offset + 2)); $bp->current_component = ''; } // Reset the offset. $uri_offset = 0; } } } // Determine the current action. $current_action = isset($bp_uri[$uri_offset + 1]) ? $bp_uri[$uri_offset + 1] : ''; /* * If a BuddyPress directory is set to the WP front page, URLs like example.com/members/?s=foo * shouldn't interfere with blog searches. */ if (empty($current_action) && !empty($_GET['s']) && 'page' == get_option('show_on_front') && !empty($match->id)) { $page_on_front = (int) get_option('page_on_front'); if ((int) $match->id === $page_on_front) { $bp->current_component = ''; return false; } } $bp->current_action = $current_action; // Slice the rest of the $bp_uri array and reset offset. $bp_uri = array_slice($bp_uri, $uri_offset + 2); $uri_offset = 0; // Set the entire URI as the action variables, we will unset the current_component and action in a second. $bp->action_variables = $bp_uri; // Reset the keys by merging with an empty array. $bp->action_variables = array_merge(array(), $bp->action_variables); }
/** * Fetch global BP options. * * BuddyPress uses common options to store configuration settings. Many of these * settings are needed at run time. Instead of fetching them all and adding many * initial queries to each page load, let's fetch them all in one go. * * @todo Use settings API and audit these methods. * * @return array $root_blog_options_meta List of options. */ function bp_core_get_root_options() { global $wpdb; // Get all the BuddyPress settings, and a few useful WP ones too $root_blog_options = bp_get_default_options(); $root_blog_options['registration'] = '0'; $root_blog_options['avatar_default'] = 'mysteryman'; $root_blog_option_keys = array_keys($root_blog_options); // Do some magic to get all the root blog options in 1 swoop // Check cache first - We cache here instead of using the standard WP // settings cache because the current blog may not be the root blog, // and it's not practical to access the cache across blogs $root_blog_options_meta = wp_cache_get('root_blog_options', 'bp'); if (false === $root_blog_options_meta) { $blog_options_keys = "'" . join("', '", (array) $root_blog_option_keys) . "'"; $blog_options_table = bp_is_multiblog_mode() ? $wpdb->options : $wpdb->get_blog_prefix(bp_get_root_blog_id()) . 'options'; $blog_options_query = "SELECT option_name AS name, option_value AS value FROM {$blog_options_table} WHERE option_name IN ( {$blog_options_keys} )"; $root_blog_options_meta = $wpdb->get_results($blog_options_query); // On Multisite installations, some options must always be fetched from sitemeta if (is_multisite()) { /** * Filters multisite options retrieved from sitemeta. * * @since BuddyPress (1.5.0) * * @param array $value Array of multisite options from sitemeta table. */ $network_options = apply_filters('bp_core_network_options', array('tags_blog_id' => '0', 'sitewide_tags_blog' => '', 'registration' => '0', 'fileupload_maxk' => '1500')); $current_site = get_current_site(); $network_option_keys = array_keys($network_options); $sitemeta_options_keys = "'" . join("', '", (array) $network_option_keys) . "'"; $sitemeta_options_query = $wpdb->prepare("SELECT meta_key AS name, meta_value AS value FROM {$wpdb->sitemeta} WHERE meta_key IN ( {$sitemeta_options_keys} ) AND site_id = %d", $current_site->id); $network_options_meta = $wpdb->get_results($sitemeta_options_query); // Sitemeta comes second in the merge, so that network 'registration' value wins $root_blog_options_meta = array_merge($root_blog_options_meta, $network_options_meta); } // Missing some options, so do some one-time fixing if (empty($root_blog_options_meta) || count($root_blog_options_meta) < count($root_blog_option_keys)) { // Get a list of the keys that are already populated $existing_options = array(); foreach ($root_blog_options_meta as $already_option) { $existing_options[$already_option->name] = $already_option->value; } // Unset the query - We'll be resetting it soon unset($root_blog_options_meta); // Loop through options foreach ($root_blog_options as $old_meta_key => $old_meta_default) { if (isset($existing_options[$old_meta_key])) { continue; } // Get old site option if (is_multisite()) { $old_meta_value = get_site_option($old_meta_key); } // No site option so look in root blog if (empty($old_meta_value)) { $old_meta_value = bp_get_option($old_meta_key, $old_meta_default); } // Update the root blog option bp_update_option($old_meta_key, $old_meta_value); // Update the global array $root_blog_options_meta[$old_meta_key] = $old_meta_value; // Clear out the value for the next time around unset($old_meta_value); } $root_blog_options_meta = array_merge($root_blog_options_meta, $existing_options); unset($existing_options); // We're all matched up } else { // Loop through our results and make them usable foreach ($root_blog_options_meta as $root_blog_option) { $root_blog_options[$root_blog_option->name] = $root_blog_option->value; } // Copy the options no the return val $root_blog_options_meta = $root_blog_options; // Clean up our temporary copy unset($root_blog_options); } wp_cache_set('root_blog_options', $root_blog_options_meta, 'bp'); } /** * Filters the global BP options. * * @since BuddyPress (1.5.0) * * @param array $root_blog_options_meta Array of global BP options. */ return apply_filters('bp_core_get_root_options', $root_blog_options_meta); }
/** * Add the navigational menu elements * * @since BuddyPress (1.6) * * @uses add_management_page() To add the Recount page in Tools section * @uses add_options_page() To add the Forums settings page in Settings * section */ public function admin_menus() { // In maintenance mode if (bp_get_maintenance_mode()) { if (!current_user_can('manage_options')) { return; } if (bp_get_maintenance_mode() == 'install') { $status = __('BuddyPress Setup', 'buddypress'); } else { $status = __('Update BuddyPress', 'buddypress'); } if (bp_get_wizard()) { if (!is_multisite() || bp_is_multiblog_mode()) { $hook = add_dashboard_page($status, $status, 'manage_options', 'bp-wizard', array(bp_get_wizard(), 'html')); } else { $hook = add_submenu_page('update-core.php', $status, $status, 'manage_options', 'bp-wizard', array(bp_get_wizard(), 'html')); } } // Not in maintenance mode } else { // Bail if user cannot moderate if (!bp_current_user_can('manage_options')) { return; } $hooks = array(); $page = bp_core_do_network_admin() ? 'settings.php' : 'options-general.php'; // Changed in BP 1.6 . See bp_core_admin_backpat_menu() $hooks[] = add_menu_page(__('BuddyPress', 'buddypress'), __('BuddyPress', 'buddypress'), 'manage_options', 'bp-general-settings', 'bp_core_admin_backpat_menu', ''); $hooks[] = add_submenu_page('bp-general-settings', __('BuddyPress Help', 'buddypress'), __('Help', 'buddypress'), 'manage_options', 'bp-general-settings', 'bp_core_admin_backpat_page'); // Add the option pages $hooks[] = add_submenu_page($page, __('BuddyPress Components', 'buddypress'), __('BuddyPress', 'buddypress'), 'manage_options', 'bp-components', 'bp_core_admin_components_settings'); $hooks[] = add_submenu_page($page, __('BuddyPress Pages', 'buddypress'), __('BuddyPress Pages', 'buddypress'), 'manage_options', 'bp-page-settings', 'bp_core_admin_slugs_settings'); $hooks[] = add_submenu_page($page, __('BuddyPress Settings', 'buddypress'), __('BuddyPress Settings', 'buddypress'), 'manage_options', 'bp-settings', 'bp_core_admin_settings'); // Fudge the highlighted subnav item when on a BuddyPress admin page foreach ($hooks as $hook) { add_action("admin_head-{$hook}", 'bp_core_modify_admin_menu_highlight'); } } }
/** * Analyzes the URI structure and breaks it down into parts for use in code. * The idea is that BuddyPress can use complete custom friendly URI's without the * user having to add new re-write rules. * * Future custom components would then be able to use their own custom URI structure. * * @package BuddyPress Core * @since BuddyPress (r100) * * The URI's are broken down as follows: * - http:// domain.com / members / andy / [current_component] / [current_action] / [action_variables] / [action_variables] / ... * - OUTSIDE ROOT: http:// domain.com / sites / buddypress / members / andy / [current_component] / [current_action] / [action_variables] / [action_variables] / ... * * Example: * - http://domain.com/members/andy/profile/edit/group/5/ * - $bp->current_component: string 'xprofile' * - $bp->current_action: string 'edit' * - $bp->action_variables: array ['group', 5] * */ function bp_core_set_uri_globals() { global $bp, $bp_unfiltered_uri, $bp_unfiltered_uri_offset; global $current_blog, $nxtdb; // Create global component, action, and item variables $bp->current_component = $bp->current_action = $bp->current_item = ''; $bp->action_variables = $bp->displayed_user->id = ''; // Don't catch URIs on non-root blogs unless multiblog mode is on if (!bp_is_root_blog() && !bp_is_multiblog_mode()) { return false; } // Fetch all the nxt page names for each component if (empty($bp->pages)) { $bp->pages = bp_core_get_directory_pages(); } // Ajax or not? if (strpos($_SERVER['REQUEST_URI'], 'nxt-load.php')) { $path = bp_core_referrer(); } else { $path = esc_url($_SERVER['REQUEST_URI']); } // Filter the path $path = apply_filters('bp_uri', $path); // Take GET variables off the URL to avoid problems, // they are still registered in the global $_GET variable if ($noget = substr($path, 0, strpos($path, '?'))) { $path = $noget; } // Fetch the current URI and explode each part separated by '/' into an array $bp_uri = explode('/', $path); // Loop and remove empties foreach ((array) $bp_uri as $key => $uri_chunk) { if (empty($bp_uri[$key])) { unset($bp_uri[$key]); } } // Running off blog other than root if (is_multisite() && !is_subdomain_install() && (bp_is_multiblog_mode() || 1 != bp_get_root_blog_id())) { // Any subdirectory names must be removed from $bp_uri. // This includes two cases: (1) when nxt is installed in a subdirectory, // and (2) when BP is running on secondary blog of a subdirectory // multisite installation. Phew! if ($chunks = explode('/', $current_blog->path)) { foreach ($chunks as $key => $chunk) { $bkey = array_search($chunk, $bp_uri); if ($bkey !== false) { unset($bp_uri[$bkey]); } $bp_uri = array_values($bp_uri); } } } // Set the indexes, these are incresed by one if we are not on a VHOST install $component_index = 0; $action_index = $component_index + 1; // Get site path items $paths = explode('/', bp_core_get_site_path()); // Take empties off the end of path if (empty($paths[count($paths) - 1])) { array_pop($paths); } // Take empties off the start of path if (empty($paths[0])) { array_shift($paths); } // Unset URI indices if they intersect with the paths foreach ((array) $bp_uri as $key => $uri_chunk) { if (in_array($uri_chunk, $paths)) { unset($bp_uri[$key]); } } // Reset the keys by merging with an empty array $bp_uri = array_merge(array(), $bp_uri); // If a component is set to the front page, force its name into $bp_uri // so that $current_component is populated (unless a specific nxt post is being requested // via a URL parameter, usually signifying Preview mode) if ('page' == get_option('show_on_front') && get_option('page_on_front') && empty($bp_uri) && empty($_GET['p']) && empty($_GET['page_id'])) { $post = get_post(get_option('page_on_front')); if (!empty($post)) { $bp_uri[0] = $post->post_name; } } // Keep the unfiltered URI safe $bp_unfiltered_uri = $bp_uri; // Get slugs of pages into array foreach ((array) $bp->pages as $page_key => $bp_page) { $key_slugs[$page_key] = trailingslashit('/' . $bp_page->slug); } // Bail if keyslugs are empty, as BP is not setup correct if (empty($key_slugs)) { return; } // Loop through page slugs and look for exact match to path foreach ($key_slugs as $key => $slug) { if ($slug == $path) { $match = $bp->pages->{$key}; $match->key = $key; $matches[] = 1; break; } } // No exact match, so look for partials if (empty($match)) { // Loop through each page in the $bp->pages global foreach ((array) $bp->pages as $page_key => $bp_page) { // Look for a match (check members first) if (in_array($bp_page->name, (array) $bp_uri)) { // Match found, now match the slug to make sure. $uri_chunks = explode('/', $bp_page->slug); // Loop through uri_chunks foreach ((array) $uri_chunks as $key => $uri_chunk) { // Make sure chunk is in the correct position if (!empty($bp_uri[$key]) && $bp_uri[$key] == $uri_chunk) { $matches[] = 1; // No match } else { $matches[] = 0; } } // Have a match if (!in_array(0, (array) $matches)) { $match = $bp_page; $match->key = $page_key; break; } // Unset matches unset($matches); } // Unset uri chunks unset($uri_chunks); } } // URLs with BP_ENABLE_ROOT_PROFILES enabled won't be caught above if (empty($matches) && defined('BP_ENABLE_ROOT_PROFILES') && BP_ENABLE_ROOT_PROFILES) { // Make sure there's a user corresponding to $bp_uri[0] if (!empty($bp->pages->members) && !empty($bp_uri[0]) && ($root_profile = get_user_by('login', $bp_uri[0]))) { // Force BP to recognize that this is a members page $matches[] = 1; $match = $bp->pages->members; $match->key = 'members'; // Without the 'members' URL chunk, NXTClass won't know which page to load // This filter intercepts the nxt query and tells it to load the members page add_filter('request', create_function('$query_args', '$query_args["pagename"] = "' . $match->name . '"; return $query_args;')); } } // Search doesn't have an associated page, so we check for it separately if (!empty($bp_uri[0]) && bp_get_search_slug() == $bp_uri[0]) { $matches[] = 1; $match = new stdClass(); $match->key = 'search'; $match->slug = bp_get_search_slug(); } // This is not a BuddyPress page, so just return. if (!isset($matches)) { return false; } // Find the offset. With $root_profile set, we fudge the offset down so later parsing works $slug = !empty($match) ? explode('/', $match->slug) : ''; $uri_offset = empty($root_profile) ? 0 : -1; // Rejig the offset if (!empty($slug) && 1 < count($slug)) { array_pop($slug); $uri_offset = count($slug); } // Global the unfiltered offset to use in bp_core_load_template(). // To avoid PHP warnings in bp_core_load_template(), it must always be >= 0 $bp_unfiltered_uri_offset = $uri_offset >= 0 ? $uri_offset : 0; // We have an exact match if (isset($match->key)) { // Set current component to matched key $bp->current_component = $match->key; // If members component, do more work to find the actual component if ('members' == $match->key) { // Viewing a specific user if (!empty($bp_uri[$uri_offset + 1])) { // Switch the displayed_user based on compatbility mode if (bp_is_username_compatibility_mode()) { $bp->displayed_user->id = (int) bp_core_get_userid(urldecode($bp_uri[$uri_offset + 1])); } else { $bp->displayed_user->id = (int) bp_core_get_userid_from_nicename(urldecode($bp_uri[$uri_offset + 1])); } if (empty($bp->displayed_user->id)) { // Prevent components from loading their templates $bp->current_component = ''; bp_do_404(); return; } // If the displayed user is marked as a spammer, 404 (unless logged- // in user is a super admin) if (!empty($bp->displayed_user->id) && bp_core_is_user_spammer($bp->displayed_user->id)) { if (is_super_admin()) { bp_core_add_message(__('This user has been marked as a spammer. Only site admins can view this profile.', 'buddypress'), 'error'); } else { bp_do_404(); return; } } // Bump the offset if (isset($bp_uri[$uri_offset + 2])) { $bp_uri = array_merge(array(), array_slice($bp_uri, $uri_offset + 2)); $bp->current_component = $bp_uri[0]; // No component, so default will be picked later } else { $bp_uri = array_merge(array(), array_slice($bp_uri, $uri_offset + 2)); $bp->current_component = ''; } // Reset the offset $uri_offset = 0; } } } // Set the current action $bp->current_action = isset($bp_uri[$uri_offset + 1]) ? $bp_uri[$uri_offset + 1] : ''; // Slice the rest of the $bp_uri array and reset offset $bp_uri = array_slice($bp_uri, $uri_offset + 2); $uri_offset = 0; // Set the entire URI as the action variables, we will unset the current_component and action in a second $bp->action_variables = $bp_uri; // Remove the username from action variables if this is not a VHOST install // @todo - move or remove this all together if (defined('VHOST') && 'no' == VHOST && empty($bp->current_component)) { array_shift($bp_uri); } // Reset the keys by merging with an empty array $bp->action_variables = array_merge(array(), $bp->action_variables); }
/** * Is this bp_get_root_blog_id()? * * @package BuddyPress * @since 1.5 * * @param int $blog_id Optional. Defaults to the current blog id. * @return bool $is_root_blog Returns true if this is bp_get_root_blog_id(). */ function bp_get_root_blog_id($blog_id = false) { // Define on which blog ID BuddyPress should run if (!defined('BP_ROOT_BLOG')) { // Root blog is the main site on this network if (is_multisite() && !bp_is_multiblog_mode()) { $current_site = get_current_site(); $root_blog_id = $current_site->blog_id; // Root blog is whatever the current site is (could be any site on the network) } elseif (is_multisite() && bp_is_multiblog_mode()) { $root_blog_id = get_current_blog_id(); // Root blog is the only blog on this network } elseif (!is_multisite()) { $root_blog_id = 1; } define('BP_ROOT_BLOG', $root_blog_id); // Root blog is defined } else { $root_blog_id = BP_ROOT_BLOG; } return apply_filters('bp_get_root_blog_id', (int) $root_blog_id); }
/** * Should BuddyPress appear in network admin (vs a single site Dashboard)? * * Because BuddyPress can be installed in multiple ways and with multiple * configurations, we need to check a few things to be confident about where * to hook into certain areas of WordPress's admin. * * @since BuddyPress (1.5.0) * * @uses bp_is_network_activated() * @uses bp_is_multiblog_mode() * * @return bool True if the BP admin screen should appear in the Network Admin, * otherwise false. */ function bp_core_do_network_admin() { // Default $retval = bp_is_network_activated(); if (bp_is_multiblog_mode()) { $retval = false; } /** * Filters whether or not BuddyPress should appear in network admin. * * @since BuddyPress (1.5.0) * * @param bool $retval Whether or not BuddyPress should be in the network admin. */ return (bool) apply_filters('bp_core_do_network_admin', $retval); }
/** * Enqueues the javascript. * * The JS is used to add AJAX functionality when clicking on the follow button. */ public function enqueue_scripts() { // Do not enqueue if no user is logged in if (!is_user_logged_in()) { return; } // Do not enqueue on multisite if not on multiblog and not on root blog if (!bp_is_multiblog_mode() && !bp_is_root_blog()) { return; } wp_enqueue_script('bp-follow-js', constant('BP_FOLLOW_URL') . '_inc/bp-follow.js', array('jquery'), strtotime($this->revision_date)); }
function bp_core_do_network_admin() { $do_network_admin = false; if (is_multisite() && !bp_is_multiblog_mode()) { $do_network_admin = true; } return apply_filters('bp_core_do_network_admin', $do_network_admin); }
/** * Fetch global BP options. * * BuddyPress uses common options to store configuration settings. Many of these * settings are needed at run time. Instead of fetching them all and adding many * initial queries to each page load, let's fetch them all in one go. * * @since 1.5.0 * * @todo Use settings API and audit these methods. * * @return array $root_blog_options_meta List of options. */ function bp_core_get_root_options() { global $wpdb; // Get all the BuddyPress settings, and a few useful WP ones too. $root_blog_options = bp_get_default_options(); $root_blog_options['registration'] = '0'; $root_blog_options['avatar_default'] = 'mysteryman'; $root_blog_option_keys = array_keys($root_blog_options); // Do some magic to get all the root blog options in 1 swoop // Check cache first - We cache here instead of using the standard WP // settings cache because the current blog may not be the root blog, // and it's not practical to access the cache across blogs. $root_blog_options_meta = wp_cache_get('root_blog_options', 'bp'); if (false === $root_blog_options_meta) { $blog_options_keys = "'" . join("', '", (array) $root_blog_option_keys) . "'"; $blog_options_table = bp_is_multiblog_mode() ? $wpdb->options : $wpdb->get_blog_prefix(bp_get_root_blog_id()) . 'options'; $blog_options_query = "SELECT option_name AS name, option_value AS value FROM {$blog_options_table} WHERE option_name IN ( {$blog_options_keys} )"; $root_blog_options_meta = $wpdb->get_results($blog_options_query); // On Multisite installations, some options must always be fetched from sitemeta. if (is_multisite()) { /** * Filters multisite options retrieved from sitemeta. * * @since 1.5.0 * * @param array $value Array of multisite options from sitemeta table. */ $network_options = apply_filters('bp_core_network_options', array('tags_blog_id' => '0', 'sitewide_tags_blog' => '', 'registration' => '0', 'fileupload_maxk' => '1500')); $current_site = get_current_site(); $network_option_keys = array_keys($network_options); $sitemeta_options_keys = "'" . join("', '", (array) $network_option_keys) . "'"; $sitemeta_options_query = $wpdb->prepare("SELECT meta_key AS name, meta_value AS value FROM {$wpdb->sitemeta} WHERE meta_key IN ( {$sitemeta_options_keys} ) AND site_id = %d", $current_site->id); $network_options_meta = $wpdb->get_results($sitemeta_options_query); // Sitemeta comes second in the merge, so that network 'registration' value wins. $root_blog_options_meta = array_merge($root_blog_options_meta, $network_options_meta); } // Loop through our results and make them usable. foreach ($root_blog_options_meta as $root_blog_option) { $root_blog_options[$root_blog_option->name] = $root_blog_option->value; } // Copy the options no the return val. $root_blog_options_meta = $root_blog_options; // Clean up our temporary copy. unset($root_blog_options); wp_cache_set('root_blog_options', $root_blog_options_meta, 'bp'); } /** * Filters the global BP options. * * @since 1.5.0 * * @param array $root_blog_options_meta Array of global BP options. */ return apply_filters('bp_core_get_root_options', $root_blog_options_meta); }
/** * Returns a flat array of the site's page hierarchy * * @version 1.0 * @since 1.0 * @return array $result | Exception on failure. Page hierarchy as flat array on success. */ public function getPageHierarchy() { // TODO: Add caching capabilities global $wpdb; // Always get page data from the root blog, except on multiblog mode, when it comes // from the current blog if (bp_is_multiblog_mode()) { $posts_table_name = $wpdb->posts; } else { $posts_table_name = $wpdb->get_blog_prefix(bp_get_root_blog_id()) . 'posts'; } $sql = "SELECT ID, post_name, post_parent, post_title FROM {$posts_table_name} WHERE post_type = 'page' AND post_status != 'auto-draft'"; $pages = $wpdb->get_results($sql); // Trap any database errors $sql_error = mysql_error($wpdb->dbh); if ($sql_error) { throw new FOX_exception(array('numeric' => 1, 'text' => "Database error", 'data' => array($sql, $sql_error), 'file' => __FILE__, 'line' => __LINE__, 'method' => __METHOD__, 'child' => null)); } // Spin the SQL server's output into a useful format $result = array(); foreach ($pages as $page) { $result[$page->ID] = array("parent" => $page->post_parent, "slug" => $page->post_name, "title" => $page->post_title); } unset($page); return $result; }
/** * Registers "Activity > Hashtags" menu item in the admin area. * * If on multisite, we need to register the main "Activity" admin page for * use on the root blog's admin dashboard as well. This is done because * the main "Activity" admin page is only viewable in the network admin * area and in order to register our "Activity > Hashtags" menu item, * we'll need the main "Activity" admin page available on the root blog. * * @todo Investigate multiblog mode some more. */ function bp_activity_hashtags_register_menu() { // on multisite, register the top level "Activity" admin page in the root blog // admin dashboard as well if (is_multisite() && !bp_is_multiblog_mode() && bp_is_root_blog()) { if (function_exists('bp_activity_add_admin_menu') && !is_network_admin()) { bp_activity_add_admin_menu(); } } // @see bp_activity_hashtags_network_admin_redirect() if (is_network_admin()) { $admin_url = 'admin.php?page=bp-activity&bp-hashtags-redirect=1'; } else { $admin_url = bp_activity_hashtags_get_admin_path(); } // register our "Activity > Hashtags" menu item add_submenu_page('bp-activity', __('Activity Hashtags', 'bp-activity-hashtags'), '<span id="bp-activity-hashtags">' . __('Hashtags', 'bp-activity-hashtags') . '</span>', 'bp_moderate', $admin_url); }