Skip to:
Content

Opened 2 weeks ago

Last modified 2 weeks ago

#3161 new defect

main query fires 404_template filter hook if a forum member has no posts

Reported by: petersplugins Owned by:
Milestone: Awaiting Review 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.

Change History (2)

#1 @vinod dalvi
2 weeks ago

  • Cc mozillavvd@… added

#2 @petersplugins
2 weeks ago

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

forums/user/([^/]+)/?$          index.php?bbp_user=$matches[1]

to

forums/user/([^/]+)/?$          index.php?bbp_user=$matches[1]&author_name=$matches[1]

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).

Note: See TracTickets for help on using tickets.