retrieve_widgets

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

WordPress Version: 6.5

/**
 * Validates and remaps any "orphaned" widgets to wp_inactive_widgets sidebar,
 * and saves the widget settings. This has to run at least on each theme change.
 *
 * For example, let's say theme A has a "footer" sidebar, and theme B doesn't have one.
 * After switching from theme A to theme B, all the widgets previously assigned
 * to the footer would be inaccessible. This function detects this scenario, and
 * moves all the widgets previously assigned to the footer under wp_inactive_widgets.
 *
 * Despite the word "retrieve" in the name, this function actually updates the database
 * and the global `$sidebars_widgets`. For that reason it should not be run on front end,
 * unless the `$theme_changed` value is 'customize' (to bypass the database write).
 *
 * @since 2.8.0
 *
 * @global array $wp_registered_sidebars The registered sidebars.
 * @global array $sidebars_widgets
 * @global array $wp_registered_widgets  The registered widgets.
 *
 * @param string|bool $theme_changed Whether the theme was changed as a boolean. A value
 *                                   of 'customize' defers updates for the Customizer.
 * @return array Updated sidebars widgets.
 */
function retrieve_widgets($theme_changed = false)
{
    global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
    $registered_sidebars_keys = array_keys($wp_registered_sidebars);
    $registered_widgets_ids = array_keys($wp_registered_widgets);
    if (!is_array(get_theme_mod('sidebars_widgets'))) {
        if (empty($sidebars_widgets)) {
            return array();
        }
        unset($sidebars_widgets['array_version']);
        $sidebars_widgets_keys = array_keys($sidebars_widgets);
        sort($sidebars_widgets_keys);
        sort($registered_sidebars_keys);
        if ($sidebars_widgets_keys === $registered_sidebars_keys) {
            $sidebars_widgets = _wp_remove_unregistered_widgets($sidebars_widgets, $registered_widgets_ids);
            return $sidebars_widgets;
        }
    }
    // Discard invalid, theme-specific widgets from sidebars.
    $sidebars_widgets = _wp_remove_unregistered_widgets($sidebars_widgets, $registered_widgets_ids);
    $sidebars_widgets = wp_map_sidebars_widgets($sidebars_widgets);
    // Find hidden/lost multi-widget instances.
    $shown_widgets = array_merge(...array_values($sidebars_widgets));
    $lost_widgets = array_diff($registered_widgets_ids, $shown_widgets);
    foreach ($lost_widgets as $key => $widget_id) {
        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $widget_id);
        // Only keep active and default widgets.
        if (is_numeric($number) && (int) $number < 2) {
            unset($lost_widgets[$key]);
        }
    }
    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
    if ('customize' !== $theme_changed) {
        // Update the widgets settings in the database.
        wp_set_sidebars_widgets($sidebars_widgets);
    }
    return $sidebars_widgets;
}

WordPress Version: 5.9

/**
 * Validates and remaps any "orphaned" widgets to wp_inactive_widgets sidebar,
 * and saves the widget settings. This has to run at least on each theme change.
 *
 * For example, let's say theme A has a "footer" sidebar, and theme B doesn't have one.
 * After switching from theme A to theme B, all the widgets previously assigned
 * to the footer would be inaccessible. This function detects this scenario, and
 * moves all the widgets previously assigned to the footer under wp_inactive_widgets.
 *
 * Despite the word "retrieve" in the name, this function actually updates the database
 * and the global `$sidebars_widgets`. For that reason it should not be run on front end,
 * unless the `$theme_changed` value is 'customize' (to bypass the database write).
 *
 * @since 2.8.0
 *
 * @global array $wp_registered_sidebars Registered sidebars.
 * @global array $sidebars_widgets
 * @global array $wp_registered_widgets  Registered widgets.
 *
 * @param string|bool $theme_changed Whether the theme was changed as a boolean. A value
 *                                   of 'customize' defers updates for the Customizer.
 * @return array Updated sidebars widgets.
 */
