Opened 10 years ago
Last modified 4 years ago
#6448 new defect (bug)
Unconditional set of $wp_rewrite->use_verbose_page_rules = false breaks flush_rewrite_rules()
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | Awaiting Contributions | Priority: | normal |
Severity: | normal | Version: | |
Component: | Core | Keywords: | |
Cc: |
Description
Bp unconditionally sets $wp_rewrite->use_verbose_page_rules = false since this commit: https://buddypress.trac.wordpress.org/changeset/5970.
This breaks rewrite rules written by flush_rewrite_rules() in setups were the post name is used for the permalink structure. This is due to line 1609 of rewrite.php. In these setups, rewrite rules for pages should be written before rewrite rules for posts. Due to Bp setting $wp_rewrite->use_verbose_page_rules to false, it happens to be the other way around. The symptom of this can be a 404 error when accessing a page by it's permalink.
One way to reproduce this bug involves Learndash, but it can potentially occur with any plugin that uses flush_rewrite_rules().
Steps to reproduce:
- Fresh WordPress 4.1.1 install
- Install and activate the plugins BuddyPress 2.2.1 and LearnDash 2.0.6.3 (both newest versions)
- open [wordpress-root]/sample-page/ -> Page is showing correctly
- open [wordpress-root]/activity/ and post something
- reload [wordpress-root]/sample-page/
Change History (11)
#2
@
10 years ago
This issue definitely also happens with other plugins, we just only have a reliable reproduction that includes LearnDash at the moment.
Although the WordPress docs mention that flush_rewrite_rules()
is an expensive operation and should not be called in the
'init'
hook, there is no mention that it *must not* be used in this context. If it is used in the
'init'
hook, and BP breaks this, it is definitely a bug in BuddyPress.
As the problem only appears when flush_rewrite_rules()
is called after BP has set
use_verbose_page_rules
to
false
I don't see how your suggestion to run
flush_rewrite_rules()
even later (with priority 999) should help solve the issue.
#4
@
10 years ago
- Milestone changed from Awaiting Review to Future Release
As the problem only appears when flush_rewrite_rules() is called after BP has set use_verbose_page_rules to false I don't see how your suggestion to run flush_rewrite_rules() even later (with priority 999) should help solve the issue.
Yes, you're right, I was confused. The "solution" would be for BP to do its own maneuvering later.
This issue definitely also happens with other plugins
If you come up with examples, please share them. I don't have access to LearnShare, and I'll need a reproducible example to think more clearly about a solution.
In any case, I maintain that it's unwise, bordering on a bug, for plugins to flush rewrite rules at 'init'. It's not just because of the overhead. It's because plugins often register post types, taxonomies, and other rewrite-related content at 'init', and flushing the rewrite rules on the same hook can cause all sorts of race conditions like the one described in this ticket.
I'll put this ticket in Future Release in the hopes that you or someone else can provide a freely available plugin that demonstrates the problem reliably.
#6
@
9 years ago
Hi all,
We're seeing this on our current site with BuddyPress 2.6.1.1, BuddyPress for Learndash 1.1.0 and Learndash 2.2.1.2 currently. It affects all our subpages on the site causing 404 errors when it happens.
We can fix this temporarily by visiting the permalinks page in the wp-admin console, but this isn't ideal and it reoccurs multiple times a day for us causing some pain for our users.
Could you please advise to a patch?
Have you spoken with Learndash about this issue?
Many thanks,
Jon.
#7
@
9 years ago
I don't think so, no. As stated previously, we never had access to it as a commercial plugin (and no interest in spending our own money on it) so we could never see exactly what it was doing.
#8
@
9 years ago
We solved the issue with the following workaround:
add_action('delete_option_rewrite_rules', function($option){
global $wp_rewrite;
$wp_rewrite->use_verbose_page_rules = true;
}, 10);
#9
@
4 years ago
For what it's worth, we've come across the same problem now. We're using WordPress 5.5+ with BuddyPress and Events Calendar plugins.
Using @chherbst's solution doesn't work in our case as we're using Object Cache which stores rewrite_rules and wp_options values to Object Cache.
We're still figuring out an ideal solution for this.
#10
@
4 years ago
Our website (https://transfamilies.org) also hit this bug. Considering the bug is well-understood, and the symptom is sporadic 404s, and the symptom is very hard to debug if you don't already know about this bug, please consider fixing this.
#11
@
4 years ago
@jasonful Along with the fix mentioned by @chherbst in #8, we also had to set autoload
to no
on wp_options
table for the row which was saving rewrite_rules
. This was because wp_options
get storied in Object Cache and sometimes the value stored in cache was incorrectly generated due to this bug in BuddyPress.
To do so, find the appropriate row by using: SELECT * FROM wp_options WHERE option_name = 'rewrite_rules' ORDER BY option_id LIMIT 300 OFFSET 0;
and changing the value of autoload
column to no
.
Thanks for the report. It appears that LearnDash is not available for free, so I'm afraid I don't have access to test it directly. Can you describe in a bit more detail the way in which LearnDash is calling
flush_rewrite_rules()
? It should *not* be doing it on every pageload, and if it is, then it's a bug there and not in BP.As for our own
use_verbose_page_rules
override: this should only take effect once BP has determined that you're looking at a BP page. Again, my guess is that BP is overridinguse_verbose_page_rules
(at'bp_init'
, which is fired at'init'
), and then LearnDash is callingflush_rewrite_rules()
afterward, on every pageload, so that viewing a page like /activity/ resets your permalink settings.If you can provide a bit more data or corroboration of my hypothesis, maybe I can help suggest an improvement to LearnDash that will work around this problem - if nothing else, running
flush_rewrite_rules()
later (say, 'init' with priority 999) should do it.