Opened 8 years ago
Last modified 19 months ago
#3161 new defect (bug)
main query fires 404_template filter hook if a forum member has no posts
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 2.7 | Priority: | normal |
| Severity: | normal | Version: | |
| Component: | General | Keywords: | |
| Cc: | mozillavvd@… |
Description
The WP main query fires the 404_template filter hook if the member has not created any posts.
How to reproduce this issue:
Add the following code e.g. to functions.php of the Theme:
add_filter( '404_template', function() {
global $wp_query;
print_r( $wp_query );
die();
} );
Create a new forum user and access his profile page on front end. The 404_template filter hook fires.
Problem Description:
bbPress adds several rewrite rules for bbp_user. The bbp_parse_query() function sets posts_query->is_404 to false but this is before the query is executed.
Adding bbp_user to the query results in a main query like the following:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
WHERE 1 = 1
AND ( wp_posts.post_author = 2 )
AND wp_posts.post_type = 'post'
AND ( wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'closed'
OR wp_posts.post_status = 'private'
OR wp_posts.post_status = 'hidden'
)
ORDER BY wp_posts.post_date DESC LIMIT 0, 10
If the user with the ID 2 has no posts created the result of this query is empty. After executing the query $wp_query->is_404 is true. This causes wp-includes/template-loader.php to call the WP core function get_404_template() which calls get_query_template('404') - defined in wp-includes/template.php. This fires the 404_template hook.
This has no effect for the template loader because bbPress adds the bbp_template_include_theme_supports() function to the template_include filter hook. If $wp_query->bbp_is_single_user is set to true the single user template is loaded, before $wp_query->is_404 ist tested.
But the 404_template filter hook fires, which is not correct because there is nor 404 error! Every plugin that uses this filter - like mine - would have to check if $wp_query->bbp_is_single_user is set to true to avoid this. But this only bypasses the problem and does not really solve it.
Solution:
$wp_query->is_404 has to be reset to false in case of $wp_query->bbp_is_single_user is true straight after the query is executed before the template loader runs.
I've found a solution that works without the need to reset is_404 after running the query.
Changing the rewrite rule for a single member from
to
causes the WP_Query class to set is_author to true.
In that case no 404 is set, see wp-includes/class-wp.php
// Don't 404 for authors without posts as long as they matched an author on this site. $author = get_query_var( 'author' ); if ( is_author() && is_numeric( $author ) && $author > 0 && is_user_member_of_blog( $author ) ) { status_header( 200 ); return; }Alternatively it should be possible to set is_author to true in function bbp_parse_query() without changing the rewrite rule (I didn't test this).