function retrieve_widgets($theme_changed = false)
{
    global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
    $registered_sidebars_keys = array_keys($wp_registered_sidebars);
    $registered_widgets_ids = array_keys($wp_registered_widgets);
    if (!is_array(get_theme_mod('sidebars_widgets'))) {
        if (empty($sidebars_widgets)) {
            return array();
        }
        unset($sidebars_widgets['array_version']);
        $sidebars_widgets_keys = array_keys($sidebars_widgets);
        sort($sidebars_widgets_keys);
        sort($registered_sidebars_keys);
        if ($sidebars_widgets_keys === $registered_sidebars_keys) {
            $sidebars_widgets = _wp_remove_unregistered_widgets($sidebars_widgets, $registered_widgets_ids);
            return $sidebars_widgets;
        }
    }
    // Discard invalid, theme-specific widgets from sidebars.
    $sidebars_widgets = _wp_remove_unregistered_widgets($sidebars_widgets, $registered_widgets_ids);
    $sidebars_widgets = wp_map_sidebars_widgets($sidebars_widgets);
    // Find hidden/lost multi-widget instances.
    $shown_widgets = array_merge(...array_values($sidebars_widgets));
    $lost_widgets = array_diff($registered_widgets_ids, $shown_widgets);
    foreach ($lost_widgets as $key => $widget_id) {
        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $widget_id);
        // Only keep active and default widgets.
        if (is_numeric($number) && (int) $number < 2) {
            unset($lost_widgets[$key]);
        }
    }
    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
    if ('customize' !== $theme_changed) {
        // Update the widgets settings in the database.
        wp_set_sidebars_widgets($sidebars_widgets);
    }
    return $sidebars_widgets;
}

WordPress Version: 5.6

/**
 * Look for "lost" widgets, this has to run at least on each theme change.
 *
 * @since 2.8.0
 *
 * @global array $wp_registered_sidebars Registered sidebars.
 * @global array $sidebars_widgets
 * @global array $wp_registered_widgets  Registered widgets.
 *
 * @param string|bool $theme_changed Whether the theme was changed as a boolean. A value
 *                                   of 'customize' defers updates for the Customizer.
 * @return array Updated sidebars widgets.
 */
function retrieve_widgets($theme_changed = false)
{
    global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
    $registered_sidebars_keys = array_keys($wp_registered_sidebars);
    $registered_widgets_ids = array_keys($wp_registered_widgets);
    if (!is_array(get_theme_mod('sidebars_widgets'))) {
        if (empty($sidebars_widgets)) {
            return array();
        }
        unset($sidebars_widgets['array_version']);
        $sidebars_widgets_keys = array_keys($sidebars_widgets);
        sort($sidebars_widgets_keys);
        sort($registered_sidebars_keys);
        if ($sidebars_widgets_keys === $registered_sidebars_keys) {
            $sidebars_widgets = _wp_remove_unregistered_widgets($sidebars_widgets, $registered_widgets_ids);
            return $sidebars_widgets;
        }
    }
    // Discard invalid, theme-specific widgets from sidebars.
    $sidebars_widgets = _wp_remove_unregistered_widgets($sidebars_widgets, $registered_widgets_ids);
    $sidebars_widgets = wp_map_sidebars_widgets($sidebars_widgets);
    // Find hidden/lost multi-widget instances.
    $shown_widgets = array_merge(...array_values($sidebars_widgets));
    $lost_widgets = array_diff($registered_widgets_ids, $shown_widgets);
    foreach ($lost_widgets as $key => $widget_id) {
        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $widget_id);
        // Only keep active and default widgets.
        if (is_numeric($number) && (int) $number < 2) {
            unset($lost_widgets[$key]);
        }
    }
    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
    if ('customize' !== $theme_changed) {
        wp_set_sidebars_widgets($sidebars_widgets);
    }
    return $sidebars_widgets;
}

WordPress Version: 5.5

/**
 * Look for "lost" widgets, this has to run at least on each theme change.
 *
 * @since 2.8.0
 *
 * @global array $wp_registered_sidebars Registered sidebars.
 * @global array $sidebars_widgets
 * @global array $wp_registered_widgets  Registered widgets.
 *
 * @param string|bool $theme_changed Whether the theme was changed as a boolean. A value
 *                                   of 'customize' defers updates for the Customizer.
 * @return array Updated sidebars widgets.
 */
