0

I found a major bug inside our custom plugin, we simply adding the new rules and flushing the existing rewrite_rules on every page load("add_action('wp_loaded', 'flush_rules')"), which seems not a good practice. I am curious to know if there is any way to check the different between the existing rewrite_rules(already stored in DB ) and the latest rewrite_rules before calling to flush_rules() method? Most of the time, the existing and the latest rewrite_rules are the same.

Thanks,

2 Answers 2

1

Here's the trick I've been using:

  • Use an array to store the rewrites
  • Hash the array
  • Store the hashed array as an option
  • Check to see if the stored option matches the curret rewrite hash; if not, update the rewrites

Greatly simplified code snippet (this is meant as a starting point, not a finished product):

add_action( 'init', 'wpse_393260_rewrites' );
function wpse_393260_rewrites() {
    // Array of rewrites.
    $my_rewrites = array(
        'foo/([a-z0-9-]+)[/]?$' => 'index.php?foo=$matches[1]',
        'bar/([a-z0-9-]+)[/]?$' => 'index.php?bar=$matches[1]',
        // etc.
    );
    // Implements the rewrite rules.
    foreach ( $my_rewrites as $regex => $query ) {
        add_rewrite_rule( $regex, $query, 'top' );
    }
    // Hashes the $my_rewrites array.
    $hashed_rewrites = md5( serialize( $my_rewrites ) );
    // Gets the currently-active rewrites from the option.
    $my_current_rewrites = get_option( 'my_rewrites_option' );
    // If anything's changed, flush the rewrites and update the option.
    if ( $my_current_rewrites !== $hashed_rewrites ) {
        flush_rewrite_rules();
        update_option( 'my_rewrites_option', $hashed_rewrites );
    }
}
1
  • 1
    Thanks, it works as I was expecting.. :) Commented Aug 16, 2021 at 17:11
0

You could add a flush rewrite only upon submitting a form:

if ( (isset($_POST['update_myform'])) && check_admin_referer('check_form', 'check_form') ) { 

    flush_rewrite_rules(false);
}

'false' ensures that rules are only updated, not totally rewritten.

You can even further add conditional rules inside the if, such as making sure that a specific field has been submitted (and therefore narrowing down the number of times flush is triggered).

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.