Best way to flush_rewrite_rules for custom post type, in a mu-plugins plugin?

I am writing a plugin that instantiates a custom post type (among other things). It is a multisite plugin and lives in the directory mu-plugins.

What is the best practice for handling flush_rewrite_rules() in this situation? For a ‘normal’ plugin you’d do this in an activation hook — which is not going to be possible for a must-use plugin since those hooks are not available.

Since this is supposed to be a “one time” event after registering the custom post type, would it make sense to do something like this in my class that registers the CPT:

private function check_flush_my_CPT() {
    global $wp_rewrite;
    if ( !get_option('my_plugin_firstrun') ) {
        $wp_rewrite->init();
        $wp_rewrite->flush_rules(true);
        update_option('my_plugin_firstrun', 'yes');
    }
}

public function register_my_CPT() {
   // do all the CPT setup steps for the $args array...  

   register_post_type('my_CPT', $args);
   $this->check_flush_my_CPT();
}

add_action( 'init', array(&$this, 'register_my_CPT' ) );

So, the CPT registration happens on every ‘init’ action — but if I have this right, the rewrite rules flush only happens once. Ever.

Am I on the right track?

(edit): I just tried it; my CPT is giving a 404 not found error, so the rewrites rules are not working 🙁

(edit #2): I did try the solution for accessing the global variable as shown in this question: How to reliably flush rewrite rules on multisite? – I will update my code example above to show this. Unfortunately I am still getting 404 error when trying to load a CPT. I see that the rewrite rules are being stored in the database, it just seems like they are not being used. I’m lost.

4 s
4

The flush_rewrite_rules function is reliable in some contexts like a theme or a plugin based on hooks but I’m not sure if it works for a mu-plugin

My statement is based on the fact that WordPress is initialized in this way:

  • call the wp-settings.php file
  • call the do_action( 'muplugins_loaded' ); hook, here your plugin is initialized
  • call $GLOBALS['wp_rewrite'] = new WP_Rewrite(); here the method flush_rules is initialized and available from now on
  • do_action( 'setup_theme' ); is called and I bet all my money that on this hook the flush_rewrite_rules will work

Solution?

Personally, I find reliable the deletion of the rewrite_rules option.

delete_option('rewrite_rules');

or

update_option('rewrite_rules', '' );

Whenever WordPress will lack the rewrite_rules it will build them back, this is also what the flush_rules method does.

There are points in WordPress execution flow where functions like this aren’t available. even in the core of WordPress I found this statement

// Rewrite rules can't be flushed during switch to blog.
delete_option( 'rewrite_rules' );

The only problem would be the performance, don’t do this on every request because it is a hard process to build them back.
As I can see you want to flush them only at the first call and this is a good thing.

P.S: I’m not such a self-promo fan but I’ve also written an article about this long time ago and I think it still stands up for this

Leave a Comment