function retrieve_widgets($theme_changed = false)
{
    global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
    $registered_sidebars_keys = array_keys($wp_registered_sidebars);
    $registered_widgets_ids = array_keys($wp_registered_widgets);
    if (!is_array(get_theme_mod('sidebars_widgets'))) {
        if (empty($sidebars_widgets)) {
            return array();
        }
        unset($sidebars_widgets['array_version']);
        $sidebars_widgets_keys = array_keys($sidebars_widgets);
        sort($sidebars_widgets_keys);
        sort($registered_sidebars_keys);
        if ($sidebars_widgets_keys === $registered_sidebars_keys) {
            $sidebars_widgets = _wp_remove_unregistered_widgets($sidebars_widgets, $registered_widgets_ids);
            return $sidebars_widgets;
        }
    }
    // Discard invalid, theme-specific widgets from sidebars.
    $sidebars_widgets = _wp_remove_unregistered_widgets($sidebars_widgets, $registered_widgets_ids);
    $sidebars_widgets = wp_map_sidebars_widgets($sidebars_widgets);
    // Find hidden/lost multi-widget instances.
    $shown_widgets = call_user_func_array('array_merge', $sidebars_widgets);
    $lost_widgets = array_diff($registered_widgets_ids, $shown_widgets);
    foreach ($lost_widgets as $key => $widget_id) {
        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $widget_id);
        // Only keep active and default widgets.
        if (is_numeric($number) && (int) $number < 2) {
            unset($lost_widgets[$key]);
        }
    }
    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
    if ('customize' !== $theme_changed) {
        wp_set_sidebars_widgets($sidebars_widgets);
    }
    return $sidebars_widgets;
}

WordPress Version: 5.1

/**
 * Look for "lost" widgets, this has to run at least on each theme change.
 *
 * @since 2.8.0
 *
 * @global array $wp_registered_sidebars Registered sidebars.
 * @global array $sidebars_widgets
 * @global array $wp_registered_widgets
 *
 * @param string|bool $theme_changed Whether the theme was changed as a boolean. A value
 *                                   of 'customize' defers updates for the Customizer.
 * @return array Updated sidebars widgets.
 */
function retrieve_widgets($theme_changed = false)
{
    global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
    $registered_sidebars_keys = array_keys($wp_registered_sidebars);
    $registered_widgets_ids = array_keys($wp_registered_widgets);
    if (!is_array(get_theme_mod('sidebars_widgets'))) {
        if (empty($sidebars_widgets)) {
            return array();
        }
        unset($sidebars_widgets['array_version']);
        $sidebars_widgets_keys = array_keys($sidebars_widgets);
        sort($sidebars_widgets_keys);
        sort($registered_sidebars_keys);
        if ($sidebars_widgets_keys === $registered_sidebars_keys) {
            $sidebars_widgets = _wp_remove_unregistered_widgets($sidebars_widgets, $registered_widgets_ids);
            return $sidebars_widgets;
        }
    }
    // Discard invalid, theme-specific widgets from sidebars.
    $sidebars_widgets = _wp_remove_unregistered_widgets($sidebars_widgets, $registered_widgets_ids);
    $sidebars_widgets = wp_map_sidebars_widgets($sidebars_widgets);
    // Find hidden/lost multi-widget instances.
    $shown_widgets = call_user_func_array('array_merge', $sidebars_widgets);
    $lost_widgets = array_diff($registered_widgets_ids, $shown_widgets);
    foreach ($lost_widgets as $key => $widget_id) {
        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $widget_id);
        // Only keep active and default widgets.
        if (is_numeric($number) && (int) $number < 2) {
            unset($lost_widgets[$key]);
        }
    }
    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
    if ('customize' !== $theme_changed) {
        wp_set_sidebars_widgets($sidebars_widgets);
    }
    return $sidebars_widgets;
}

WordPress Version: 4.9

/**
 * Look for "lost" widgets, this has to run at least on each theme change.
 *
 * @since 2.8.0
 *
 * @global array $wp_registered_sidebars
 * @global array $sidebars_widgets
 * @global array $wp_registered_widgets
 *
 * @param string|bool $theme_changed Whether the theme was changed as a boolean. A value
 *                                   of 'customize' defers updates for the Customizer.
 * @return array Updated sidebars widgets.
 */
