Avoid losing widgets when switching themes - take one, props aaroncampbell, see #17979

git-svn-id: https://develop.svn.wordpress.org/trunk@18630 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Ozz
2011-09-02 22:13:55 +00:00
parent 46773a16ea
commit 4782c3dc6f
4 changed files with 140 additions and 97 deletions
+30 -72
View File
@@ -44,10 +44,17 @@ $help .= '<p>' . __('<a href="http://codex.wordpress.org/Appearance_Widgets_Scre
$help .= '<p>' . __('<a href="http://wordpress.org/support/" target="_blank">Support Forums</a>') . '</p>';
add_contextual_help($current_screen, $help);
// These are the widgets grouped by sidebar
$sidebars_widgets = wp_get_sidebars_widgets();
if ( empty( $sidebars_widgets ) )
$sidebars_widgets = wp_get_widget_defaults();
// register the inactive_widgets area as sidebar
register_sidebar(array(
'name' => __('Inactive Widgets'),
'id' => 'wp_inactive_widgets',
'class' => 'inactive',
'description' => '',
'before_widget' => '',
'after_widget' => '',
@@ -55,78 +62,22 @@ register_sidebar(array(
'after_title' => '',
));
// These are the widgets grouped by sidebar
$sidebars_widgets = wp_get_sidebars_widgets();
if ( empty( $sidebars_widgets ) )
$sidebars_widgets = wp_get_widget_defaults();
// look for "lost" widgets, this has to run at least on each theme change
function retrieve_widgets() {
global $wp_registered_widget_updates, $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
$_sidebars_widgets = array();
$sidebars = array_keys($wp_registered_sidebars);
unset( $sidebars_widgets['array_version'] );
$old = array_keys($sidebars_widgets);
sort($old);
sort($sidebars);
if ( $old == $sidebars )
return;
// Move the known-good ones first
foreach ( $sidebars as $id ) {
if ( array_key_exists( $id, $sidebars_widgets ) ) {
$_sidebars_widgets[$id] = $sidebars_widgets[$id];
unset($sidebars_widgets[$id], $sidebars[$id]);
}
foreach ( $sidebars_widgets as $sidebar_id => $widgets ) {
if ( empty( $wp_registered_sidebars[ $sidebar_id ] ) && ! empty( $widgets ) ) {
// register the inactive_widgets area as sidebar
register_sidebar(array(
'name' => __( 'Inactive Widgets (Previous Theme)' ),
'id' => $sidebar_id,
'class' => 'orphaned',
'description' => __( 'This is a left over sidebar from an old theme and does not show anywhere on your site' ),
'before_widget' => '',
'after_widget' => '',
'before_title' => '',
'after_title' => '',
));
}
// if new theme has less sidebars than the old theme
if ( !empty($sidebars_widgets) ) {
foreach ( $sidebars_widgets as $lost => $val ) {
if ( is_array($val) )
$_sidebars_widgets['wp_inactive_widgets'] = array_merge( (array) $_sidebars_widgets['wp_inactive_widgets'], $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);
}
retrieve_widgets();
if ( count($wp_registered_sidebars) == 1 ) {
@@ -387,8 +338,15 @@ $i = 0;
foreach ( $wp_registered_sidebars as $sidebar => $registered_sidebar ) {
if ( 'wp_inactive_widgets' == $sidebar )
continue;
$closed = $i ? ' closed' : ''; ?>
<div class="widgets-holder-wrap<?php echo $closed; ?>">
$wrap_class = 'widgets-holder-wrap';
if ( !empty( $registered_sidebar['class'] ) )
$wrap_class .= ' sidebar-' . $registered_sidebar['class'];
if ( $i )
$wrap_class .= ' closed'; ?>
<div class="<?php esc_attr_e( $wrap_class ); ?>">
<div class="sidebar-name">
<div class="sidebar-name-arrow"><br /></div>
<h3><?php echo esc_html( $registered_sidebar['name'] ); ?>