Skip to:

Re: How to overwrite a function?

Jeff Sayre



Your basic idea is correct. The issue is the order in which each action function hooked to the bp_setup_nav action event is being triggered. Let’s look at the code you have in bp-custom.php.

function my_groups_setup_nav() {
[the whole function code]
remove_action('bp_setup_nav', 'groups_setup_nav');
add_action( 'bp_setup_nav', 'my_groups_setup_nav' );

This fails because your custom code in bp-custom.php is executed before the code in bp-groups.php is executed. So, you are calling to remove an action that has not yet be registered by WordPress.

I’m almost finished with an article about the intricacies of WordPress’ action and filter functions, but here is a brief explanation to try to shed some light on the issue.

Each action and filter event when triggered by a do_action or apply_filters call sends execution to the appropriate do_action or apply_filters function in /wp-includes/plugin.php. These functions do several things, one of which is querying a very large array that contains all of the added filter functions and action functions. This array gets populated by the actions of the add_filter and add_action calls.

To avoid getting too long winded, as each file gets loaded, any and all add_action and add_filter calls that are directly executable at the time, get triggered which builds this big array. This array is then used by the do_action and apply_filters functions to determine the sequence in which each added action of filter will be executed.

You can read my article when it is ready for a much longer but clearer explanation.

With that briefly described, the piece of information that applies to your situation is that when the action event for bp_setup_nav is triggered, via the do_action( ‘bp_setup_nav’ ) call on line 2025 in bp-core.php, the do_action function starts processing each action function that was “added” to it in the order in which it was added (with an important exception). This means that for your custom function my_groups_setup_nav to work, it must remove the action function in the array discussed above so that when the bp_setup_nav action event is triggered it uses your action function instead of the one added by the add_action(‘bp_setup_nav’, ‘groups_setup_nav’) call.

So, what you need to do is trigger your remove and add action calls in the proper sequence–after the action function that creates the groups navigation menus has been added to the filter array but before the bp_setup_nav action event is triggered. I realize this may be hard to understand.

This is what you need to do instead:

<?php function my_groups_setup_nav() {

/* Remove the added action from the array of functions that get run
* when the action event for bp_setup_nav is triggered
remove_action('bp_setup_nav', 'groups_setup_nav');

// Then replace the removed function with your custom content
[the whole function code]

add_action( 'plugins_loaded', 'my_groups_setup_nav' );

A final bit of clarification. This is what happens in your current custom function:

1. As soon as BuddyPress is initialized, it looks to see if bp-custom.php exists. If it does, it loads it.

2. This will cause your remove_action call to be fired.

3. But the corresponding action has not yet been added to the very large filter array since bp-groups.php has not yet been loaded.

4. So, nothing happens as there is nothing to remove.

5. bp-groups.php eventually gets loaded and at that point the add_action(‘bp_setup_nav’, ‘groups_setup_nav’) call is fired, resulting in the action function that you were trying to remove getting added to the filter array but after the fact.

6. Eventually the bp_setup_nav action event is triggered.

7. When that happens, the first function hooked to it (added to it) is your custom function. It now gets triggered.

8. All other action functions hooked to the bp_setup_nav action event get triggered one by one including the groups_setup_nav function–the one you had tried to remove in step 2.

9. You have a mess with two duplicate functions doing the same thing.

Skip to toolbar