function retrieve_widgets($theme_changed = false)
{
    global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
    $registered_sidebars_keys = array_keys($wp_registered_sidebars);
    $registered_widgets_ids = array_keys($wp_registered_widgets);
    if (!is_array(get_theme_mod('sidebars_widgets'))) {
        if (empty($sidebars_widgets)) {
            return array();
        }
        unset($sidebars_widgets['array_version']);
        $sidebars_widgets_keys = array_keys($sidebars_widgets);
        sort($sidebars_widgets_keys);
        sort($registered_sidebars_keys);
        if ($sidebars_widgets_keys === $registered_sidebars_keys) {
            $sidebars_widgets = _wp_remove_unregistered_widgets($sidebars_widgets, $registered_widgets_ids);
            return $sidebars_widgets;
        }
    }
    // Discard invalid, theme-specific widgets from sidebars.
    $sidebars_widgets = _wp_remove_unregistered_widgets($sidebars_widgets, $registered_widgets_ids);
    $sidebars_widgets = wp_map_sidebars_widgets($sidebars_widgets);
    // Find hidden/lost multi-widget instances.
    $shown_widgets = call_user_func_array('array_merge', $sidebars_widgets);
    $lost_widgets = array_diff($registered_widgets_ids, $shown_widgets);
    foreach ($lost_widgets as $key => $widget_id) {
        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $widget_id);
        // Only keep active and default widgets.
        if (is_numeric($number) && (int) $number < 2) {
            unset($lost_widgets[$key]);
        }
    }
    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
    if ('customize' !== $theme_changed) {
        wp_set_sidebars_widgets($sidebars_widgets);
    }
    return $sidebars_widgets;
}

WordPress Version: 4.3

/**
 * Look for "lost" widgets, this has to run at least on each theme change.
 *
 * @since 2.8.0
 *
 * @global array $wp_registered_sidebars
 * @global array $sidebars_widgets
 * @global array $wp_registered_widgets
 *
 * @param string|bool $theme_changed Whether the theme was changed as a boolean. A value
 *                                   of 'customize' defers updates for the Customizer.
 * @return array|void
 */
function retrieve_widgets($theme_changed = false)
{
    global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
    $registered_sidebar_keys = array_keys($wp_registered_sidebars);
    $orphaned = 0;
    $old_sidebars_widgets = get_theme_mod('sidebars_widgets');
    if (is_array($old_sidebars_widgets)) {
        // time() that sidebars were stored is in $old_sidebars_widgets['time']
        $_sidebars_widgets = $old_sidebars_widgets['data'];
        if ('customize' !== $theme_changed) {
            remove_theme_mod('sidebars_widgets');
        }
        foreach ($_sidebars_widgets as $sidebar => $widgets) {
            if ('wp_inactive_widgets' === $sidebar || 'orphaned_widgets' === substr($sidebar, 0, 16)) {
                continue;
            }
            if (!in_array($sidebar, $registered_sidebar_keys)) {
                $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $widgets;
                unset($_sidebars_widgets[$sidebar]);
            }
        }
    } else {
        if (empty($sidebars_widgets)) {
            return;
        }
        unset($sidebars_widgets['array_version']);
        $old = array_keys($sidebars_widgets);
        sort($old);
        sort($registered_sidebar_keys);
        if ($old == $registered_sidebar_keys) {
            return;
        }
        $_sidebars_widgets = array('wp_inactive_widgets' => (!empty($sidebars_widgets['wp_inactive_widgets'])) ? $sidebars_widgets['wp_inactive_widgets'] : array());
        unset($sidebars_widgets['wp_inactive_widgets']);
        foreach ($wp_registered_sidebars as $id => $settings) {
            if ($theme_changed) {
                $_sidebars_widgets[$id] = array_shift($sidebars_widgets);
            } else if (isset($sidebars_widgets[$id])) {
                $_sidebars_widgets[$id] = $sidebars_widgets[$id];
                unset($sidebars_widgets[$id]);
            }
        }
        foreach ($sidebars_widgets as $val) {
            if (is_array($val) && !empty($val)) {
                $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $val;
            }
        }
    }
    // discard invalid, theme-specific widgets from sidebars
    $shown_widgets = array();
    foreach ($_sidebars_widgets as $sidebar => $widgets) {
        if (!is_array($widgets)) {
            continue;
        }
        $_widgets = array();
        foreach ($widgets as $widget) {
            if (isset($wp_registered_widgets[$widget])) {
                $_widgets[] = $widget;
            }
        }
        $_sidebars_widgets[$sidebar] = $_widgets;
        $shown_widgets = array_merge($shown_widgets, $_widgets);
    }
    $sidebars_widgets = $_sidebars_widgets;
    unset($_sidebars_widgets, $_widgets);
    // find hidden/lost multi-widget instances
    $lost_widgets = array();
    foreach ($wp_registered_widgets as $key => $val) {
        if (in_array($key, $shown_widgets, true)) {
            continue;
        }
        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key);
        if (2 > (int) $number) {
            continue;
        }
        $lost_widgets[] = $key;
    }
    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
    if ('customize' !== $theme_changed) {
        wp_set_sidebars_widgets($sidebars_widgets);
    }
    return $sidebars_widgets;
}

