Opened 12 years ago
Last modified 7 years ago
#27276 new defect (bug)
wp_rewrite_rule does not update option when it's empty
| Reported by: |
|
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.