Skip to:
Content

BuddyPress.org

Changeset 8610


Ignore:
Timestamp:
07/12/2014 03:01:27 AM (11 years ago)
Author:
boonebgorges
Message:

Untangle some load order and mutual dependency issues between component loaders

BuddyPress's components are dependent upon each other in numerous ways. All
components depend in one way or another on bp-core. Many components reference
bp-members functions and globals. References to bp-xprofile can be found in
a number of components. And so on. We have managed to make these dependencies
work on a case-by-case basis, though the system becomes less stable as it
becomes more complex. The fact that all components are loaded at
bp_setup_components introduces the possibliity of numerous race conditions that
may not cause problems on vanilla installations of BuddyPress, but can cause
fatal errors when trying to customize in various ways.

As part of an ongoing project to disentangle and regularize these dependencies
(see eg #5750), this changeset introduces a few enhancements that make the
dependencies between components more predictable, more serialized, and more
stable.

  • In bp-members and bp-groups, move canonical_stack determination out of the main setup_globals() method and into its own setup_canonical_stack() method. This new method runs after all components have had a chance to run setup_globals(). As a result, the components are able to reference each other safely when determining default and fallback components for redirects (for example, the members component has access to the activity component's slug and other global data when determining whether example.com/members/boone/activity/ should resolve to example.com/members/boone/)
  • In bp-members, use only WP core data to set up the loggedin_user and displayed_user global objects. Previously, these objects were configured by referenced to xprofile, which required that xprofile be loaded before members. Now, users' display names are first loaded from wp_users, and are overridden by the xprofile component via filter, only after xprofile has fully initialized.
  • In bp-xprofile, move the Settings > Profile navigation setup routine out of the main setup_nav() task. bp-xprofile loads early, before bp-settings has had a chance to set up its top-level navigation. As a result, bp-xprofile must wait until the bp_settings_setup_nav action to add its Profile subnav item.
  • Fine-tune the component load order. bp-core, which acts more like a library of common functionality than like a traditional component, is moved from bp_setup_components:10 to bp_loaded:0. This ensures that it is available to all other components. bp-xprofile, which must load after bp-members but at the same time is closely coupled to it, is moved to bp_setup_components:2, just after bp-members.

These changes are enough to make it possible to move forward on dependent
tickets; see, for example, #5407. It's likely that significant entanglement
and load-order issues remain. We'll continue to fix them as they arise, by
making load order more explicit, and by breaking the component bootstrap
process into increasingly discrete chunks.

Fixes #5436

Props boonebgorges, r-a-y

Location:
trunk/src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-core/bp-core-actions.php

    r7542 r8610  
    6767add_action( 'bp_init', 'bp_core_set_uri_globals',    2  );
    6868add_action( 'bp_init', 'bp_setup_globals',           4  );
     69add_action( 'bp_init', 'bp_setup_canonical_stack',   5  );
    6970add_action( 'bp_init', 'bp_setup_nav',               6  );
    7071add_action( 'bp_init', 'bp_setup_title',             8  );
  • trunk/src/bp-core/bp-core-component.php

    r8573 r8610  
    338338        add_action( 'bp_setup_globals',          array( $this, 'setup_globals'          ), 10 );
    339339
     340        // Set up canonical stack
     341        add_action( 'bp_setup_canonical_stack',  array( $this, 'setup_canonical_stack'  ), 10 );
     342
    340343        // Include required files. Called early to ensure that BP core
    341344        // components are loaded before plugins that hook their loader functions
     
    378381        do_action( 'bp_' . $this->id . '_setup_actions' );
    379382    }
     383
     384    /**
     385     * Set up the canonical URL stack for this component.
     386     *
     387     * @since BuddyPress (2.1.0)
     388     */
     389    public function setup_canonical_stack() {}
    380390
    381391    /**
  • trunk/src/bp-core/bp-core-dependency.php

    r7542 r8610  
    3030function bp_setup_components() {
    3131    do_action( 'bp_setup_components' );
     32}
     33
     34/**
     35 * Fire the 'bp_setup_canonical_stack' action, where plugins should set up their canonical URL.
     36 */
     37function bp_setup_canonical_stack() {
     38    do_action( 'bp_setup_canonical_stack' );
    3239}
    3340
  • trunk/src/bp-core/bp-core-loader.php

    r8223 r8610  
    264264    buddypress()->core = new BP_Core();
    265265}
    266 add_action( 'bp_setup_components', 'bp_setup_core', 2 );
     266add_action( 'bp_loaded', 'bp_setup_core', 0 );
  • trunk/src/bp-groups/bp-groups-loader.php

    r8605 r8610  
    241241        }
    242242
    243         if ( bp_is_groups_component() && !empty( $this->current_group ) ) {
    244 
    245             $this->default_extension = apply_filters( 'bp_groups_default_extension', defined( 'BP_GROUPS_DEFAULT_EXTENSION' ) ? BP_GROUPS_DEFAULT_EXTENSION : 'home' );
    246 
    247             if ( !bp_current_action() ) {
    248                 $bp->current_action = $this->default_extension;
    249             }
    250 
    251             // Prepare for a redirect to the canonical URL
    252             $bp->canonical_stack['base_url'] = bp_get_group_permalink( $this->current_group );
    253 
    254             if ( bp_current_action() ) {
    255                 $bp->canonical_stack['action'] = bp_current_action();
    256             }
    257 
    258             if ( !empty( $bp->action_variables ) ) {
    259                 $bp->canonical_stack['action_variables'] = bp_action_variables();
    260             }
    261 
    262             // When viewing the default extension, the canonical URL should not have
    263             // that extension's slug, unless more has been tacked onto the URL via
    264             // action variables
    265             if ( bp_is_current_action( $this->default_extension ) && empty( $bp->action_variables ) )  {
    266                 unset( $bp->canonical_stack['action'] );
    267             }
    268 
    269         }
    270 
    271243        // Preconfigured group creation steps
    272244        $this->group_creation_steps = apply_filters( 'groups_create_group_steps', array(
     
    306278        // Auto join group when non group member performs group activity
    307279        $this->auto_join = defined( 'BP_DISABLE_AUTO_GROUP_JOIN' ) && BP_DISABLE_AUTO_GROUP_JOIN ? false : true;
     280    }
     281
     282    /**
     283     * Set up canonical stack for this component.
     284     *
     285     * @since BuddyPress (2.1.0)
     286     */
     287    public function setup_canonical_stack() {
     288        if ( ! bp_is_groups_component() ) {
     289            return;
     290        }
     291
     292        if ( empty( $this->current_group ) ) {
     293            return;
     294        }
     295
     296
     297        $this->default_extension = apply_filters( 'bp_groups_default_extension', defined( 'BP_GROUPS_DEFAULT_EXTENSION' ) ? BP_GROUPS_DEFAULT_EXTENSION : 'home' );
     298
     299        if ( !bp_current_action() ) {
     300            buddypress()->current_action = $this->default_extension;
     301        }
     302
     303        // Prepare for a redirect to the canonical URL
     304        buddypress()->canonical_stack['base_url'] = bp_get_group_permalink( $this->current_group );
     305
     306        if ( bp_current_action() ) {
     307            buddypress()->canonical_stack['action'] = bp_current_action();
     308        }
     309
     310        if ( !empty( buddypress()->action_variables ) ) {
     311            buddypress()->canonical_stack['action_variables'] = bp_action_variables();
     312        }
     313
     314        // When viewing the default extension, the canonical URL should not have
     315        // that extension's slug, unless more has been tacked onto the URL via
     316        // action variables
     317        if ( bp_is_current_action( $this->default_extension ) && empty( buddypress()->action_variables ) )  {
     318            unset( buddypress()->canonical_stack['action'] );
     319        }
    308320    }
    309321
  • trunk/src/bp-members/bp-members-loader.php

    r8568 r8610  
    9797        /** Logged in user ****************************************************/
    9898
     99        // The core userdata of the user who is currently logged in.
     100        $bp->loggedin_user->userdata       = bp_core_get_core_userdata( bp_loggedin_user_id() );
     101
    99102        // Fetch the full name for the logged in user
    100         $bp->loggedin_user->fullname       = bp_core_get_user_displayname( bp_loggedin_user_id() );
     103        $bp->loggedin_user->fullname       = isset( $bp->loggedin_user->userdata->display_name ) ? $bp->loggedin_user->userdata->display_name : '';
    101104
    102105        // Hits the DB on single WP installs so get this separately
     
    106109        $bp->loggedin_user->domain         = bp_core_get_user_domain( bp_loggedin_user_id() );
    107110
    108         // The core userdata of the user who is currently logged in.
    109         $bp->loggedin_user->userdata       = bp_core_get_core_userdata( bp_loggedin_user_id() );
    110 
    111111        /** Displayed user ****************************************************/
     112
     113        // The core userdata of the user who is currently being displayed
     114        $bp->displayed_user->userdata = bp_core_get_core_userdata( bp_displayed_user_id() );
     115
     116        // Fetch the full name displayed user
     117        $bp->displayed_user->fullname = isset( $bp->displayed_user->userdata->fullname ) ? $bp->displayed_user->userdata->fullname : '';
    112118
    113119        // The domain for the user currently being displayed
    114120        $bp->displayed_user->domain   = bp_core_get_user_domain( bp_displayed_user_id() );
    115 
    116         // The core userdata of the user who is currently being displayed
    117         $bp->displayed_user->userdata = bp_core_get_core_userdata( bp_displayed_user_id() );
    118 
    119         // Fetch the full name displayed user
    120         $bp->displayed_user->fullname = bp_core_get_user_displayname( bp_displayed_user_id() );
    121121
    122122        /** Signup ************************************************************/
     
    131131            $bp->profile->id   = 'profile';
    132132        }
     133    }
     134
     135    /**
     136     * Set up canonical stack for this component.
     137     *
     138     * @since BuddyPress (2.1.0)
     139     */
     140    public function setup_canonical_stack() {
     141        $bp = buddypress();
    133142
    134143        /** Default Profile Component *****************************************/
  • trunk/src/bp-xprofile/bp-xprofile-functions.php

    r8534 r8610  
    498498
    499499/**
     500 * Replace the displayed and logged-in userss fullnames with the xprofile name, if required.
     501 *
     502 * The Members component uses the logged-in user's display_name to set the
     503 * value of buddypress()->loggedin_user->fullname. However, in cases where
     504 * profile sync is disabled, display_name may diverge from the xprofile
     505 * fullname field value, and the xprofile field should take precedence.
     506 *
     507 * Runs at bp_setup_globals:100 to ensure that all components have loaded their
     508 * globals before attempting any overrides.
     509 *
     510 * @since BuddyPress (2.0.0)
     511 */
     512function xprofile_override_user_fullnames() {
     513    // If sync is enabled, the two names will match. No need to continue.
     514    if ( ! bp_disable_profile_sync() ) {
     515        return;
     516    }
     517
     518    if ( bp_loggedin_user_id() ) {
     519        buddypress()->loggedin_user->fullname = bp_core_get_user_displayname( bp_loggedin_user_id() );
     520    }
     521
     522    if ( bp_displayed_user_id() ) {
     523        buddypress()->displayed_user->fullname = bp_core_get_user_displayname( bp_displayed_user_id() );
     524    }
     525}
     526add_action( 'bp_setup_globals', 'xprofile_override_user_fullnames', 100 );
     527
     528/**
    500529 * Setup the avatar upload directory for a user.
    501530 *
  • trunk/src/bp-xprofile/bp-xprofile-loader.php

    r8568 r8610  
    219219        }
    220220
    221         // Privacy Settings
    222         if ( bp_is_active( 'settings' ) ) {
    223 
    224             // Get the settings slug
    225             $settings_slug = bp_get_settings_slug();
    226 
    227             // Add the sub-navigation
    228             $sub_nav[] = array(
    229                 'name'            => __( 'Profile', 'buddypress' ),
    230                 'slug'            => 'profile',
    231                 'parent_url'      => trailingslashit( $user_domain . $settings_slug ),
    232                 'parent_slug'     => $settings_slug,
    233                 'screen_function' => 'bp_xprofile_screen_settings',
    234                 'position'        => 30,
    235                 'user_has_access' => bp_core_can_edit_settings()
    236             );
    237         }
     221        // The Settings > Profile nav item can only be set up after
     222        // the Settings component has run its own nav routine
     223        add_action( 'bp_settings_setup_nav', array( $this, 'setup_settings_nav' ) );
    238224
    239225        parent::setup_nav( $main_nav, $sub_nav );
     226    }
     227
     228    /**
     229     * Set up the Settings > Profile nav item.
     230     *
     231     * Loaded in a separate method because the Settings component may not
     232     * be loaded in time for BP_XProfile_Component::setup_nav().
     233     *
     234     * @since BuddyPress (2.1.0)
     235     */
     236    public function setup_settings_nav() {
     237        if ( ! bp_is_active( 'settings' ) ) {
     238            return;
     239        }
     240
     241        // Determine user to use
     242        if ( bp_displayed_user_domain() ) {
     243            $user_domain = bp_displayed_user_domain();
     244        } elseif ( bp_loggedin_user_domain() ) {
     245            $user_domain = bp_loggedin_user_domain();
     246        } else {
     247            return;
     248        }
     249
     250        // Get the settings slug
     251        $settings_slug = bp_get_settings_slug();
     252
     253        bp_core_new_subnav_item( array(
     254            'name'            => __( 'Profile', 'buddypress' ),
     255            'slug'            => 'profile',
     256            'parent_url'      => trailingslashit( $user_domain . $settings_slug ),
     257            'parent_slug'     => $settings_slug,
     258            'screen_function' => 'bp_xprofile_screen_settings',
     259            'position'        => 30,
     260            'user_has_access' => bp_core_can_edit_settings()
     261        ) );
    240262    }
    241263
     
    355377        $bp->profile = new BP_XProfile_Component();
    356378}
    357 add_action( 'bp_setup_components', 'bp_setup_xprofile', 6 );
     379add_action( 'bp_setup_components', 'bp_setup_xprofile', 2 );
Note: See TracChangeset for help on using the changeset viewer.