WordPress Version: 4.1

/**
 * Look for "lost" widgets, this has to run at least on each theme change.
 *
 * @since 2.8.0
 *
 * @param string|bool $theme_changed Whether the theme was changed as a boolean. A value
 *                                   of 'customize' defers updates for the Customizer.
 * @return array
 */
function retrieve_widgets($theme_changed = false)
{
    global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
    $registered_sidebar_keys = array_keys($wp_registered_sidebars);
    $orphaned = 0;
    $old_sidebars_widgets = get_theme_mod('sidebars_widgets');
    if (is_array($old_sidebars_widgets)) {
        // time() that sidebars were stored is in $old_sidebars_widgets['time']
        $_sidebars_widgets = $old_sidebars_widgets['data'];
        if ('customize' !== $theme_changed) {
            remove_theme_mod('sidebars_widgets');
        }
        foreach ($_sidebars_widgets as $sidebar => $widgets) {
            if ('wp_inactive_widgets' === $sidebar || 'orphaned_widgets' === substr($sidebar, 0, 16)) {
                continue;
            }
            if (!in_array($sidebar, $registered_sidebar_keys)) {
                $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $widgets;
                unset($_sidebars_widgets[$sidebar]);
            }
        }
    } else {
        if (empty($sidebars_widgets)) {
            return;
        }
        unset($sidebars_widgets['array_version']);
        $old = array_keys($sidebars_widgets);
        sort($old);
        sort($registered_sidebar_keys);
        if ($old == $registered_sidebar_keys) {
            return;
        }
        $_sidebars_widgets = array('wp_inactive_widgets' => (!empty($sidebars_widgets['wp_inactive_widgets'])) ? $sidebars_widgets['wp_inactive_widgets'] : array());
        unset($sidebars_widgets['wp_inactive_widgets']);
        foreach ($wp_registered_sidebars as $id => $settings) {
            if ($theme_changed) {
                $_sidebars_widgets[$id] = array_shift($sidebars_widgets);
            } else if (isset($sidebars_widgets[$id])) {
                $_sidebars_widgets[$id] = $sidebars_widgets[$id];
                unset($sidebars_widgets[$id]);
            }
        }
        foreach ($sidebars_widgets as $val) {
            if (is_array($val) && !empty($val)) {
                $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $val;
            }
        }
    }
    // discard invalid, theme-specific widgets from sidebars
    $shown_widgets = array();
    foreach ($_sidebars_widgets as $sidebar => $widgets) {
        if (!is_array($widgets)) {
            continue;
        }
        $_widgets = array();
        foreach ($widgets as $widget) {
            if (isset($wp_registered_widgets[$widget])) {
                $_widgets[] = $widget;
            }
        }
        $_sidebars_widgets[$sidebar] = $_widgets;
        $shown_widgets = array_merge($shown_widgets, $_widgets);
    }
    $sidebars_widgets = $_sidebars_widgets;
    unset($_sidebars_widgets, $_widgets);
    // find hidden/lost multi-widget instances
    $lost_widgets = array();
    foreach ($wp_registered_widgets as $key => $val) {
        if (in_array($key, $shown_widgets, true)) {
            continue;
        }
        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key);
        if (2 > (int) $number) {
            continue;
        }
        $lost_widgets[] = $key;
    }
    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
    if ('customize' !== $theme_changed) {
        wp_set_sidebars_widgets($sidebars_widgets);
    }
    return $sidebars_widgets;
}

WordPress Version: 4.0

/**
 * Look for "lost" widgets, this has to run at least on each theme change.
 *
 * @since 2.8.0
 *
 * @param mixed $theme_changed Whether the theme was changed as a boolean. A value
 *                             of 'customize' defers updates for the customizer.
 * @return array
 */
