diff --git a/wp-includes/cache.php b/wp-includes/cache.php index 09ca7cda7..8bad63ad6 100644 --- a/wp-includes/cache.php +++ b/wp-includes/cache.php @@ -191,21 +191,8 @@ class WP_Object_Cache { foreach ($dogs as $catt) $this->cache['category'][$catt->cat_ID] = $catt; } - } else - if ('options' == $group) { - $wpdb->hide_errors(); - if (!$options = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options WHERE autoload = 'yes'")) { - $options = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options"); - } - $wpdb->show_errors(); + } - if ( ! $options ) - return; - - foreach ($options as $option) { - $this->cache['options'][$option->option_name] = $option->option_value; - } - } } function make_group_dir($group, $perms) { diff --git a/wp-includes/functions.php b/wp-includes/functions.php index f030bb17e..c96ebd56b 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -208,20 +208,33 @@ function get_option($setting) { if ( $pre ) return $pre; - $value = wp_cache_get($setting, 'options'); + // prevent non-existent options from triggering multiple queries + $notoptions = wp_cache_get('notoptions', 'options'); + if ( isset($notoptions[$setting]) ) + return false; - if ( false === $value ) { - if ( defined('WP_INSTALLING') ) - $wpdb->hide_errors(); - $row = $wpdb->get_row("SELECT option_value FROM $wpdb->options WHERE option_name = '$setting' LIMIT 1"); - if ( defined('WP_INSTALLING') ) - $wpdb->show_errors(); + $alloptions = wp_load_alloptions(); - if( is_object( $row) ) { // Has to be get_row instead of get_var because of funkiness with 0, false, null values - $value = $row->option_value; - wp_cache_set($setting, $value, 'options'); - } else { - return false; + if ( isset($alloptions[$setting]) ) { + $value = $alloptions[$setting]; + } else { + $value = wp_cache_get($setting, 'options'); + + if ( false === $value ) { + if ( defined('WP_INSTALLING') ) + $wpdb->hide_errors(); + $row = $wpdb->get_row("SELECT option_value FROM $wpdb->options WHERE option_name = '$setting' LIMIT 1"); + if ( defined('WP_INSTALLING') ) + $wpdb->show_errors(); + + if( is_object( $row) ) { // Has to be get_row instead of get_var because of funkiness with 0, false, null values + $value = $row->option_value; + wp_cache_set($setting, $value, 'options'); + } else { // option does not exist, so we must cache its non-existence + $notoptions[$setting] = true; + wp_cache_set('notoptions', $notoptions, 'options'); + return false; + } } } @@ -235,6 +248,12 @@ function get_option($setting) { return apply_filters( 'option_' . $setting, maybe_unserialize($value) ); } +function wp_protect_special_option($option) { + $protected = array('alloptions', 'notoptions'); + if ( in_array($option, $protected) ) + die(sprintf(__('%s is a protected WP option and may not be modified'), wp_specialchars($option))); +} + function form_option($option) { echo attribute_escape(get_option($option)); } @@ -262,9 +281,29 @@ function get_alloptions() { return apply_filters('all_options', $all_options); } +function wp_load_alloptions() { + global $wpdb; + + $alloptions = wp_cache_get('alloptions', 'options'); + + if ( !$alloptions ) { + $wpdb->hide_errors(); + if ( !$alloptions_db = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options WHERE autoload = 'yes'") ) + $alloptions_db = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options"); + $wpdb->show_errors(); + $alloptions = array(); + foreach ( (array) $alloptions_db as $o ) + $alloptions[$o->option_name] = $o->option_value; + wp_cache_set('alloptions', $alloptions, 'options'); + } + return $alloptions; +} + function update_option($option_name, $newvalue) { global $wpdb; + wp_protect_special_option($option_name); + if ( is_string($newvalue) ) $newvalue = trim($newvalue); @@ -279,10 +318,22 @@ function update_option($option_name, $newvalue) { return true; } + $notoptions = wp_cache_get('notoptions', 'options'); + if ( isset($notoptions[$option_name]) ) { + unset($notoptions[$option_name]); + wp_cache_set('notoptions', $notoptions, 'options'); + } + $_newvalue = $newvalue; $newvalue = maybe_serialize($newvalue); - wp_cache_set($option_name, $newvalue, 'options'); + $alloptions = wp_load_alloptions(); + if ( isset($alloptions[$option_name]) ) { + $alloptions[$options_name] = $newvalue; + wp_cache_set('alloptions', $alloptions, 'options'); + } else { + wp_cache_set($option_name, $newvalue, 'options'); + } $newvalue = $wpdb->escape($newvalue); $option_name = $wpdb->escape($option_name); @@ -298,13 +349,26 @@ function update_option($option_name, $newvalue) { function add_option($name, $value = '', $description = '', $autoload = 'yes') { global $wpdb; - // Make sure the option doesn't already exist - if ( false !== get_option($name) ) - return; + wp_protect_special_option($name); + + // Make sure the option doesn't already exist we can check the cache before we ask for a db query + $notoptions = wp_cache_get('notoptions', 'options'); + if ( isset($notoptions[$name]) ) { + unset($notoptions[$name]); + wp_cache_set('notoptions', $notoptions, 'options'); + } elseif ( false !== get_option($name) ) { + return; + } $value = maybe_serialize($value); - wp_cache_set($name, $value, 'options'); + if ( 'yes' == $autoload ) { + $alloptions = wp_load_alloptions(); + $alloptions[$name] = $value; + wp_cache_set('alloptions', $alloptions, 'options'); + } else { + wp_cache_set($name, $value, 'options'); + } $name = $wpdb->escape($name); $value = $wpdb->escape($value); @@ -316,11 +380,22 @@ function add_option($name, $value = '', $description = '', $autoload = 'yes') { function delete_option($name) { global $wpdb; + + wp_protect_special_option($name); + // Get the ID, if no ID then return - $option_id = $wpdb->get_var("SELECT option_id FROM $wpdb->options WHERE option_name = '$name'"); - if ( !$option_id ) return false; + $option = $wpdb->get_row("SELECT option_id, autoload FROM $wpdb->options WHERE option_name = '$name'"); + if ( !$option->option_id ) return false; $wpdb->query("DELETE FROM $wpdb->options WHERE option_name = '$name'"); - wp_cache_delete($name, 'options'); + if ( 'yes' == $option->autoload ) { + $alloptions = wp_load_alloptions(); + if ( isset($alloptions[$name]) ) { + unset($alloptions[$name]); + wp_cache_set('alloptions', $alloptions, 'options'); + } + } else { + wp_cache_delete($name, 'options'); + } return true; } diff --git a/wp-includes/version.php b/wp-includes/version.php index 1f55e5174..3bf2ede06 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -3,6 +3,6 @@ // This holds the version number in a separate file so we can bump it without cluttering the SVN $wp_version = '2.2-bleeding'; -$wp_db_version = 4772; +$wp_db_version = 4773; ?>