0

I'm providing a checkbox to my plugin Settings API to enable/disable certain Rewrite rules to my plugins CPT. I want to flush the rewrite rules when the specific setting is changed. So I did the following:

function my_flush_rules_while_rewrite_changed( $old_values, $new_values ) {
    if( $old_values['rewrite_url'] != $new_values['rewrite_url'] ) {
        flush_rewrite_rules();
        //echo "Rewrite rules flushed";
        //exit();
    }
}

add_action( 'update_option_my_settings', 'my_flush_rules_while_rewrite_changed', 10, 2 );

It's not flushing the rewrite rules. Though I tested without the conditions, and tested that the echod text is displayed if used with exit(). So, I'm sure, the function is being called, but sad part is, it's NOT WORKING.

Flush the rewrite rules

I thought it's the Rewrite Rules plugin's problem, but the actual rewriting isn't working without saving Permalink changes. So it's actually a problem with my code - it's not working.

But why?

5
  • are you adding the new rules before flushing? It's not just emptying the rules, its rebuilding them from whatever is currently registered.
    – Milo
    Commented May 6, 2017 at 14:58
  • Yes, I first tried with false, then tried the hard flush. FYI, I added filter to post_type_link and rewrite_rules_array like this QA. Commented May 6, 2017 at 15:05
  • It's more likely that the issue is not that the flush_rewrite_rules is not flushing rules, but that your new rules aren't present when the flush occurs. I can't verify that without seeing all of your code though. A hard flush will write to .htaccess, so a simple test to see if it's actually flushing is to empty that file and see if it's rebuilt after the flush.
    – Milo
    Commented May 6, 2017 at 15:19
  • FYI, here is my last code: github.com/nanodesigns/nanosupport/commit/… Commented May 6, 2017 at 15:21
  • Are you certain the filter is applied when the rules are flushed? You add the filter in an if conditional, have you verified it passes that test in this specific case? This issue is almost always a result of the order in which you are doing things.
    – Milo
    Commented May 6, 2017 at 15:32

1 Answer 1

1

flush_rewrite_rules is firing, but it's too late; the previous rewrite setting has already determined your register_post_type args at the start of the request, so you're just flushing the "old" rules.

You could try re-registering the post type just before flushing, but I'm not sure of the wider implications or even if this will work.

If it were me, I'd use the logic you've already got to stash a flag in the settings, then handle on the subsequent request:

function my_flush_rules_while_rewrite_changed( $new_values, $old_values ) {
    if( empty( $new_values['rewrite_url'] ) && ! empty( $old_values['rewrite_url'] ) || ! empty( $new_values['rewrite_url'] ) && empty( $old_values['rewrite_url'] ) ) {
        $new_values['flush_rewrite_rules'] = true;
    }

    return $new_values;
}

add_filter( 'pre_update_option_my_custom_settings', 'my_flush_rules_while_rewrite_changed', 11, 2 );

And then as an example:

add_action( 'init', function () {
    $settings = get_option( 'my_custom_settings' );
    if ( ! empty( $settings['flush_rewrite_rules'] ) ) {
        flush_rewrite_rules();
        unset( $settings['flush_rewrite_rules'] );
        update_option( 'my_custom_settings', $settings );
    }
});
2
  • It's the answer. But isn't it be a resource-heavy workaround than asking the user to do flush 'em manually? I'm simply concerned about the hooking into init. Commented May 8, 2017 at 18:38
  • 1
    I don't think the expense is notable. The rules are only flushed on next request, settings are autoloaded. You could use admin_init instead, that should be fine Commented May 8, 2017 at 23:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.