function retrieve_widgets($theme_changed = false)
{
    global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
    $registered_sidebar_keys = array_keys($wp_registered_sidebars);
    $orphaned = 0;
    $old_sidebars_widgets = get_theme_mod('sidebars_widgets');
    if (is_array($old_sidebars_widgets)) {
        // time() that sidebars were stored is in $old_sidebars_widgets['time']
        $_sidebars_widgets = $old_sidebars_widgets['data'];
        if ('customize' !== $theme_changed) {
            remove_theme_mod('sidebars_widgets');
        }
        foreach ($_sidebars_widgets as $sidebar => $widgets) {
            if ('wp_inactive_widgets' === $sidebar || 'orphaned_widgets' === substr($sidebar, 0, 16)) {
                continue;
            }
            if (!in_array($sidebar, $registered_sidebar_keys)) {
                $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $widgets;
                unset($_sidebars_widgets[$sidebar]);
            }
        }
    } else {
        if (empty($sidebars_widgets)) {
            return;
        }
        unset($sidebars_widgets['array_version']);
        $old = array_keys($sidebars_widgets);
        sort($old);
        sort($registered_sidebar_keys);
        if ($old == $registered_sidebar_keys) {
            return;
        }
        $_sidebars_widgets = array('wp_inactive_widgets' => (!empty($sidebars_widgets['wp_inactive_widgets'])) ? $sidebars_widgets['wp_inactive_widgets'] : array());
        unset($sidebars_widgets['wp_inactive_widgets']);
        foreach ($wp_registered_sidebars as $id => $settings) {
            if ($theme_changed) {
                $_sidebars_widgets[$id] = array_shift($sidebars_widgets);
            } else if (isset($sidebars_widgets[$id])) {
                $_sidebars_widgets[$id] = $sidebars_widgets[$id];
                unset($sidebars_widgets[$id]);
            }
        }
        foreach ($sidebars_widgets as $val) {
            if (is_array($val) && !empty($val)) {
                $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $val;
            }
        }
    }
    // discard invalid, theme-specific widgets from sidebars
    $shown_widgets = array();
    foreach ($_sidebars_widgets as $sidebar => $widgets) {
        if (!is_array($widgets)) {
            continue;
        }
        $_widgets = array();
        foreach ($widgets as $widget) {
            if (isset($wp_registered_widgets[$widget])) {
                $_widgets[] = $widget;
            }
        }
        $_sidebars_widgets[$sidebar] = $_widgets;
        $shown_widgets = array_merge($shown_widgets, $_widgets);
    }
    $sidebars_widgets = $_sidebars_widgets;
    unset($_sidebars_widgets, $_widgets);
    // find hidden/lost multi-widget instances
    $lost_widgets = array();
    foreach ($wp_registered_widgets as $key => $val) {
        if (in_array($key, $shown_widgets, true)) {
            continue;
        }
        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key);
        if (2 > (int) $number) {
            continue;
        }
        $lost_widgets[] = $key;
    }
    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
    if ('customize' !== $theme_changed) {
        wp_set_sidebars_widgets($sidebars_widgets);
    }
    return $sidebars_widgets;
}

WordPress Version: 9.1

/**
 * Look for "lost" widgets, this has to run at least on each theme change.
 *
 * @since 2.8.0
 *
 * @param mixed $theme_changed Whether the theme was changed as a boolean. A value
 *                             of 'customize' defers updates for the customizer.
 * @return array
 */
