Flushing Rewrite Rules on All Sites in a Multisite Network

TL;DR: View the code on Meta Trac.

Every once in awhile I’ll run into a situation where something will break permalinks on all the sites in a WordPress Multisite network, like a plugin network-activation gone wrong.

On a single site, it’s easy enough to fix by manually visiting Settings > Permalinks, which will flush and rebuild the rewrite rules, but if you’ve got more than a couple dozen sites in a network, then that’s no longer practical. You need a way to do it automatically for all of the sites.

The Typical Approach

Most of the attempts I’ve seen to do that will work similar to this:

/*
 * This is an example of a FLAWED way to do it, don't use it.
 * Use the better way described at the end of the post instead.
 */
function flush_rewrite_rules_everywhere() {
    global $wp_rewrite;
    $sites = wp_get_sites( array( 'limit' => false ) );

    foreach ( $sites as $site_id ) {
        switch_to_blog( $site_id );
        $wp_rewrite->init();

        flush_rewrite_rules();

        restore_current_blog();
    }
    $wp_rewrite->init();
}

That works for the basic rules, but it breaks down when you’ve created custom post types, because switch_to_blog() doesn’t reinitialize everything in the context of the new site; there are a few things that aren’t switched at all, and plugins are one of those things.

So, if the plugins that create the custom post types aren’t running on the site that initially calls the function, then they won’t be loaded when flush_rewrite_rules() gets called, and the rewrite rules for the CPTs will never be generated.

A Better Way

What’s really needed is a way to call flush_rewrite_rules() within the context of each fully-loaded site. So to do that, I wrote a WP-CLI command that will issue an HTTP request to each site and call the function. You can view the code on Meta trac.

One thought on “Flushing Rewrite Rules on All Sites in a Multisite Network

Leave a Reply

Your email address will not be published. Required fields are marked *