+
+/**
+ * Handle sidebars config after theme change
+ *
+ * @access private
+ * @since 3.3
+ */
+function _wp_sidebars_changed() {
+ global $sidebars_widgets;
+
+ if ( ! is_array( $sidebars_widgets ) )
+ $sidebars_widgets = wp_get_sidebars_widgets();
+
+ retrieve_widgets(true);
+}
+
+// look for "lost" widgets, this has to run at least on each theme change
+function retrieve_widgets($theme_changed = false) {
+ global $wp_registered_widget_updates, $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 {
+ // no theme change, grab only sidebars that are currently registered
+ 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;
+}