Skip to:
Content

BuddyPress.org

Ticket #4954: 4954.ray.01.patch

File 4954.ray.01.patch, 54.8 KB (added by r-a-y, 10 years ago)

Patch created off r7859.

  • bp-core/bp-core-actions.php

    add_action( 'bp_loaded', 'bp_register_theme_directory', 14 ); 
    6464 * The load order helps to execute code at the correct time.
    6565 *                                                   v---Load order
    6666 */
    67 add_action( 'bp_init', 'bp_core_set_uri_globals',    2  );
    6867add_action( 'bp_init', 'bp_setup_globals',           4  );
    69 add_action( 'bp_init', 'bp_setup_nav',               6  );
    7068add_action( 'bp_init', 'bp_setup_title',             8  );
    7169add_action( 'bp_init', 'bp_core_load_admin_bar_css', 12 );
    7270add_action( 'bp_init', 'bp_add_rewrite_tags',        20 );
    add_action( 'bp_init', 'bp_add_rewrite_rules', 30 ); 
    7472add_action( 'bp_init', 'bp_add_permastructs',        40 );
    7573
    7674/**
     75 * bp_parse_query - Attached to 'parse_query' above
     76 *
     77 * Attach various query-related actions to the bp_parse_query action.
     78 */
     79add_action( 'bp_parse_query', 'bp_setup_nav', 10 );
     80
     81/**
    7782 * bp_template_redirect - Attached to 'template_redirect' above
    7883 *
    7984 * Attach various template actions to the bp_template_redirect action.
  • bp-core/bp-core-catchuri.php

    if ( !defined( 'ABSPATH' ) ) exit; 
    1616/**
    1717 * Analyze the URI and break it down into BuddyPress-usable chunks.
    1818 *
    19  * BuddyPress can use complete custom friendly URIs without the user having to
    20  * add new rewrite rules. Custom components are able to use their own custom
    21  * URI structures with very little work.
     19 * This isn't really used anymore.  Don't look or it will blind your eyes!
     20 * Currently, only used on AJAX requests to determine the current_X items.
     21 *
     22 * Rewrite rules now take care of URI parsing.
    2223 *
    2324 * The URIs are broken down as follows:
    2425 *   - http:// domain.com / members / andy / [current_component] / [current_action] / [action_variables] / [action_variables] / ...
    function bp_core_set_uri_globals() { 
    312313}
    313314
    314315/**
     316 * Get a specific BuddyPress URI segment based on the current URI.
     317 *
     318 * For example, the following URI - /community/members/admin/activity/groups/:
     319 *  'root_slug' will return 'community/members'
     320 *  'item' will return 'admin'
     321 *  'component' will return 'activity'
     322 *  'action' will return 'groups'
     323 *  'action_variables' will return anything after 'groups' if set
     324 *
     325 * Note: This set up resembles the members component only.  For groups, you'll
     326 * have to manually shift various items around due to the inconsistency of
     327 * BP's current_X convention across different components.
     328 *
     329 * You shouldn't really have to use this function unless you need to find a BP
     330 * URI segment earlier than the 'parse_query' action.
     331 *
     332 * @since BuddyPress (2.0.0)
     333 *
     334 * @param string $context See phpDoc.
     335 * @return string|bool String on success. Boolean false on failure.
     336 */
     337function bp_core_get_from_uri( $context = 'item' ) {
     338        // Don't do this on non-root blogs unless multiblog mode is on
     339        if ( ! bp_is_root_blog() && ! bp_is_multiblog_mode() ) {
     340                return false;
     341        }
     342
     343        // get root slug if already queried
     344        if ( ! empty( buddypress()->rewrite->root_slug ) && $context == 'root_slug' ) {
     345                return buddypress()->rewrite->root_slug;
     346
     347        // get existing path if already calculated
     348        } elseif ( ! empty( buddypress()->unfiltered_uri ) ) {
     349                $path = buddypress()->unfiltered_uri;
     350
     351        // calculate the path
     352        } else {
     353                $site_path = bp_core_get_site_path();
     354
     355                // subdirectory install
     356                if ( is_multisite() && ! is_subdomain_install() ) {
     357                        global $current_blog;
     358                        $site_path = $current_blog->path;
     359                }
     360
     361                // strip site path from URI
     362                $path = str_replace( $site_path, '', esc_url( $_SERVER['REQUEST_URI'] ) );
     363
     364                $bp_root_slugs = wp_list_pluck( (array) buddypress()->pages, 'slug' );
     365
     366                // search for any BP root slug and strip it if matched
     367                foreach( $bp_root_slugs as $root_slug ) {
     368                        if ( strpos( $path, $root_slug ) === 0 ) {
     369                                if ( $context == 'root_slug' ) {
     370                                        buddypress()->rewrite->root_slug = $root_slug;
     371                                        return $root_slug;
     372                                }
     373
     374                                $path = str_replace( $root_slug . '/', '', $path );
     375                                break;
     376                        }
     377                }
     378
     379                // finally, split up the path
     380                $path = array_filter( explode( '/', $path ) );
     381
     382                // save for later
     383                buddypress()->unfiltered_uri = $path;
     384        }
     385
     386        switch ( $context ) {
     387                case 'component' :
     388                        $key = 1;
     389                        break;
     390
     391                case 'action' :
     392                        $key = 2;
     393                        break;
     394
     395                case 'action_variables' :
     396                        unset( $path[0], $path[1], $path[2] );
     397
     398                        return ! empty( $path ) ? array_values( $path ) : array();
     399                        break;
     400
     401                case 'item' :
     402                default :
     403                        $key = 0;
     404                        break;
     405        }
     406
     407        if ( empty( $path[$key] ) ) {
     408                return false;
     409        }
     410
     411        return $path[$key];
     412}
     413
     414/**
    315415 * Are root profiles enabled and allowed?
    316416 *
    317417 * @since BuddyPress (1.6.0)
    function bp_core_enable_root_profiles() { 
    329429}
    330430
    331431/**
    332  * Load a specific template file with fallback support.
     432 * Template loader support for the old bp-default theme.
     433 *
     434 * Do not use this function unless you want to support bp-default.  Developers
     435 * new to BuddyPress can (and should) ignore this function.
    333436 *
    334437 * Example:
    335438 *   bp_core_load_template( 'members/index' );
    function bp_core_enable_root_profiles() { 
    340443 * @return bool|null Returns false on failure.
    341444 */
    342445function bp_core_load_template( $templates ) {
    343         global $post, $bp, $wp_query, $wpdb;
    344 
    345         // Determine if the root object WP page exists for this request
    346         // note: get_page_by_path() breaks non-root pages
    347         if ( !empty( $bp->unfiltered_uri_offset ) ) {
    348                 if ( !$page_exists = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_name = %s", $bp->unfiltered_uri[$bp->unfiltered_uri_offset] ) ) ) {
    349                         return false;
    350                 }
    351         }
    352 
    353         // Set the root object as the current wp_query-ied item
    354         $object_id = 0;
    355         foreach ( (array) $bp->pages as $page ) {
    356                 if ( $page->name == $bp->unfiltered_uri[$bp->unfiltered_uri_offset] ) {
    357                         $object_id = $page->id;
    358                 }
    359         }
    360 
    361         // Make the queried/post object an actual valid page
    362         if ( !empty( $object_id ) ) {
    363                 $wp_query->queried_object    = get_post( $object_id );
    364                 $wp_query->queried_object_id = $object_id;
    365                 $post                        = $wp_query->queried_object;
    366         }
    367 
    368446        // Fetch each template and add the php suffix
    369447        $filtered_templates = array();
    370448        foreach ( (array) $templates as $template ) {
    371449                $filtered_templates[] = $template . '.php';
    372450        }
    373451
    374         // Filter the template locations so that plugins can alter where they are located
    375         $located_template = apply_filters( 'bp_located_template', locate_template( (array) $filtered_templates, false ), $filtered_templates );
    376         if ( !empty( $located_template ) ) {
     452        // bp-default template lookup. will always exist!
     453        if ( ! bp_use_theme_compat_with_current_theme() ) {
     454                $template = locate_template( (array) $filtered_templates, false );
    377455
    378                 // Template was located, lets set this as a valid page and not a 404.
     456        // theme compat doesn't require older bp-default so avoid unnecessary
     457        // locate_template() call
     458        } else {
     459                $template = '';
     460        }
     461
     462        // Filter the template locations so plugins can alter where they are located
     463        $located_template = apply_filters( 'bp_located_template', $template, $filtered_templates );
     464
     465        if ( ! empty( $located_template ) ) {
     466                // reset $wp_query properties
     467                global $wp_query;
     468                $wp_query->is_page = $wp_query->is_singular = true;
     469                $wp_query->is_404  = false;
     470
     471                // Template was located, let's set this as a valid page and not a 404.
    379472                status_header( 200 );
    380                 $wp_query->is_page     = true;
    381                 $wp_query->is_singular = true;
    382                 $wp_query->is_404      = false;
    383473
    384474                do_action( 'bp_core_pre_load_template', $located_template );
    385475
    function bp_core_load_template( $templates ) { 
    389479
    390480                // Kill any other output after this.
    391481                exit();
    392 
    393         // No template found, so setup theme compatability
    394         // @todo Some other 404 handling if theme compat doesn't kick in
    395         } else {
    396 
    397                 // We know where we are, so reset important $wp_query bits here early.
    398                 // The rest will be done by bp_theme_compat_reset_post() later.
    399                 if ( is_buddypress() ) {
    400                         status_header( 200 );
    401                         $wp_query->is_page     = true;
    402                         $wp_query->is_singular = true;
    403                         $wp_query->is_404      = false;
    404                 }
    405 
    406                 do_action( 'bp_setup_theme_compat' );
    407482        }
    408483}
    409484
    add_action( 'login_form_bpnoaccess', 'bp_core_no_access_wp_login_error' ); 
    555630function bp_redirect_canonical() {
    556631        global $bp;
    557632
    558         if ( !bp_is_blog_page() && apply_filters( 'bp_do_redirect_canonical', true ) ) {
     633        if ( ! bp_is_blog_page() && apply_filters( 'bp_do_redirect_canonical', true ) ) {
    559634                // If this is a POST request, don't do a canonical redirect.
    560635                // This is for backward compatibility with plugins that submit form requests to
    561636                // non-canonical URLs. Plugin authors should do their best to use canonical URLs in
    function bp_redirect_canonical() { 
    565640                }
    566641
    567642                // build the URL in the address bar
    568                 $requested_url  = bp_get_requested_url();
     643                $requested_url = bp_get_requested_url();
    569644
    570645                // Stash query args
    571                 $url_stack      = explode( '?', $requested_url );
    572                 $req_url_clean  = $url_stack[0];
    573                 $query_args     = isset( $url_stack[1] ) ? $url_stack[1] : '';
     646                $url_stack     = explode( '?', $requested_url );
     647                $req_url_clean = $url_stack[0];
     648
     649                // Strip BP query vars from canonical URL
     650                if ( ! empty( $url_stack[1] ) ) {
     651                        wp_parse_str( $url_stack[1], $query_args );
     652
     653                        $sans_bp_query_args = array_diff_key( $query_args, array_flip( buddypress()->rewrite->registered_query_vars ) );
     654
     655                        // Put the querystring back together
     656                        $url_stack[1] = http_build_query( $sans_bp_query_args );
     657                }
     658
     659                $query_args    = isset( $url_stack[1] ) ? $url_stack[1] : '';
    574660
    575                 $canonical_url  = bp_get_canonical_url();
     661                $canonical_url = bp_get_canonical_url();
    576662
    577663                // Only redirect if we've assembled a URL different from the request
    578664                if ( $canonical_url !== $req_url_clean ) {
    function _bp_maybe_remove_redirect_canonical() { 
    731817        if ( ! bp_is_blog_page() )
    732818                remove_action( 'template_redirect', 'redirect_canonical' );
    733819}
    734 add_action( 'bp_init', '_bp_maybe_remove_redirect_canonical' );
     820add_action( 'bp_parse_query', '_bp_maybe_remove_redirect_canonical' );
    735821
    736822/**
    737823 * Rehook maybe_redirect_404() to run later than the default.
  • bp-core/bp-core-component.php

    class BP_Component { 
    201201         *           names.
    202202         *     @type array $meta_tables Optional. An array of metadata table
    203203         *           names.
     204         *     @type array $query_vars Optional. An array of query variables
     205         *           used with rewrite rules.
    204206         * }
    205207         */
    206208        public function setup_globals( $args = array() ) {
    class BP_Component { 
    219221                        'search_string'         => '',
    220222                        'global_tables'         => '',
    221223                        'meta_tables'           => '',
     224                        'query_vars'            => array(),
    222225                ) );
    223226
    224227                // Slug used for permalink URI chunk after root
    class BP_Component { 
    236239                // Notifications callback
    237240                $this->notification_callback = apply_filters( 'bp_' . $this->id . '_notification_callback', $r['notification_callback'] );
    238241
     242                // Query variables used with rewrite rules
     243                $this->query_vars            = (array) apply_filters( 'bp_' . $this->id . '_query_vars',    $r['query_vars'] );
     244                buddypress()->rewrite->registered_query_vars = array_merge( buddypress()->rewrite->registered_query_vars, $this->query_vars );
     245
    239246                // Set the global table names, if applicable
    240247                if ( ! empty( $r['global_tables'] ) ) {
    241248                        $this->register_global_tables( $r['global_tables'] );
    class BP_Component { 
    366373                add_action( 'bp_add_permastructs',       array( $this, 'add_permastructs'       ), 10 );
    367374
    368375                // Allow components to parse the main query
    369                 add_action( 'bp_parse_query',            array( $this, 'parse_query'            ), 10 );
     376                add_action( 'bp_parse_query',            array( $this, 'parse_query'            ), 8 );
    370377
    371378                // Generate rewrite rules
    372379                add_action( 'bp_generate_rewrite_rules', array( $this, 'generate_rewrite_rules' ), 10 );
  • bp-core/bp-core-rewrite.php

    new file mode 100644
     
     1<?php
     2/**
     3 * Rewrite module.
     4 *
     5 * @package BuddyPress
     6 * @subpackage Core
     7 */
     8
     9// Exit if accessed directly
     10if ( !defined( 'ABSPATH' ) ) exit;
     11
     12if ( class_exists( 'BP_Rewrite' ) ) return;
     13
     14/**
     15 * BuddyPress Rewrite Class.
     16 *
     17 * The BuddyPress rewrite class is responsible for injecting rewrite rules
     18 * into WordPress and for parsing various URI properties for use with BP
     19 * when a rewrite rule matches.
     20 *
     21 * @package BuddyPress
     22 * @subpackage Rewrite
     23 *
     24 * @since BuddyPress (2.0.0)
     25 */
     26class BP_Rewrite {
     27        /**
     28         * All of BP's registered query variables will be stored here.
     29         *
     30         * @var array
     31         */
     32        public $registered_query_vars = array();
     33
     34        /**
     35         * Constructor.
     36         */
     37        public function __construct() {
     38                add_filter( 'query_vars',                array( $this, 'query_vars' ) );
     39                add_action( 'bp_generate_rewrite_rules', array( $this, 'rewrite_rules' ),      999 );
     40                add_action( 'bp_parse_query',            array( $this, 'parse_query' ),        2 );
     41                add_action( 'bp_init',                   array( $this, 'setup_ajax_globals' ), 2  );
     42                add_action( 'posts_request',             array( $this, 'posts_request' ),      10, 2 );
     43        }
     44
     45        /**
     46         * Add custom rewrite rules for BuddyPress pages to WordPress.
     47         *
     48         * @param object $wp_rewrite The current WP_Rewrite instance.
     49         */
     50        public function rewrite_rules( $wp_rewrite ) {
     51                // Don't add rewrite rules on non-root blogs unless multiblog mode is on
     52                if ( ! bp_is_root_blog() && ! bp_is_multiblog_mode() ) {
     53                        return;
     54                }
     55
     56                if ( empty( buddypress()->pages ) ) {
     57                        buddypress()->pages = bp_core_get_directory_pages();
     58                }
     59
     60                $bp_rules = array();
     61
     62                // @todo test with various BP nested pages... might need to sort rewrite
     63                //       rules according to length of root slug for priority reasons
     64                // @todo support root profiles - can't see a decent way to do this
     65                // @todo remove dependency on WP pages and use virtual pages?
     66                //       for now, manually refresh permalinks when a BP page slug is altered
     67                foreach ( buddypress()->pages as $component => $data ) {
     68
     69                        // directory page (eg. /members/)
     70                        $bp_rules[ $data->slug . '/?$' ]        = 'index.php?bp_component=' . $component;
     71
     72                        // single page (eg. /members/*)
     73                        // also matches all item and action variables under this single page
     74                        $bp_rules[ $data->slug . '/([^?\#]*)' ] = 'index.php?bp_component=' . $component . '&bp_path=' . $wp_rewrite->preg_index( 1 );
     75
     76                }
     77
     78                $wp_rewrite->rules = array_merge( $bp_rules, $wp_rewrite->rules );
     79        }
     80
     81        /**
     82         * Set up various BP URI properties from the matched WP rewrite rules.
     83         *
     84         * @param object $query The current WP_Query instance.
     85         */
     86        public function parse_query( $query ) {
     87                // if on frontpage and if BP page is frontpage, set the BP component
     88                if ( $front_page_component = self::get_bp_frontpage_component_from_page_id( $query->query_vars['page_id'] ) ) {
     89                        $query->set( 'bp_component', $front_page_component );
     90                }
     91
     92                // if not on a BP page, stop now!
     93                if ( ! $query->get( 'bp_component' ) ) {
     94                        return;
     95                }
     96
     97                // set 'current_component'
     98                buddypress()->current_component = $query->get( 'bp_component' );
     99
     100                // set 'current_action' and 'action_variables'
     101                if ( $query->get( 'bp_path' ) ) {
     102                        // Break path into array
     103                        $bp_path = array_filter( explode( '/', $query->get( 'bp_path' ) ) );
     104
     105                        // this is to keep backpat behavior with directory action pages
     106                        // eg. /groups/create/
     107                        //
     108                        // the single current action is set in each component's loader
     109                        buddypress()->current_action = array_shift( $bp_path );
     110
     111                        // this might be used in the future to support non-fancy permalinks
     112                        $query->set( 'bp_action', buddypress()->current_action );
     113
     114                        if ( ! empty( $bp_path ) ) {
     115                                buddypress()->action_variables = $bp_path;
     116
     117                                // this might be used in the future to support non-fancy permalinks
     118                                $query->set( 'bp_action_variables', buddypress()->action_variables );
     119                        }
     120
     121                // we're on a directory page
     122                } else {
     123                        buddypress()->is_directory = true;
     124                }
     125
     126                // set as page
     127                $query->is_page = true;
     128
     129                // not a 404
     130                $query->is_404  = false;
     131        }
     132
     133        /**
     134         * Set up various BP URI properties when using AJAX.
     135         *
     136         * BP's URI globals now fires on the 'parse_query' hook.  The problem is
     137         * 'parse_query' doesn't fire on AJAX requests.  So if you attempt to use a
     138         * function like bp_is_current_action() during AJAX, it will not work.  This
     139         * has the potential to break some plugins utilizing this behavior.
     140         *
     141         * Fortunately, our old URI globals function handles AJAX requests just fine,
     142         * so let's bring it off the bench durng AJAX.
     143         */
     144        public function setup_ajax_globals() {
     145                // stop if we're not on an ajax request
     146                if ( ! defined( 'DOING_AJAX' ) || ( defined( 'DOING_AJAX' ) && constant( 'DOING_AJAX') !== true ) ) {
     147                        return;
     148                }
     149
     150                // sigh... hello old friend, we're stuck with you at least for now.
     151                bp_core_set_uri_globals();
     152        }
     153
     154        /**
     155         * Add our query vars to WordPress.
     156         */
     157        public function query_vars( $vars ) {
     158                $this->registered_query_vars[] = 'bp_component';
     159                $this->registered_query_vars[] = 'bp_path';
     160
     161                return array_merge( $this->registered_query_vars, $vars );
     162        }
     163
     164        /**
     165         * Change the SQL query when on a BP page.
     166         *
     167         * When we're on a BP page, a WP_Query loop is queried.  We don't want to
     168         * fetch these posts, so set the query to fetch a simple query.
     169         *
     170         * @todo Is there a better way to do this?
     171         *
     172         * @param string $retval The current SQL statement
     173         * @param object $query The current WP_Query instance.
     174         * @return string SQL statement
     175         */
     176        public function posts_request( $retval, $query ) {
     177                // if not on a BP page, stop now!
     178                if ( ! $query->get( 'bp_component' ) ) {
     179                        return $retval;
     180                }
     181
     182                // change the query to fetch nothing instead of WP posts
     183                // @todo is there a better way to do this without filtering 'posts_request'?
     184                return "SELECT 'nothing'";
     185        }
     186
     187        /**
     188         * Get the BuddyPress component ID from a WP page ID.
     189         *
     190         * Perhaps move to bp-core-functions.php?
     191         *
     192         * @param int $page_id The WP page ID set as front page.
     193         * @return string|bool String of component on success. Boolean false on failure.
     194         */
     195        public static function get_bp_frontpage_component_from_page_id( $page_id = 0 ) {
     196                if ( get_option( 'show_on_front' ) != 'page' ) {
     197                        return false;
     198                }
     199
     200                if ( get_option( 'page_on_front' ) != $page_id ) {
     201                        return false;
     202                }
     203
     204                if ( empty( buddypress()->pages ) ) {
     205                        buddypress()->pages = bp_core_get_directory_pages();
     206                }
     207
     208                foreach ( buddypress()->pages as $component => $data ) {
     209                        if ( $page_id == $data->id ) {
     210                                return $component;
     211                        }
     212
     213                }
     214
     215                return false;
     216        }
     217
     218        /**
     219         * Get the BuddyPress component ID if a BP page is set as frontpage.
     220         *
     221         * Perhaps move to bp-core-functions.php?
     222         *
     223         * @param int $page_id The WP page ID set as front page.
     224         * @return string|bool String of component on success. Boolean false on failure.
     225         */
     226        public static function get_bp_frontpage_component() {
     227                return self::get_bp_frontpage_component_from_page_id( get_option( 'page_on_front' ) );
     228        }
     229}
  • bp-core/bp-core-theme-compatibility.php

    function bp_theme_compat_reset_post( $args = array() ) { 
    531531        $post = new WP_Post( (object) $dummy );
    532532
    533533        // Copy the new post global into the main $wp_query
    534         $wp_query->post       = $post;
    535         $wp_query->posts      = array( $post );
     534        $wp_query->post              = $post;
     535        $wp_query->posts             = array( $post );
     536        $wp_query->queried_object    = $post;
     537        $wp_query->queried_object_id = $dummy['ID'];
    536538
    537539        // Prevent comments form from appearing
    538540        $wp_query->post_count = 1;
    function bp_template_include_theme_compat( $template = '' ) { 
    591593                return $template;
    592594        }
    593595
     596        if ( bp_current_component() ) {
     597                bp_set_theme_compat_active();
     598                do_action( 'bp_setup_theme_compat' );
     599        }
     600
    594601        /**
    595602         * Use this action to execute code that will communicate to BuddyPress's
    596603         * theme compatibility layer whether or not we're replacing the_content()
  • bp-groups/bp-groups-loader.php

    class BP_Groups_Component extends BP_Component { 
    151151                        'search_string'         => __( 'Search Groups...', 'buddypress' ),
    152152                        'global_tables'         => $global_tables,
    153153                        'meta_tables'           => $meta_tables,
     154                        'query_vars'            => array( 'bp_group_id' ),
    154155                );
    155156
    156157                parent::setup_globals( $args );
    157158
    158                 /** Single Group Globals **********************************************/
     159                /** Default Extension *************************************************/
    159160
    160                 // Are we viewing a single group?
    161                 if ( bp_is_groups_component() && $group_id = BP_Groups_Group::group_exists( bp_current_action() ) ) {
     161                $this->default_extension = apply_filters( 'bp_groups_default_extension', defined( 'BP_GROUPS_DEFAULT_EXTENSION' ) ? BP_GROUPS_DEFAULT_EXTENSION : 'home' );
     162
     163                /** Single Group ******************************************************/
     164
     165                // Set up backpat globals for plugins relying on them to exist on 'bp_init'
     166                $this->backpat_globals();
     167
     168                /** Misc **************************************************************/
     169
     170                // Illegal group names/slugs
     171                $this->forbidden_names = apply_filters( 'groups_forbidden_names', array(
     172                        'my-groups',
     173                        'create',
     174                        'invites',
     175                        'send-invites',
     176                        'forum',
     177                        'delete',
     178                        'add',
     179                        'admin',
     180                        'request-membership',
     181                        'members',
     182                        'settings',
     183                        'avatar',
     184                        $this->slug,
     185                        $this->root_slug,
     186                ) );
     187
     188                // Preconfigured group creation steps
     189                $this->group_creation_steps = apply_filters( 'groups_create_group_steps', array(
     190                        'group-details'  => array(
     191                                'name'       => __( 'Details',  'buddypress' ),
     192                                'position'   => 0
     193                        ),
     194                        'group-settings' => array(
     195                                'name'       => __( 'Settings', 'buddypress' ),
     196                                'position'   => 10
     197                        )
     198                ) );
     199
     200                // If avatar uploads are not disabled, add avatar option
     201                if ( ! (int) buddypress()->site_options['bp-disable-avatar-uploads'] ) {
     202                        $this->group_creation_steps['group-avatar'] = array(
     203                                'name'     => __( 'Avatar',   'buddypress' ),
     204                                'position' => 20
     205                        );
     206                }
     207
     208                // If friends component is active, add invitations
     209                if ( bp_is_active( 'friends' ) ) {
     210                        $this->group_creation_steps['group-invites'] = array(
     211                                'name'     => __( 'Invites', 'buddypress' ),
     212                                'position' => 30
     213                        );
     214                }
     215
     216                // Groups statuses
     217                $this->valid_status = apply_filters( 'groups_valid_status', array(
     218                        'public',
     219                        'private',
     220                        'hidden'
     221                ) );
     222
     223                // Auto join group when non group member performs group activity
     224                $this->auto_join = defined( 'BP_DISABLE_AUTO_GROUP_JOIN' ) && BP_DISABLE_AUTO_GROUP_JOIN ? false : true;
     225        }
     226
     227
     228        /**
     229         * Parse the main query and set up some pertinent properties.
     230         *
     231         * @since BuddyPress (2.0.0)
     232         *
     233         * @param object The main WP_Query
     234         */
     235        public function parse_query( $query ) {
     236                $bp = buddypress();
     237
     238                // the beginning of supporting non-fancy permalinks!
     239                //
     240                // still lots of work to do with our internal links to support querystrings
     241                //
     242                // you can use the following example:
     243                //    domain.com/?bp_group_id=X
     244                //
     245                // and bp_redirect_canonical() will redirect to the pretty permalink
     246                if ( $query->get( 'bp_group_id' ) && $group_slug = BP_Groups_Group::get_slug( $query->get( 'bp_group_id' ) ) ) {
     247                        // set pertinent query vars
     248                        $query->set( 'bp_component', 'groups' );
     249                        $query->set( 'bp_path', $group_slug );
     250                        $bp->current_action = $group_slug;
     251                }
     252
     253                // if not on a groups page, stop now!
     254                if ( $query->get( 'bp_component' ) !== 'groups' ) {
     255                        return;
     256                }
     257
     258                // if we're on the groups directory, stop now!
     259                if ( ! $query->get( 'bp_path' ) ) {
     260                        return;
     261                }
     262
     263                /* single group *******************************************************/
     264
     265                // set up single group
     266                //
     267                // we're doing a conditional here to prevent requerying b/c we might have
     268                // already set the current_group object.
     269                //
     270                // this is needed for unit tests to pass AND we should remove the
     271                // backpat_setup_globals() method later when backpat is null and void!
     272                if ( empty( $this->current_group->id ) ) {
     273                        $group_id = BP_Groups_Group::group_exists( bp_current_action() );
    162274
    163275                        $bp->is_single_item  = true;
    164276                        $current_group_class = apply_filters( 'bp_groups_current_group_class', 'BP_Groups_Group' );
    165277                        $this->current_group = apply_filters( 'bp_groups_current_group_object', new $current_group_class( $group_id ) );
     278                }
    166279
    167                         // When in a single group, the first action is bumped down one because of the
    168                         // group name, so we need to adjust this and set the group name to current_item.
    169                         $bp->current_item   = bp_current_action();
    170                         $bp->current_action = bp_action_variable( 0 );
    171                         array_shift( $bp->action_variables );
    172 
    173                         // Using "item" not "group" for generic support in other components.
    174                         if ( bp_current_user_can( 'bp_moderate' ) )
    175                                 bp_update_is_item_admin( true, 'groups' );
    176                         else
    177                                 bp_update_is_item_admin( groups_is_user_admin( bp_loggedin_user_id(), $this->current_group->id ), 'groups' );
    178 
    179                         // If the user is not an admin, check if they are a moderator
    180                         if ( !bp_is_item_admin() )
    181                                 bp_update_is_item_mod  ( groups_is_user_mod  ( bp_loggedin_user_id(), $this->current_group->id ), 'groups' );
     280                // No group - reset group
     281                if ( empty( $this->current_group->id ) ) {
     282                        $bp->is_single_item = false;
     283                        $this->current_group = 0;
    182284
     285                // Group exists - set up single group properties and current_X items
     286                } else {
    183287                        // Is the logged in user a member of the group?
    184                         if ( ( is_user_logged_in() && groups_is_user_member( bp_loggedin_user_id(), $this->current_group->id ) ) )
     288                        if ( ( is_user_logged_in() && groups_is_user_member( bp_loggedin_user_id(), $this->current_group->id ) ) ) {
    185289                                $this->current_group->is_user_member = true;
    186                         else
     290                        } else {
    187291                                $this->current_group->is_user_member = false;
     292                        }
    188293
    189294                        // Should this group be visible to the logged in user?
    190                         if ( 'public' == $this->current_group->status || $this->current_group->is_user_member )
     295                        if ( 'public' == $this->current_group->status || $this->current_group->is_user_member ) {
    191296                                $this->current_group->is_visible = true;
    192                         else
     297                        } else {
    193298                                $this->current_group->is_visible = false;
     299                        }
    194300
    195301                        // If this is a private or hidden group, does the user have access?
    196302                        if ( 'private' == $this->current_group->status || 'hidden' == $this->current_group->status ) {
    class BP_Groups_Component extends BP_Component { 
    202308                                $this->current_group->user_has_access = true;
    203309                        }
    204310
    205                 // Set current_group to 0 to prevent debug errors
    206                 } else {
    207                         $this->current_group = 0;
    208                 }
    209 
    210                 // Illegal group names/slugs
    211                 $this->forbidden_names = apply_filters( 'groups_forbidden_names', array(
    212                         'my-groups',
    213                         'create',
    214                         'invites',
    215                         'send-invites',
    216                         'forum',
    217                         'delete',
    218                         'add',
    219                         'admin',
    220                         'request-membership',
    221                         'members',
    222                         'settings',
    223                         'avatar',
    224                         $this->slug,
    225                         $this->root_slug,
    226                 ) );
    227 
    228                 // If the user was attempting to access a group, but no group by that name was found, 404
    229                 if ( bp_is_groups_component() && empty( $this->current_group ) && bp_current_action() && !in_array( bp_current_action(), $this->forbidden_names ) ) {
    230                         bp_do_404();
    231                         return;
     311                        // single group pages support a custom current_item property based on the URI
     312                        // therefore, we have to shift all other current_X items up
     313                        $bp->current_component = 'groups';
     314                        $bp->current_item      = bp_current_action();
     315                        $bp->current_action    = bp_action_variable( 0 );
     316                        array_shift( $bp->action_variables );
    232317                }
    233318
    234                 if ( bp_is_groups_component() && !empty( $this->current_group ) ) {
     319                /* canonical stuff *****************************************************/
    235320
    236                         $this->default_extension = apply_filters( 'bp_groups_default_extension', defined( 'BP_GROUPS_DEFAULT_EXTENSION' ) ? BP_GROUPS_DEFAULT_EXTENSION : 'home' );
     321                if ( ! empty( $this->current_group ) ) {
    237322
    238                         if ( !bp_current_action() ) {
     323                        if ( ! bp_current_action() ) {
    239324                                $bp->current_action = $this->default_extension;
    240325                        }
    241326
    class BP_Groups_Component extends BP_Component { 
    259344
    260345                }
    261346
    262                 // Group access control
    263                 if ( bp_is_groups_component() && !empty( $this->current_group ) ) {
    264                         if ( !$this->current_group->user_has_access ) {
     347                // if we're on a non-fancy link, a group exists and canonical redirect is on,
     348                // stop the rest of this method since we need to get redirected anyway.
     349                if ( $query->get( 'bp_group_id' ) && ! empty( $this->current_group ) && apply_filters( 'bp_do_redirect_canonical', true ) ) {
     350                        return;
     351                }
     352
     353                /* item admin **********************************************************/
     354
     355                // Using "item" not "group" for generic support in other components.
     356                if ( bp_current_user_can( 'bp_moderate' ) ) {
     357                        bp_update_is_item_admin( true, 'groups' );
     358                } else {
     359                        bp_update_is_item_admin( groups_is_user_admin( bp_loggedin_user_id(), $this->current_group->id ), 'groups' );
     360                }
     361
     362                // If the user is not an admin, check if they are a moderator
     363                if ( ! bp_is_item_admin() ) {
     364                        bp_update_is_item_mod  ( groups_is_user_mod  ( bp_loggedin_user_id(), $this->current_group->id ), 'groups' );
     365                }
     366
     367                /* group validation ***************************************************/
     368
     369                // If the user was attempting to access a group, but no group by that name was found, 404
     370                if ( empty( $this->current_group ) && bp_current_action() && ! in_array( bp_current_action(), $this->forbidden_names ) ) {
     371                        bp_do_404();
     372                        return;
     373                }
     374
     375                /** group access ******************************************************/
     376
     377                if ( !empty( $this->current_group ) ) {
     378                        if ( ! $this->current_group->user_has_access ) {
    265379
    266380                                // Hidden groups should return a 404 for non-members.
    267381                                // Unset the current group so that you're not redirected
    class BP_Groups_Component extends BP_Component { 
    273387                                        return;
    274388
    275389                                // Skip the no_access check on home and membership request pages
    276                                 } elseif ( !bp_is_current_action( 'home' ) && !bp_is_current_action( 'request-membership' ) ) {
     390                                } elseif ( ! bp_is_current_action( 'home' ) && ! bp_is_current_action( 'request-membership' ) ) {
    277391
    278392                                        // Off-limits to this user. Throw an error and redirect to the group's home page
    279393                                        if ( is_user_logged_in() ) {
    class BP_Groups_Component extends BP_Component { 
    291405                        }
    292406
    293407                        // Protect the admin tab from non-admins
    294                         if ( bp_is_current_action( 'admin' ) && !bp_is_item_admin() ) {
     408                        if ( bp_is_current_action( 'admin' ) && ! bp_is_item_admin() ) {
    295409                                bp_core_no_access( array(
    296410                                        'message'  => __( 'You are not an admin of this group.', 'buddypress' ),
    297411                                        'root'     => bp_get_group_permalink( $bp->groups->current_group ),
    class BP_Groups_Component extends BP_Component { 
    300414                        }
    301415                }
    302416
    303                 // Preconfigured group creation steps
    304                 $this->group_creation_steps = apply_filters( 'groups_create_group_steps', array(
    305                         'group-details'  => array(
    306                                 'name'       => __( 'Details',  'buddypress' ),
    307                                 'position'   => 0
    308                         ),
    309                         'group-settings' => array(
    310                                 'name'       => __( 'Settings', 'buddypress' ),
    311                                 'position'   => 10
    312                         )
    313                 ) );
     417                parent::parse_query( $query );
    314418
    315                 // If avatar uploads are not disabled, add avatar option
    316                 if ( ! (int) buddypress()->site_options['bp-disable-avatar-uploads'] ) {
    317                         $this->group_creation_steps['group-avatar'] = array(
    318                                 'name'     => __( 'Avatar',   'buddypress' ),
    319                                 'position' => 20
    320                         );
    321                 }
    322 
    323                 // If friends component is active, add invitations
    324                 if ( bp_is_active( 'friends' ) ) {
    325                         $this->group_creation_steps['group-invites'] = array(
    326                                 'name'     => __( 'Invites', 'buddypress' ),
    327                                 'position' => 30
    328                         );
    329                 }
    330 
    331                 // Groups statuses
    332                 $this->valid_status = apply_filters( 'groups_valid_status', array(
    333                         'public',
    334                         'private',
    335                         'hidden'
    336                 ) );
    337 
    338                 // Auto join group when non group member performs group activity
    339                 $this->auto_join = defined( 'BP_DISABLE_AUTO_GROUP_JOIN' ) && BP_DISABLE_AUTO_GROUP_JOIN ? false : true;
    340419        }
    341420
    342421        /**
    class BP_Groups_Component extends BP_Component { 
    606685
    607686                parent::setup_title();
    608687        }
     688
     689        /**
     690         * Set up some backwards-compatibility globals if we're on a group page.
     691         *
     692         * Before rewrite rules, we would set the current_X items on 'init'.  With
     693         * rewrite rules, we set them on 'parse_query', which runs later and could
     694         * potentially break functionality for plugins checking for current_X items on
     695         * 'bp_init'.
     696         *
     697         * The current_X items are duplicated here using {@link bp_core_get_from_uri()} for
     698         * backpat.  In a future release, we can remove this method entirely.
     699         *
     700         * @since BuddyPress (2.0.0)
     701         */
     702        protected function backpat_globals() {
     703                $bp = buddypress();
     704
     705                if ( bp_core_get_from_uri( 'root_slug' ) == bp_get_groups_root_slug() ) {
     706                        $bp->current_component = $this->slug;
     707
     708                        // we're on a single group page
     709                        if ( $group_id = BP_Groups_Group::group_exists( urldecode( bp_core_get_from_uri( 'item' ) ) ) ) {
     710
     711                                $bp->is_single_item  = true;
     712                                $current_group_class = apply_filters( 'bp_groups_current_group_class', 'BP_Groups_Group' );
     713                                $this->current_group = apply_filters( 'bp_groups_current_group_object', new $current_group_class( $group_id ) );
     714
     715                                // backpat for plugins checking current_X items on 'bp_init'
     716                                $bp->current_item     = bp_core_get_from_uri( 'item' );
     717                                $bp->current_action   = bp_core_get_from_uri( 'component' );
     718                                $bp->action_variables = (array) bp_core_get_from_uri( 'action' );
     719                                array_unshift( $bp->action_variables, bp_core_get_from_uri( 'action_variables' ) );
     720
     721                                if ( ! bp_current_action() ) {
     722                                        $bp->current_action = $this->default_extension;
     723                                }
     724
     725                                // Is the logged in user a member of the group?
     726                                if ( ( is_user_logged_in() && groups_is_user_member( bp_loggedin_user_id(), $this->current_group->id ) ) ) {
     727                                        $this->current_group->is_user_member = true;
     728                                } else {
     729                                        $this->current_group->is_user_member = false;
     730                                }
     731
     732                                // Should this group be visible to the logged in user?
     733                                if ( 'public' == $this->current_group->status || $this->current_group->is_user_member ) {
     734                                        $this->current_group->is_visible = true;
     735                                } else {
     736                                        $this->current_group->is_visible = false;
     737                                }
     738
     739                                // If this is a private or hidden group, does the user have access?
     740                                if ( 'private' == $this->current_group->status || 'hidden' == $this->current_group->status ) {
     741                                        if ( $this->current_group->is_user_member && is_user_logged_in() || bp_current_user_can( 'bp_moderate' ) )
     742                                                $this->current_group->user_has_access = true;
     743                                        else
     744                                                $this->current_group->user_has_access = false;
     745                                } else {
     746                                        $this->current_group->user_has_access = true;
     747                                }
     748
     749                        // directory action
     750                        // eg. /groups/create/
     751                        } else {
     752                                $bp->current_action = bp_core_get_from_uri( 'item' );
     753                        }
     754
     755                }
     756
     757                if ( empty( $this->current_group ) ) {
     758                        $this->current_group = 0;
     759                }
     760        }
    609761}
    610762
    611763
  • bp-loader.php

    class BuddyPress { 
    446446                require( $this->plugin_dir . 'bp-core/bp-core-functions.php'  );
    447447                require( $this->plugin_dir . 'bp-core/bp-core-moderation.php' );
    448448                require( $this->plugin_dir . 'bp-core/bp-core-loader.php'     );
     449                require( $this->plugin_dir . 'bp-core/bp-core-rewrite.php'     );
    449450
    450451                // Skip or load deprecated content
    451452                if ( false !== $this->load_deprecated ) {
    class BuddyPress { 
    477478                if ( bp_is_deactivation( $this->basename ) )
    478479                        return;
    479480
     481                // Set up rewrite rules
     482                add_action( 'bp_loaded', array( $this, 'setup_rewrite_rules' ), 0 );
     483
    480484                // Array of BuddyPress core actions
    481485                $actions = array(
    482486                        'setup_theme',              // Setup the default theme compat
     487                        'register_theme_directory', // Register the theme directory
     488                        'register_theme_packages',  // Register bundled theme packages (bp-themes)
     489                );
     490
     491                /*
     492                        // these are not being used at the moment
    483493                        'setup_current_user',       // Setup currently logged in user
    484494                        'register_post_types',      // Register post types
    485495                        'register_post_statuses',   // Register post statuses
    486496                        'register_taxonomies',      // Register taxonomies
    487497                        'register_views',           // Register the views
    488                         'register_theme_directory', // Register the theme directory
    489                         'register_theme_packages',  // Register bundled theme packages (bp-themes)
    490498                        'load_textdomain',          // Load textdomain
    491499                        'add_rewrite_tags',         // Add rewrite tags
    492500                        'generate_rewrite_rules'    // Generate rewrite rules
    493                 );
     501                */
    494502
    495503                // Add the actions
    496504                foreach( $actions as $class_action )
    class BuddyPress { 
    592600                // Setup the theme package to use for compatibility
    593601                bp_setup_theme_compat( bp_get_theme_package_id() );
    594602        }
     603
     604        /**
     605         * Set up the rewrite rules to be used with BuddyPress.
     606         *
     607         * @since BuddyPress (2.0.0)
     608         */
     609        public function setup_rewrite_rules() {
     610                $this->rewrite = new BP_Rewrite;
     611        }
    595612}
    596613
    597614/**
  • bp-members/bp-members-loader.php

    class BP_Members_Component extends BP_Component { 
    7373                        'root_slug'     => isset( $bp->pages->members->slug ) ? $bp->pages->members->slug : BP_MEMBERS_SLUG,
    7474                        'has_directory' => true,
    7575                        'search_string' => __( 'Search Members...', 'buddypress' ),
     76                        'query_vars'    => array( 'bp_user_id' ),
    7677                ) );
    7778
     79                /** Default Profile Component *****************************************/
     80
     81                if ( ! defined( 'BP_DEFAULT_COMPONENT' ) ) {
     82                        if ( bp_is_active( 'activity' ) && isset( $bp->pages->activity ) ) {
     83                                $bp->default_component = bp_get_activity_slug();
     84                        } else {
     85                                $bp->default_component = ( 'xprofile' === $bp->profile->id ) ? 'profile' : $bp->profile->id;
     86                        }
     87
     88                } else {
     89                        $bp->default_component = BP_DEFAULT_COMPONENT;
     90                }
     91
    7892                /** Logged in user ****************************************************/
    7993
    8094                // Fetch the full name for the logged in user
    class BP_Members_Component extends BP_Component { 
    91105
    92106                /** Displayed user ****************************************************/
    93107
    94                 // The domain for the user currently being displayed
    95                 $bp->displayed_user->domain   = bp_core_get_user_domain( bp_displayed_user_id() );
    96 
    97                 // The core userdata of the user who is currently being displayed
    98                 $bp->displayed_user->userdata = bp_core_get_core_userdata( bp_displayed_user_id() );
    99 
    100                 // Fetch the full name displayed user
    101                 $bp->displayed_user->fullname = bp_core_get_user_displayname( bp_displayed_user_id() );
     108                // Set up backpat globals for plugins relying on them to exist on 'bp_init'
     109                $this->backpat_globals();
    102110
    103111                /** Signup ***************************************************/
    104112                $bp->signup = new stdClass;
    class BP_Members_Component extends BP_Component { 
    111119                        $bp->profile->id   = 'profile';
    112120                }
    113121
    114                 /** Default Profile Component *****************************************/
     122        }
    115123
    116                 if ( !defined( 'BP_DEFAULT_COMPONENT' ) ) {
    117                         if ( bp_is_active( 'activity' ) && isset( $bp->pages->activity ) ) {
    118                                 $bp->default_component = bp_get_activity_slug();
     124        /**
     125         * Parse the main query and set up some pertinent properties.
     126         *
     127         * @since BuddyPress (2.0.0)
     128         *
     129         * @param object The main WP_Query
     130         */
     131        public function parse_query( $query ) {
     132                $bp = buddypress();
     133
     134                // the beginning of supporting non-fancy permalinks!
     135                //
     136                // still lots of work to do with our internal links to support querystrings
     137                //
     138                // you can use the following example:
     139                //    domain.com/?bp_user_id=X
     140                //
     141                // and bp_redirect_canonical() will redirect to pretty permalink
     142                if ( $user_id = $query->get( 'bp_user_id' ) ) {
     143                        $bp->displayed_user->id       = $user_id;
     144                        $bp->displayed_user->userdata = get_user_by( 'id', $user_id );
     145                        $bp->displayed_user->fullname = $bp->displayed_user->userdata->display_name;
     146                        $bp->displayed_user->domain   = bp_core_get_user_domain( $user_id );
     147
     148                        // set pertinent query vars
     149                        $query->set( 'bp_component', 'members' );
     150                        $query->set( 'bp_path', bp_is_username_compatibility_mode() ? $bp->displayed_user->userdata->user_login : $bp->displayed_user->userdata->user_nicename );
     151                }
     152
     153                // if not on a members page, stop now!
     154                if ( $query->get( 'bp_component' ) !== 'members' ) {
     155                        return;
     156                }
     157
     158                // if we're on the members directory, stop now!
     159                if ( ! $query->get( 'bp_path' ) ) {
     160                        return;
     161                }
     162
     163                // single member pages support a custom current_item property based on the URI
     164                // as well as a custom current_component different than $this->id
     165                //
     166                // therefore, we have to shift all other current_X items up
     167                $bp->current_item      = bp_current_action();
     168                $bp->current_component = array_shift( $bp->action_variables );
     169                $bp->current_action    = array_shift( $bp->action_variables );
     170
     171                /* displayed user ******************************************************/
     172
     173                // set up displayed user
     174                //
     175                // we're doing a conditional here to prevent requerying b/c we might have
     176                // already set the displayed_user object.
     177                //
     178                // this is needed for unit tests to pass AND we should remove the
     179                // backpat_setup_globals() method later when backpat is null and void!
     180                if ( ! bp_displayed_user_id() ) {
     181                        if ( bp_is_username_compatibility_mode() ) {
     182                                $bp->displayed_user->id = (int) bp_core_get_userid( urldecode( $bp->current_item ) );
    119183                        } else {
    120                                 $bp->default_component = ( 'xprofile' === $bp->profile->id ) ? 'profile' : $bp->profile->id;
     184                                $bp->displayed_user->id = (int) bp_core_get_userid_from_nicename( urldecode( $bp->current_item ) );
    121185                        }
    122186
    123                 } else {
    124                         $bp->default_component = BP_DEFAULT_COMPONENT;
     187                        // The domain for the user currently being displayed
     188                        $bp->displayed_user->domain   = bp_core_get_user_domain( bp_displayed_user_id() );
     189
     190                        // The core userdata of the user who is currently being displayed
     191                        $bp->displayed_user->userdata = bp_core_get_core_userdata( bp_displayed_user_id() );
     192
     193                        // Fetch the full name displayed user
     194                        $bp->displayed_user->fullname = bp_core_get_user_displayname( bp_displayed_user_id() );
     195                }
     196
     197                // If no user, set displayed user properties to empty
     198                if ( ! bp_displayed_user_id() ) {
     199                        $bp->displayed_user->domain = $bp->displayed_user->userdata = $bp->displayed_user->fullname = false;
    125200                }
    126201
    127                 if ( bp_displayed_user_id() ) {
    128                         $bp->canonical_stack['base_url'] = bp_displayed_user_domain();
     202                /* canonical stuff *****************************************************/
    129203
    130                         if ( bp_current_component() ) {
    131                                 $bp->canonical_stack['component'] = bp_current_component();
    132                         }
     204                $bp->canonical_stack['base_url'] = bp_displayed_user_domain();
    133205
    134                         if ( bp_current_action() ) {
    135                                 $bp->canonical_stack['action'] = bp_current_action();
    136                         }
     206                if ( bp_current_component() ) {
     207                        $bp->canonical_stack['component'] = bp_current_component();
     208                }
    137209
    138                         if ( !empty( $bp->action_variables ) ) {
    139                                 $bp->canonical_stack['action_variables'] = bp_action_variables();
    140                         }
     210                if ( bp_current_action() ) {
     211                        $bp->canonical_stack['action'] = bp_current_action();
     212                }
    141213
    142                         if ( !bp_current_component() ) {
    143                                 $bp->current_component = $bp->default_component;
    144                         } else if ( bp_is_current_component( $bp->default_component ) && !bp_current_action() ) {
    145                                 // The canonical URL will not contain the default component
    146                                 unset( $bp->canonical_stack['component'] );
    147                         }
     214                if ( !empty( $bp->action_variables ) ) {
     215                        $bp->canonical_stack['action_variables'] = bp_action_variables();
     216                }
    148217
    149                         // if we're on a spammer's profile page, only users with the 'bp_moderate' cap
    150                         // can view subpages on the spammer's profile
    151                         //
    152                         // users without the cap trying to access a spammer's subnav page will get
    153                         // redirected to the root of the spammer's profile page.  this occurs by
    154                         // by removing the component in the canonical stack.
    155                         if ( bp_is_user_spammer( bp_displayed_user_id() ) && ! bp_current_user_can( 'bp_moderate' ) ) {
     218                if ( ! bp_current_component() ) {
     219                        $bp->current_component = $bp->default_component;
     220
     221                } else if ( bp_is_current_component( $bp->default_component ) && ! bp_current_action() ) {
     222                        // The canonical URL will not contain the default component
     223                        unset( $bp->canonical_stack['component'] );
     224                }
     225
     226                /** user validation ***************************************************/
     227
     228                // user doesn't exist, set 404
     229                if ( ! bp_displayed_user_id() ) {
     230                        $bp->current_component = '';
     231                        bp_do_404();
     232                        return;
     233
     234                // if we're on a spammer's profile page, only users with the 'bp_moderate' cap
     235                // can view subpages on the spammer's profile
     236                //
     237                // users without the cap trying to access a spammer's subnav page will get
     238                // redirected to the root of the spammer's profile page.  this occurs by
     239                // by removing the component in the canonical stack.
     240                } elseif ( bp_is_user_spammer( bp_displayed_user_id() ) ) {
     241                        if ( ! bp_current_user_can( 'bp_moderate' ) ) {
    156242                                unset( $bp->canonical_stack['component'] );
     243                                $bp->current_component = '';
     244                                bp_do_404();
     245                                return;
     246                        } else {
     247                                bp_core_add_message( __( 'This user has been marked as a spammer. Only site admins can view this profile.', 'buddypress' ), 'warning' );
    157248                        }
    158249                }
     250
     251                parent::parse_query( $query );
    159252        }
    160253
    161254        /**
    class BP_Members_Component extends BP_Component { 
    165258                $bp = buddypress();
    166259
    167260                // Add 'Profile' to the main navigation
    168                 if ( !bp_is_active( 'xprofile' ) ) {
     261                if ( ! bp_is_active( 'xprofile' ) ) {
    169262
    170263                        // Don't set up navigation if there's no user
    171                         if ( !is_user_logged_in() && !bp_is_user() ) {
     264                        if ( ! is_user_logged_in() && ! bp_is_user() ) {
    172265                                return;
    173266                        }
    174267
    class BP_Members_Component extends BP_Component { 
    220313
    221314                parent::setup_title();
    222315        }
     316
     317        /**
     318         * Set up some backwards-compatibility globals if we're on a member page.
     319         *
     320         * Before rewrite rules, we would set the current_X items on 'init'.  With
     321         * rewrite rules, we set them on 'parse_query', which runs later and could
     322         * potentially break functionality for plugins checking for current_X items on
     323         * 'bp_init'.
     324         *
     325         * The current_X items are duplicated here using {@link bp_core_get_from_uri()} for
     326         * backpat.  In a future release, we can remove this method entirely.
     327         *
     328         * @since BuddyPress (2.0.0)
     329         */
     330        protected function backpat_globals() {
     331                $bp = buddypress();
     332
     333                if ( bp_core_get_from_uri( 'root_slug' ) == bp_get_members_root_slug() ) {
     334                        $bp->current_component = $this->slug;
     335
     336                        // we're on a single member page
     337                        if ( $current_item = urldecode( bp_core_get_from_uri( 'item' ) ) ) {
     338                                // set up displayed user ID
     339                                if ( bp_is_username_compatibility_mode() ) {
     340                                        $bp->displayed_user->id = (int) bp_core_get_userid( $current_item );
     341                                } else {
     342                                        $bp->displayed_user->id = (int) bp_core_get_userid_from_nicename( $current_item );
     343                                }
     344
     345                                // The domain for the user currently being displayed
     346                                $bp->displayed_user->domain   = bp_core_get_user_domain( bp_displayed_user_id() );
     347
     348                                // The core userdata of the user who is currently being displayed
     349                                $bp->displayed_user->userdata = bp_core_get_core_userdata( bp_displayed_user_id() );
     350
     351                                // Fetch the full name displayed user
     352                                $bp->displayed_user->fullname = bp_core_get_user_displayname( bp_displayed_user_id() );
     353
     354                                // backpat for plugins checking current_X items on 'bp_init'
     355                                $bp->current_component = bp_core_get_from_uri( 'component' );
     356                                $bp->current_item      = bp_core_get_from_uri( 'item' );
     357                                $bp->current_action    = bp_core_get_from_uri( 'action' );
     358                                $bp->action_variables  = bp_core_get_from_uri( 'action_variables' );
     359
     360                                if ( ! bp_current_component() ) {
     361                                        $bp->current_component = $bp->default_component;
     362                                }
     363                        }
     364
     365                } else {
     366                        // Set displayed user properties to empty
     367                        $bp->displayed_user->id     = 0;
     368                        $bp->displayed_user->domain = $bp->displayed_user->userdata = $bp->displayed_user->fullname = false;
     369                }
     370
     371        }
    223372}
    224373
    225374function bp_setup_members() {
  • tests/includes/testcase.php

    class BP_UnitTestCase extends WP_UnitTestCase { 
    142142                        $GLOBALS['blog_id'] = $GLOBALS['current_blog']->blog_id;
    143143                }
    144144
     145                $this->flush_cache();
     146                // For BuddyPress, James.
     147                $GLOBALS['bp']->loggedin_user = NULL;
     148                do_action( 'bp_init' );
     149
    145150                unset($GLOBALS['wp_query'], $GLOBALS['wp_the_query']);
    146151                $GLOBALS['wp_the_query'] = new WP_Query();
    147152                $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
    class BP_UnitTestCase extends WP_UnitTestCase { 
    156161                }
    157162
    158163                $GLOBALS['wp']->main($parts['query']);
    159 
    160                 // For BuddyPress, James.
    161                 $GLOBALS['bp']->loggedin_user = NULL;
    162                 do_action( 'bp_init' );
    163164        }
    164165
    165166        protected function checkRequirements() {
  • tests/testcases/routing/activity.php

    class BP_Tests_Routing_Activity extends BP_UnitTestCase { 
    99        public function setUp() {
    1010                parent::setUp();
    1111
     12                global $wp_rewrite;
     13                $wp_rewrite->set_permalink_structure('/%postname%/');
     14                $wp_rewrite->flush_rules();
     15
    1216                $this->old_current_user = get_current_user_id();
    1317                $this->set_current_user( $this->factory->user->create( array( 'role' => 'subscriber' ) ) );
    1418        }
    class BP_Tests_Routing_Activity extends BP_UnitTestCase { 
    1620        public function tearDown() {
    1721                parent::tearDown();
    1822                $this->set_current_user( $this->old_current_user );
     23                $GLOBALS['wp_rewrite']->init();
    1924        }
    2025
    2126        function test_activity_directory() {
  • tests/testcases/routing/friends.php

    class BP_Tests_Routing_Friends extends BP_UnitTestCase { 
    99        public function setUp() {
    1010                parent::setUp();
    1111
     12                global $wp_rewrite;
     13                $wp_rewrite->set_permalink_structure('/%postname%/');
     14                $wp_rewrite->flush_rules();
     15
    1216                $this->old_current_user = get_current_user_id();
    1317                $this->set_current_user( $this->factory->user->create( array( 'role' => 'subscriber' ) ) );
    1418        }
    class BP_Tests_Routing_Friends extends BP_UnitTestCase { 
    1620        public function tearDown() {
    1721                parent::tearDown();
    1822                $this->set_current_user( $this->old_current_user );
     23                $GLOBALS['wp_rewrite']->init();
    1924        }
    2025
    2126        function test_member_friends() {
  • tests/testcases/routing/groups.php

    class BP_Tests_Routing_Groups extends BP_UnitTestCase { 
    99        public function setUp() {
    1010                parent::setUp();
    1111
     12                global $wp_rewrite;
     13                $wp_rewrite->set_permalink_structure('/%postname%/');
     14                $wp_rewrite->flush_rules();
     15
    1216                $this->old_current_user = get_current_user_id();
    1317                $this->set_current_user( $this->factory->user->create( array( 'role' => 'subscriber' ) ) );
    1418        }
    class BP_Tests_Routing_Groups extends BP_UnitTestCase { 
    1620        public function tearDown() {
    1721                parent::tearDown();
    1822                $this->set_current_user( $this->old_current_user );
     23                $GLOBALS['wp_rewrite']->init();
    1924        }
    2025
    2126        function test_member_groups() {
  • tests/testcases/routing/members.php

    class BP_Tests_Routing_Members extends BP_UnitTestCase { 
    99        public function setUp() {
    1010                parent::setUp();
    1111
     12                global $wp_rewrite;
     13                $wp_rewrite->set_permalink_structure('/%postname%/');
     14                $wp_rewrite->flush_rules();
     15
    1216                $this->old_current_user = get_current_user_id();
    1317                $this->set_current_user( $this->factory->user->create( array( 'user_login' => 'paulgibbs', 'role' => 'subscriber' ) ) );
    1418        }
    class BP_Tests_Routing_Members extends BP_UnitTestCase { 
    1620        public function tearDown() {
    1721                parent::tearDown();
    1822                $this->set_current_user( $this->old_current_user );
     23                $GLOBALS['wp_rewrite']->init();
    1924        }
    2025
    2126        function test_members_directory() {
  • tests/testcases/routing/messages.php

    class BP_Tests_Routing_Messages extends BP_UnitTestCase { 
    99        public function setUp() {
    1010                parent::setUp();
    1111
     12                global $wp_rewrite;
     13                $wp_rewrite->set_permalink_structure('/%postname%/');
     14                $wp_rewrite->flush_rules();
     15
    1216                $this->old_current_user = get_current_user_id();
    1317                $this->set_current_user( $this->factory->user->create( array( 'role' => 'subscriber' ) ) );
    1418        }
    class BP_Tests_Routing_Messages extends BP_UnitTestCase { 
    1620        public function tearDown() {
    1721                parent::tearDown();
    1822                $this->set_current_user( $this->old_current_user );
     23                $GLOBALS['wp_rewrite']->init();
    1924        }
    2025
    2126        function test_member_messages() {
  • tests/testcases/routing/settings.php

    class BP_Tests_Routing_Settings extends BP_UnitTestCase { 
    99        public function setUp() {
    1010                parent::setUp();
    1111
     12                global $wp_rewrite;
     13                $wp_rewrite->set_permalink_structure('/%postname%/');
     14                $wp_rewrite->flush_rules();
     15
    1216                $this->old_current_user = get_current_user_id();
    1317                $this->set_current_user( $this->factory->user->create( array( 'role' => 'subscriber' ) ) );
    1418        }
    class BP_Tests_Routing_Settings extends BP_UnitTestCase { 
    1620        public function tearDown() {
    1721                parent::tearDown();
    1822                $this->set_current_user( $this->old_current_user );
     23                $GLOBALS['wp_rewrite']->init();
    1924        }
    2025
    2126        function test_member_settings() {
  • tests/testcases/routing/xprofile.php

    class BP_Tests_Routing_XProfile extends BP_UnitTestCase { 
    99        public function setUp() {
    1010                parent::setUp();
    1111
     12                global $wp_rewrite;
     13                $wp_rewrite->set_permalink_structure('/%postname%/');
     14                $wp_rewrite->flush_rules();
     15
    1216                $this->old_current_user = get_current_user_id();
    1317                $this->set_current_user( $this->factory->user->create( array( 'role' => 'subscriber' ) ) );
    1418        }
    class BP_Tests_Routing_XProfile extends BP_UnitTestCase { 
    1620        public function tearDown() {
    1721                parent::tearDown();
    1822                $this->set_current_user( $this->old_current_user );
     23                $GLOBALS['wp_rewrite']->init();
    1924        }
    2025
    2126        function test_member_profile() {