function retrieve_widgets($theme_changed = false)
{
    global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
    $registered_sidebar_keys = array_keys($wp_registered_sidebars);
    $orphaned = 0;
    $old_sidebars_widgets = get_theme_mod('sidebars_widgets');
    if (is_array($old_sidebars_widgets)) {
        // time() that sidebars were stored is in $old_sidebars_widgets['time']
        $_sidebars_widgets = $old_sidebars_widgets['data'];
        if ('customize' !== $theme_changed) {
            remove_theme_mod('sidebars_widgets');
        }
        foreach ($_sidebars_widgets as $sidebar => $widgets) {
            if ('wp_inactive_widgets' == $sidebar || 'orphaned_widgets' == substr($sidebar, 0, 16)) {
                continue;
            }
            if (!in_array($sidebar, $registered_sidebar_keys)) {
                $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $widgets;
                unset($_sidebars_widgets[$sidebar]);
            }
        }
    } else {
        if (empty($sidebars_widgets)) {
            return;
        }
        unset($sidebars_widgets['array_version']);
        $old = array_keys($sidebars_widgets);
        sort($old);
        sort($registered_sidebar_keys);
        if ($old == $registered_sidebar_keys) {
            return;
        }
        $_sidebars_widgets = array('wp_inactive_widgets' => (!empty($sidebars_widgets['wp_inactive_widgets'])) ? $sidebars_widgets['wp_inactive_widgets'] : array());
        unset($sidebars_widgets['wp_inactive_widgets']);
        foreach ($wp_registered_sidebars as $id => $settings) {
            if ($theme_changed) {
                $_sidebars_widgets[$id] = array_shift($sidebars_widgets);
            } else if (isset($sidebars_widgets[$id])) {
                $_sidebars_widgets[$id] = $sidebars_widgets[$id];
                unset($sidebars_widgets[$id]);
            }
        }
        foreach ($sidebars_widgets as $val) {
            if (is_array($val) && !empty($val)) {
                $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $val;
            }
        }
    }
    // discard invalid, theme-specific widgets from sidebars
    $shown_widgets = array();
    foreach ($_sidebars_widgets as $sidebar => $widgets) {
        if (!is_array($widgets)) {
            continue;
        }
        $_widgets = array();
        foreach ($widgets as $widget) {
            if (isset($wp_registered_widgets[$widget])) {
                $_widgets[] = $widget;
            }
        }
        $_sidebars_widgets[$sidebar] = $_widgets;
        $shown_widgets = array_merge($shown_widgets, $_widgets);
    }
    $sidebars_widgets = $_sidebars_widgets;
    unset($_sidebars_widgets, $_widgets);
    // find hidden/lost multi-widget instances
    $lost_widgets = array();
    foreach ($wp_registered_widgets as $key => $val) {
        if (in_array($key, $shown_widgets, true)) {
            continue;
        }
        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key);
        if (2 > (int) $number) {
            continue;
        }
        $lost_widgets[] = $key;
    }
    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
    if ('customize' !== $theme_changed) {
        wp_set_sidebars_widgets($sidebars_widgets);
    }
    return $sidebars_widgets;
}

WordPress Version: 3.9

/**
 * Look for "lost" widgets, this has to run at least on each theme change.
 *
 * @since 2.8.0
 *
 * @param mixed $theme_changed Whether the theme was changed as a boolean. A value
 *                             of 'customize' defers updates for the customizer.
 * @return array
 */
function retrieve_widgets($theme_changed = false)
{
    global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
    $registered_sidebar_keys = array_keys($wp_registered_sidebars);
    $orphaned = 0;
    $old_sidebars_widgets = get_theme_mod('sidebars_widgets');
    if (is_array($old_sidebars_widgets)) {
        // time() that sidebars were stored is in $old_sidebars_widgets['time']
        $_sidebars_widgets = $old_sidebars_widgets['data'];
        if ('customize' === $theme_changed) {
            remove_theme_mod('sidebars_widgets');
        }
        foreach ($_sidebars_widgets as $sidebar => $widgets) {
            if ('wp_inactive_widgets' == $sidebar || 'orphaned_widgets' == substr($sidebar, 0, 16)) {
                continue;
            }
            if (!in_array($sidebar, $registered_sidebar_keys)) {
                $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $widgets;
                unset($_sidebars_widgets[$sidebar]);
            }
        }
    } else {
        if (empty($sidebars_widgets)) {
            return;
        }
        unset($sidebars_widgets['array_version']);
        $old = array_keys($sidebars_widgets);
        sort($old);
        sort($registered_sidebar_keys);
        if ($old == $registered_sidebar_keys) {
            return;
        }
        $_sidebars_widgets = array('wp_inactive_widgets' => (!empty($sidebars_widgets['wp_inactive_widgets'])) ? $sidebars_widgets['wp_inactive_widgets'] : array());
        unset($sidebars_widgets['wp_inactive_widgets']);
        foreach ($wp_registered_sidebars as $id => $settings) {
            if ($theme_changed) {
                $_sidebars_widgets[$id] = array_shift($sidebars_widgets);
            } else if (isset($sidebars_widgets[$id])) {
                $_sidebars_widgets[$id] = $sidebars_widgets[$id];
                unset($sidebars_widgets[$id]);
            }
        }
        foreach ($sidebars_widgets as $val) {
            if (is_array($val) && !empty($val)) {
                $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $val;
            }
        }
    }
    // discard invalid, theme-specific widgets from sidebars
    $shown_widgets = array();
    foreach ($_sidebars_widgets as $sidebar => $widgets) {
        if (!is_array($widgets)) {
            continue;
        }
        $_widgets = array();
        foreach ($widgets as $widget) {
            if (isset($wp_registered_widgets[$widget])) {
                $_widgets[] = $widget;
            }
        }
        $_sidebars_widgets[$sidebar] = $_widgets;
        $shown_widgets = array_merge($shown_widgets, $_widgets);
    }
    $sidebars_widgets = $_sidebars_widgets;
    unset($_sidebars_widgets, $_widgets);
    // find hidden/lost multi-widget instances
    $lost_widgets = array();
    foreach ($wp_registered_widgets as $key => $val) {
        if (in_array($key, $shown_widgets, true)) {
            continue;
        }
        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key);
        if (2 > (int) $number) {
            continue;
        }
        $lost_widgets[] = $key;
    }
    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
    if ('customize' === $theme_changed) {
        wp_set_sidebars_widgets($sidebars_widgets);
    }
    return $sidebars_widgets;
}

