bp_setup_nav not firing
-
Hi, i’m using BP 1.2.3 with WP 3-alpha.
Got a problem with bp_setup_nav, which is not firing. Very strange.
My plugin structure is set as it was told some days ago :
loader.php
function bp_oqp_init() {
require ONEQUICKPOST_PLUGIN_DIR.’/one-quick-post-bp.php’;
}
add_action( ‘bp_init’, ‘bp_oqp_init’ );
The inclusion of one-quick-post-bp.php is ok.
one-quick-post-bp
function oqp_bp_setup_nav() {
global $bp;
exit;
do_action( ‘oqp_bp_setup_nav’ );
}
add_action( ‘bp_setup_nav’, ‘oqp_bp_setup_nav’ );
So, a simple exit…Which isn’t called.
What’s the matter here ?
Tnx.
-
Bug in BP code. I’ve used this recently:
add_action( 'wp', blah_setup_nav', 2 );
add_action( 'admin_menu', 'blah_setup_nav', 2 );You can get the BP hook bp-setup-nav to fire (to function as expected), if you set the proper priority within the add_action line of bp-core.php. This, of course, is a core hack and is something that needs to be addressed in trunk itself.
So, on line 2027 of bp-core.php, instead of:
add_action( 'plugins-loaded', 'bp-setup-nav' );
You do this:
add_action( 'plugins-loaded', 'bp-setup-nav', 50 );
The issue is that there are other functions that need to be fired before this one but since the priorities on a number of plugins-loaded hooks within BP are not set, it causes an issue that results in the bp-setup-nav hook not to be fired.
I’m currently investigating an issue where a number of my custom do_action hooks do not fire when they should. There are also a few additional BP custom hooks that do not fire when they should as well. It may be that this issue is related. Once I figure out the root cause, I will post in Trac. But for now, if you want to use the custom BP hook bp-setup-nav, you can add a very low priority and it will work.
I’ve found the reverted commit I was looking at: https://trac.buddypress.org/changeset/2794
That may help
The issue is that any BP hook that ties into the plugins_loaded event must be fired in the proper sequence. For some reason, the default of not setting any priorities–which is usually a safe way to approach adding to any action hook–misbehaves in this case.
More than likely the culprit is that a necessary support function (or two) gets fired out of sequence, therefor not providing the required support for the function in question.
So, for the bp-setup-nav function to work, its add_action call must set a priority that does not cause it to be fired before any need support function.
I have not yet created a Trac ticket as a I think more sleuthing is needed to determine the proper sequence, and therefore priorities, for all added actions to the plugins_loaded hook within BP.
Okay, within BP, the plugins_loaded hook is added to nine times. I’m not positive on how WP searches for actions that are added to a given hook once fired, but I assume it is a standard directory search pattern–meaning top down, alphabetical. (Although I have not looked at function do_action to see if my assumption is correct.)
This means that for all activated plugins, once the plugins_loaded event is triggered, WP will first find the added actions to this hook in BuddyPress/bp-activity.php, then /bp-core.php, then finally bp-loader.php. After that, it will begin searching all BP subdirectories beginning with the BuddyPress//bp-activity/ directory.
What does this mean? It means that the single add_action to the plugins_loaded event in /bp-activity.php will be fired first, then the six added actions in /bp-core.php, and finally the single added action in bp-loader.php. This might be the root of the problem.
Since any added actions to the plugins_loaded event will be triggered no matter where they are (assuming a given plugin is activated), it causes an issue if crucial supporting code to a given function is not fired before. There is no reason for the plugins_loaded event to be referenced more than once within BP. The single occurrence of that in function bp_loaded is sufficient. From there all other added actions to the plugins_loaded event should be replaced with bp_init.
Also, no BP-dependent plugin should reference the plugins_loaded event because it will cause a conflict if BuddyPress is deactivated but for some reason that BP-dependent plugin is still active.
Instead, BP-dependent plugins should either reference the bp_init hook, or create their own custom hook.
Refactoring the aforementioned added actions in BP to fire on bp-init instead of plugins_loaded will more than likely not only solve the issue of the bp-set-nav hook not working, but also the bp_setup_root_components hook and the bp_setup_globals hook, and possibly any other hooks that we have not yet discovered are not working.
I also would recommend that priorities be set on all bp-init actions within BP core so as they are fired in the proper sequence and so that any future BP-dependent plugin that comes before “buddypress” alphabetically does not have any of its actions that are added to bp-init fire before others with in BP.
Okay, I’ve just gone through BP core and commented out all references to the plugins_loaded event accept for in bp-loader.php. I then refactored these references to hook into bp-init instead. All hooks worked fine accept bp-setup-nav. I had to set it to no priority or a priority lower than ten to make my navigation items show up in my plugin.
So, I outputted the various do_action arrays and discovered the issue. It is as I thought above–somewhat.
Not only does WordPress search for action calls top-down and alphabetically, it then reorders all action calls for a given hook by priority and if no priority is given, by the order in which it first came across a given action reference. Yes, I know, this is probably confusing most of you. Without seeing the output it may be too complex to visualize.
Here’s why my navigation menu was not showing up:
– All third-party plugins are now supposed to hook into the bp-init event
– The function in my plugin’s loader file that does that is called ‘BPAz_init’. It hooks into bp-init as follows:
add_action( 'bp_init', 'BPAz_init' );
– As you can see, I do not set a load priority on that action
– With the bp_setup_nav event (see line 2025 in bp-core.php) now tied to the bp-init event, instead of plugins_loaded, in my test core hack, and without setting any priority
add_action( 'bp_init', 'bp_setup_nav' );
it gets fired after my BPAz_init function and my plugin’s navigation menu appears
– But, if I set a priority below 10 for the bp_setup_nav event, my navigation fails to load. If I set a priority above 10, it loads. So,
add_action( 'bp_init', 'bp_setup_nav', 9 );
does not work, but,
add_action( 'bp_init', 'bp_setup_nav', 11);
works. My plugin’s navigation appears and functions.
So, the question is why?
Here’s the answer. It has to do with the fact that the function in my loader file that calls the bp-init event is found in a file that comes alphabetically before the file in which the function bp_setup_nav exists.
So, my function BPAz_init lives in a file found in /bp-authz/bp-authz-loader.php but function bp_setup_nav lives in /buddypress/bp-core.php. When the do_action function is processing the array, it sorts them first by priority and second by the order in which they were first loaded. Since my initialization function lives in a subdirectory that is searched before the buddypress subdirectory, my function that is hooked into the bp-init event is discovered before the bp_setup_nav action. This means that if no priorities are set for either function, things just happen to work fine by simple virtue of my plugin directory having a lower alphabetical order and thus higher search priority.
But if I set the priority for the bp_setup_nav action to be higher than ten (as in 9 or lower), then it is fired before my plugin is ever initialized and therefore my navigation menus cannot be rendered. If I set the priority for the bp_setup_nav action lower than ten (as in a number equal to or greater than 11), then my plugin is initialized before the bp_setup_nav event and my navigation menus work.
If I had not serendipitously named my file to something that has a higher alphabetical order than “buddypress”, I may never have discovered this issue. But, the moral of the story is this: the bp_setup_nav event must occur after all BP-dependent plugin’s have been initialized, otherwise their navigation menus will not appear. So, with the bp_setup_nav event tied to plugins_loaded, it fires before all BP-dependent plugin’s have been initialized. But, by setting a low-enough priority, it is possible to push that particular action of plugins_loaded to after all the BP-dependent plugin’s have been initialized. This is, of course, not the best way to do this.
As there may be other BP actions that are loaded too soon, I will need to spend a little time figuring out what this means for all the other action hooks in BuddyPress and BP-dependent plugins. The order in which an action fires can obviously be crucial. Since the firing order is based first on priority set, then on the alphabetical name of the functions that call a given hook, this can result in unexpected behavior.
Confused? Me too!
Jeff, you rule. I feel like I learned a lot about WordPress by reading your posts in this thread!
Thanks, Boone!
Action hook firing sequence is confusing. I think the sequence of actions, and their priorities, need to be carefully looked at in BuddyPress.
By the way, I clarified my above post a little and added some additional thoughts to it while you were more than likely reading an older version. So, please reread my post above.
I just added a patch to Trac that will fix this issue and more like it: https://trac.buddypress.org/ticket/2325
There’s a question for you then Jeff:
What priority would I need to remove the action, like so:
remove_action( 'bp_setup_nav', 'bp_blogs_setup_nav' );
It’s being added with a default of 10, but removing it with a priority of 10, like I should, doesn’t work…
@Jeff thank you a lot for this very useful information I hope the patch you provided get into the next release, the skeleton component is basically useless without this patch.
Thanks again.
I am not a coder, but your posts give a very good insight of how things are working and what is going on under the hood.
I do appreciate the work you have put into this bug and even providing a patch for it !
It is good to see you back here in the Forums !
Thank you !
@jeffsayre
I believe this topic was started before the BP 1.0 release. I have still experiencing problems hooking into bp_setup_nav() and would like to know if altering the core files is the only way to solve the problem. I am currently testing using functions.php and have not been able to get the hook to fire.If I am understanding you correctly, I must do one of two things to correct the problem. 1.) Edit the bp-core and change the priority of bp_setup_nav or 2.) Put the add_action call for my plugin inside a file in a directory that alphabetically comes before “buddypress” ?
The preferred method is to hook your nav setup function to the ‘bp_setup_nav’ hook. If you are unable to do so in your functions.php, it’s probably because functions.php and other theme files are loaded too late. Put your code in wp-content/bp-custom.php (create it if it doesn’t exist) and try that. A standalone plugin should work fine too.
- The topic ‘bp_setup_nav not firing’ is closed to new replies.