Make WordPress Core

Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#31140 closed defect (bug) (worksforme)

WordPress 4.0 upgrade caused 404 on single custom post types

Reported by: marjwyatt's profile MarjWyatt Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.0
Component: Posts, Post Types Keywords:
Focuses: Cc:

Description (last modified by dd32)

I was alerted to an issue with viewing single custom post types. I reverted the site to WordPress v3.9.1 and this was not failing.

Today, I went through the tedious process of troubleshooting the problem. When I upgraded to WordPress 4.0, the code failed.

I used the following steps to research the problem further:
1) I enabled the WordPress default theme, the code worked.
2) Re-enabled my theme and disabled all the plugins to determine whether or not there was a plugin conflict. There was not.

I deduced the problem was in the theme code I'd written.

I started with functions.php and found this bit of code:

// Manually protest wsg-intros because WLM doesn't
add_action( 'pre_get_posts', 'protect_wsg_intros' );
function protect_wsg_intros() {
    if ( ( is_post_type_archive ( 'wsg-intros' ) ) && ( ! is_user_logged_in() ) ) {
        wp_redirect( 'http://localhost/wsg/oops-this-content-is-members-only' );
    }
    elseif ( ( is_singular ( 'wsg-intros' ) ) && ( ! is_user_logged_in() ) ) {
        wp_redirect( 'http://localhost/wsg/oops-this-content-is-members-only' );
    }
}

When I remarked out the elseif statement, the single custom post type worked on my theme with all plugins enabled.

Great! Problem solved! But the solution leaves me with a question. Why would that elseif statement cause a 404 on the single custom post type view with the upgrade to WordPress 4.0? Is this a bug?

Change History (5)

#1 @MarjWyatt
10 years ago

I see that I added the code incorrectly and didn't supply keywords. Sorry.

Here is the code/function:

// Manually protest wsg-intros because WLM doesn't
add_action( 'pre_get_posts', 'protect_wsg_intros' );
function protect_wsg_intros() {
    if ( ( is_post_type_archive ( 'wsg-intros' ) ) && ( ! is_user_logged_in() ) ) {
        wp_redirect( 'http://localhost/wsg/oops-this-content-is-members-only' );
    }
    elseif ( ( is_singular ( 'wsg-intros' ) ) && ( ! is_user_logged_in() ) ) {
        wp_redirect( 'http://localhost/wsg/oops-this-content-is-members-only' );
    }
}

#2 @dd32
10 years ago

  • Description modified (diff)

#3 @dd32
10 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to worksforme
  • Status changed from new to closed

Calling template tags, such as is_singular() before the posts have been queried is rather unreliable - unreliable in that WordPress doesn't yet know what the current post/page is on pre_get_posts so it can't reliably tell you what the status of the request is. Running that code on something such as template_redirect should solve that problem though.

That being said, I can't reproduce this in trunk, the is_singular() does nothing since the post isn't loaded, and doesn't affect the query, the single post is still loaded (logged in, or not).

Additionally, you should check is_main_query() in pre_get_posts callbacks to prevent also running on other queries (such as theme sidebars listing posts, etc). You should also enable WP_DEBUG as that'll have indicated a PHP Notice due to calling is_singular too early.

#4 @MarjWyatt
10 years ago

Thank you for your response. I have one more question.

So nothing changed from 3.9.1 to 4.0 to cause this to fail after upgrading?

#5 @dd32
10 years ago

There is the potential something changed between 3.9 and 4.0, but my inability to duplicate the issue you're seeing on 4.1 doesn't allow me to find out if that's the case.

The code would've been broken on 3.9 - is_singular('wsg-intros') would've always returned false. Although there's the possibility it was working because you had a 2nd posts loop later in the page load (or in the sidebar) where it was referencing the main query still.

Last edited 10 years ago by dd32 (previous) (diff)
Note: See TracTickets for help on using tickets.