WordPress Version: 3.7

// look for "lost" widgets, this has to run at least on each theme change
function retrieve_widgets($theme_changed = false)
{
    global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
    $registered_sidebar_keys = array_keys($wp_registered_sidebars);
    $orphaned = 0;
    $old_sidebars_widgets = get_theme_mod('sidebars_widgets');
    if (is_array($old_sidebars_widgets)) {
        // time() that sidebars were stored is in $old_sidebars_widgets['time']
        $_sidebars_widgets = $old_sidebars_widgets['data'];
        remove_theme_mod('sidebars_widgets');
        foreach ($_sidebars_widgets as $sidebar => $widgets) {
            if ('wp_inactive_widgets' == $sidebar || 'orphaned_widgets' == substr($sidebar, 0, 16)) {
                continue;
            }
            if (!in_array($sidebar, $registered_sidebar_keys)) {
                $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $widgets;
                unset($_sidebars_widgets[$sidebar]);
            }
        }
    } else {
        if (empty($sidebars_widgets)) {
            return;
        }
        unset($sidebars_widgets['array_version']);
        $old = array_keys($sidebars_widgets);
        sort($old);
        sort($registered_sidebar_keys);
        if ($old == $registered_sidebar_keys) {
            return;
        }
        $_sidebars_widgets = array('wp_inactive_widgets' => (!empty($sidebars_widgets['wp_inactive_widgets'])) ? $sidebars_widgets['wp_inactive_widgets'] : array());
        unset($sidebars_widgets['wp_inactive_widgets']);
        foreach ($wp_registered_sidebars as $id => $settings) {
            if ($theme_changed) {
                $_sidebars_widgets[$id] = array_shift($sidebars_widgets);
            } else if (isset($sidebars_widgets[$id])) {
                $_sidebars_widgets[$id] = $sidebars_widgets[$id];
                unset($sidebars_widgets[$id]);
            }
        }
        foreach ($sidebars_widgets as $val) {
            if (is_array($val) && !empty($val)) {
                $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $val;
            }
        }
    }
    // discard invalid, theme-specific widgets from sidebars
    $shown_widgets = array();
    foreach ($_sidebars_widgets as $sidebar => $widgets) {
        if (!is_array($widgets)) {
            continue;
        }
        $_widgets = array();
        foreach ($widgets as $widget) {
            if (isset($wp_registered_widgets[$widget])) {
                $_widgets[] = $widget;
            }
        }
        $_sidebars_widgets[$sidebar] = $_widgets;
        $shown_widgets = array_merge($shown_widgets, $_widgets);
    }
    $sidebars_widgets = $_sidebars_widgets;
    unset($_sidebars_widgets, $_widgets);
    // find hidden/lost multi-widget instances
    $lost_widgets = array();
    foreach ($wp_registered_widgets as $key => $val) {
        if (in_array($key, $shown_widgets, true)) {
            continue;
        }
        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key);
        if (2 > (int) $number) {
            continue;
        }
        $lost_widgets[] = $key;
    }
    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
    wp_set_sidebars_widgets($sidebars_widgets);
    return $sidebars_widgets;
}