﻿id,summary,reporter,owner,description,type,status,priority,milestone,component,version,severity,resolution,keywords,cc
21824,Custom Post Type Permalink Rules Are Not Updated Correctly When Saving Changes,MarcusPope,,"When changing permalink structures using Common Settings or Custom Structure, clicking Save Changes will only update core system rewrite rules.  Custom Post Type rewrite rules are re-used from the previous setting.  If you click save changes twice the correct rewrite rules are updated and used.

If you only save once, canonical.php will step in and issue a 301 redirect to the appropriate post.  But if you save twice it doesn't have to do any work at all.  This is actually causing an infinite 301 redirect with one of my plugins.  I have a fix to prevent the recursion, but it still means it cannot find my custom post type content until I update the permalinks settings again. This behavior occurs whether you register post types in ""init"" or in a theme's functions.php or in a plugin.

I've seen multiple core devs and users say off-handedly that you should save the page once or twice as seen in these links:

http://wordpress.org/support/topic/permalinks-go-404-on-custom-post-types?replies=7#post-2301522

http://wordpress.org/support/topic/plugin-custom-post-type-permalinks-all-custom-post-type-pages-and-categories-result-in-404s?replies=12#post-2841550

http://wordpress.stackexchange.com/a/40591/10127

http://wordpress.org/support/topic/custom-post-type-permalink-rewrite?replies=10

The reason this behavior occurs is because `flush_rewrite_rules()` doesn't actually flush custom post type rewrite rules stored in `WP_Rewrite::$extra_permastructs`.  `WP_Rewrite::init()` will only reset internal core posts/pages/category/etc structures.  And `$extra_permastructs` rules are created on `register_post_type()` which occurs before the form post to options-permalink.php has a chance to update the `structure` and `$front` values.

So order of execution is:

1. Change Permalink Structure and Page Post to options-permalink.php
1. Read structure setting from database
1. Load system permalinks
1. Load plugins and register their permalinks
1. options-permalink updates the structure setting value in the database
1. Calls flush system permalinks
1. Loads new system permalinks and merges with old CPT permalinks because it never calls `register_post_type()`

On a second save, step 4 will have the correct permalinks structure, so when they are merged with the already correct system permalinks all is well with the universe again.

Ideally `flush_rewrite_rules()` actually flushes all rewrite rules. But I'm not sure if calling `register_post_type()` twice in one page load is safe.  It could do an ajax post for the first change, and then a full form post for custom post types - but that seems a little hackey.  I don't have a good solution yet so I can't provide a patch.

To reproduce and debug this behavior, setup at least one CPT and dump the variable `$this->rules` at the end of the function `rewrite_rules()` in rewrite.php.  Go into permalinks settings page, change your structure to Numeric, click save.  The log file will list all of the rules but the CPT will not have ""archives"" in front of their URL (unless Numeric was already selected.)  Now select a different structure - ""Post name"", click save, and the CPT urls will have ""archives"" in front of the url, but the others will not.  Click save again, and CPT's will be fixed.

Thanks,
Marcus",defect (bug),closed,normal,,Rewrite Rules,,normal,duplicate,,
