Opened 11 years ago
Last modified 5 years ago
#27276 new defect (bug)
wp_rewrite_rule does not update option when it's empty
Reported by: | mainpart | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 3.7 |
Component: | Rewrite Rules | Keywords: | needs-patch |
Focuses: | Cc: |
Description
This bug report about possible problems with situation when deleted options still present in cache. I'm using memcache so my cache is transistient.
i've been adding rewrite_rule
function duke_add_endpoints() { add_rewrite_rule('...','...'); global $wp_rewrite; $wp_rewrite->flush_rules(); } add_action( 'init', 'duke_add_endpoints');
and discovered that i can't get it work because of it completely absence in further $wp_rewrite references.
Intrigued by that fact (especialy with hard flushing) i've been lead to parse_requestof class-wp and due to it's
$rewrite = $wp_rewrite->wp_rewrite_rules();
i guided to wp_rewrite_rules method of wp-includes/rewrite.php where discovered that rewrite_rules option is loaded from wp_options but if it's not there - it loaded from cache (bacause of get_option behaviour).
$alloptions = wp_load_alloptions(); if ( isset( $alloptions[$option] ) ) { $value = $alloptions[$option]; } else { $value = wp_cache_get( $option, 'options' ); if ( false === $value ) { $row = $wpdb->get_row(....
Wondering why it was not overriden by flush_rules both in wp_options and in cache i've dig into flush_rules and discovered that it operates the same method
function flush_rules($hard = true) { delete_option('rewrite_rules'); $this->wp_rewrite_rules(); .......
but wait... IF THE REWRITE_RULES IS NOT IN THE WP_OPTION then it still taken from cache with previous value.
function wp_rewrite_rules() { $this->rules = get_option('rewrite_rules'); ///at this point the value already deleted from table but still remains in cache so get_option returns OLD value till it remain in cache for indefinite time if ( empty($this->rules) ) { $this->matches = 'matches'; $this->rewrite_rules(); update_option('rewrite_rules', $this->rules); } return $this->rules; }
so if your rewrite rules not in table but in cache - they probably stuck there forever till cache gets cleared. i guess it has something to infere with delete_option and situation when cache is not cleared. but i guess it's next bug to catch.
delete_option()
specifically clears the deleted value from cache: tags/3.8.1/src/wp-includes/option.php#L370. Looks like it failed here. Might be related to #25773.