Make WordPress Core

Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#42563 closed defect (bug) (invalid)

Flushing rewrite rules on plugin deactivation does nothing

Reported by: brainfork Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.8.3
Component: Rewrite Rules Keywords:
Focuses: Cc:


Attempting to flush custom rewrite rules added via plugin on same plugin deactivation as described in the codex/code reference using the following:

register_deactivation_hook( __FILE__, 'flush_rewrite_rules' );

Expected result:
Custom rewrite rules are removed when plugin is deactivated.

Actual result:
Custom rewrite rules persist, can only be cleared by manually triggering a flush

Change History (4)

#1 @mdgl
4 years ago

I suspect you are seeing this behaviour because you also have an action attached to 'init' that creates taxonomies or post types that result in new rewrite rules.

The problem is that the 'init' action is run before the deactivation hook when deactivating the (active) plugin, so your rewrite rules are still updated before being flushed.

I find you need to add something like the following check in your 'init' action before creating new taxonomies or post types:

function xxx_plugin_initialise() {
      if ( is_admin() && strpos($_SERVER['REQUEST_URI'], parse_url(admin_url('plugins.php'), PHP_URL_PATH) . '?action=deactivate&plugin=' . urlencode(plugin_basename(__FILE__))) === 0 )

add_action( 'init', 'xxx_plugin_initialise' );

function xxx_plugin_activate() {

function xxx_plugin_deactivate() {

register_activation_hook( __FILE__, 'xxx_plugin_activate' );
register_deactivation_hook( __FILE__, 'xxx_plugin_deactivate' );

It would be good if the Codex and other advice searchable on the Internet was updated with a description of this issue.

Last edited 4 years ago by mdgl (previous) (diff)

#2 @mdgl
4 years ago

See also #29118.

#3 @ptbello
4 years ago

May I add that the unexpected behaviour directly conflicts with the example shown in the Plugin Handbook's Deactivation Hooks page

#4 @dd32
4 years ago

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

Thanks for mentioning that @ptbello - I've fixed that entry to reference unregister_post_type().

The correct method here is to call unregister_post_type() (and/or unregister_taxonomy()) in the deactivation handler prior to calling flush_rewrite_rules().

For example:

function xxx_plugin_deactivate() {
      unregister_post_type( 'aaaaa' );
      unregister_taxonomy( 'bbbbb' );

I'm closing this as invalid as it's working as expected - if you've called register_post_type() on that pageload, calling flush_rewrite_rules() later in that page will deliberately include the post type rules as it doesn't have any way of detecting that it's happening during deactivation of a plugin that's registered a rule.

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