Opened 11 years ago
Last modified 6 years ago
#25798 new defect (bug)
Certain single CPT items result in 404 since 3.7
Reported by: | boonebgorges | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 3.7 |
Component: | Posts, Post Types | Keywords: | needs-patch needs-unit-tests |
Focuses: | Cc: |
Description
Related: #25749
The changes in [25182] to the query_var mapping of hierarchical post types have broken single permalinks in some cases, when Permalink setting is set to "Post name". To reproduce:
- Register a post type as follows:
register_post_type( 'bbg_test', array( // ... 'hierarchical' => true, 'public' => true, 'rewrite' => true, // any value other than false 'query_var' => false, // ... ) );
- Set permalink settings to "Post name" (and flush)
- Create a new post of the type above, and attempt to visit at the url
http://example.com/bbg_test/foo
(or whatever). Result: 404.
- Change to any other permalink setting. Result: page loads as expected.
Cause: When the CPT is registered with 'rewrite'
other than false
, it passes the test at http://core.trac.wordpress.org/browser/tags/3.7/src/wp-includes/post.php#L1275. When it's hierarchical, it passes the test at line 1293. When, because 'query_var'
is set to false
, the rewrite tag set on line 1294 is of the form 'post_type=bbg_test&pagename=foo' (instead of 'bbg_test=foo'). Then, when an item is loaded, during WP::parse_request()
, it passes the preg_match()
test here http://core.trac.wordpress.org/browser/tags/3.7/src/wp-includes/class-wp.php#L198, but a page (ie, an item with post_type
'page') is not found by get_page_by_path()
, and as a result the correct rewrite rule is not matched.
As noted, this is a regression in 3.7 [25182], before which preg_match( '/pagename=\$matches...
wouldn't have matched.
Obviously it's an edge case that (a) a post type is hierarchical AND has query_var set to false, and also (b) permalinks are set to "Post name", but it is a change in behavior that broke one of my plugins, and has been a bit of a bear to track down :) I'm going to set query_var
to true for my purposes (no harm done on my end) but that may not be possible for others.
Change History (4)
#2
@
11 years ago
After a quick test, it looks like passing the post type to get_page_by_path()
here fixes the issue.
I just hard coded the post type to test it quickly and it resolved the 404 error.
if ( ! get_page_by_path( $matches[ $varmatch[1] ], OBJECT, 'bbg_test' ) )
I've replicated the issue.