wp_set_option_autoload_values

The timeline below displays how wordpress function wp_set_option_autoload_values has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.4

/**
 * Sets the autoload values for multiple options in the database.
 *
 * Autoloading too many options can lead to performance problems, especially if the options are not frequently used.
 * This function allows modifying the autoload value for multiple options without changing the actual option value.
 * This is for example recommended for plugin activation and deactivation hooks, to ensure any options exclusively used
 * by the plugin which are generally autoloaded can be set to not autoload when the plugin is inactive.
 *
 * @since 6.4.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param array $options Associative array of option names and their autoload values to set. The option names are
 *                       expected to not be SQL-escaped. The autoload values accept 'yes'|true to enable or 'no'|false
 *                       to disable.
 * @return array Associative array of all provided $options as keys and boolean values for whether their autoload value
 *               was updated.
 */
function wp_set_option_autoload_values(array $options)
{
    global $wpdb;
    if (!$options) {
        return array();
    }
    $grouped_options = array('yes' => array(), 'no' => array());
    $results = array();
    foreach ($options as $option => $autoload) {
        wp_protect_special_option($option);
        // Ensure only valid options can be passed.
        if ('no' === $autoload || false === $autoload) {
            // Sanitize autoload value and categorize accordingly.
            $grouped_options['no'][] = $option;
        } else {
            $grouped_options['yes'][] = $option;
        }
        $results[$option] = false;
        // Initialize result value.
    }
    $where = array();
    $where_args = array();
    foreach ($grouped_options as $autoload => $options) {
        if (!$options) {
            continue;
        }
        $placeholders = implode(',', array_fill(0, count($options), '%s'));
        $where[] = "autoload != '%s' AND option_name IN ({$placeholders})";
        $where_args[] = $autoload;
        foreach ($options as $option) {
            $where_args[] = $option;
        }
    }
    $where = 'WHERE ' . implode(' OR ', $where);
    /*
     * Determine the relevant options that do not already use the given autoload value.
     * If no options are returned, no need to update.
     */
    // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
    $options_to_update = $wpdb->get_col($wpdb->prepare("SELECT option_name FROM {$wpdb->options} {$where}", $where_args));
    if (!$options_to_update) {
        return $results;
    }
    // Run UPDATE queries as needed (maximum 2) to update the relevant options' autoload values to 'yes' or 'no'.
    foreach ($grouped_options as $autoload => $options) {
        if (!$options) {
            continue;
        }
        $options = array_intersect($options, $options_to_update);
        $grouped_options[$autoload] = $options;
        if (!$grouped_options[$autoload]) {
            continue;
        }
        // Run query to update autoload value for all the options where it is needed.
        $success = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->options} SET autoload = %s WHERE option_name IN (" . implode(',', array_fill(0, count($grouped_options[$autoload]), '%s')) . ')', array_merge(array($autoload), $grouped_options[$autoload])));
        if (!$success) {
            // Set option list to an empty array to indicate no options were updated.
            $grouped_options[$autoload] = array();
            continue;
        }
        // Assume that on success all options were updated, which should be the case given only new values are sent.
        foreach ($grouped_options[$autoload] as $option) {
            $results[$option] = true;
        }
    }
    /*
     * If any options were changed to 'yes', delete their individual caches, and delete 'alloptions' cache so that it
     * is refreshed as needed.
     * If no options were changed to 'yes' but any options were changed to 'no', delete them from the 'alloptions'
     * cache. This is not necessary when options were changed to 'yes', since in that situation the entire cache is
     * deleted anyway.
     */
    if ($grouped_options['yes']) {
        wp_cache_delete_multiple($grouped_options['yes'], 'options');
        wp_cache_delete('alloptions', 'options');
    } elseif ($grouped_options['no']) {
        $alloptions = wp_load_alloptions(true);
        foreach ($grouped_options['no'] as $option) {
            if (isset($alloptions[$option])) {
                unset($alloptions[$option]);
            }
        }
        wp_cache_set('alloptions', $alloptions, 'options');
    }
    return $results;
}