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
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 methodflush_rules
is initialized and available from now on do_action( 'setup_theme' );
is called and I bet all my money that on this hook theflush_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