The rewrite rules for WordPress control which pages and posts to display based on the URL. These are normally updated via the Permalinks setting. When you hit ‘save changes’ all the rules for which URL maps to which page are saved to the database.
When developing plugins and themes it is common to add some custom post types, or custom taxonomies. These both add to the rewrite rules. Rather than constantly clicking to save the permalinks button, we can use the flush_rewrite_rules() function call. It is expensive to do (calculating the rules and writing to the database uses lots of server resources). However, you don’t want to make your end-user have update their permalinks manually every time you release an update. This is why the codex recommends hooking into the activation hook, as this will get fired when the plugin is installed or updated from wordpress.org.
I am often faced with two scenarios that are not covered by the activation hook. Firstly, whilst developing I don’t update my plugin like that – I just change the code. And secondly I mostly write bespoke code for clients not hosted on wordpress.org, and updated using version control, not from inside WordPress admin.
So I need some other trigger. Something that happens automatically, but not all the time. I decided to hook into the theme version changing.
add_action( 'admin_init', 'tcb_version_update_check' );
function tcb_version_update_check(){
$theme = wp_get_theme();
$in_file_version = $theme->Version;
$slug = $theme->stylesheet;
$optionkey = "tcb_vesion_check_{$slug}";
$in_db_version = get_option( $optionkey, 0 );
$version_diff = version_compare( $in_db_version, $in_file_version );
if( !$version_diff ) return;
error_log( "Theme version has changed: $in_db_version -> $in_file_version" );
if( $version_diff == 1 ) :
error_log( "Theme version has gone down. Doesn't compute. Not running update hook." );
return;
endif;
do_action( 'tcb_theme_version_update', $in_file_version, $in_db_version );
update_option( $optionkey, $in_file_version );
}
add_action( 'tcb_theme_version_update', 'tcb_update_flush_rewrite_rules', 10, 2 );
function tcb_update_flush_rewrite_rules( $new_version, $old_version ){
error_log( "Flushing rewrite rules" );
flush_rewrite_rules( false );
}
What I’ve done is hooked into admin_init to check whether the theme version has changed. Added a little sanity check to see if it has gone down!?! And invoked my own hook to let myself expand on the version change trigger.