Avoid losing widgets when switching themes - take one, props aaroncampbell, see #17979
git-svn-id: http://svn.automattic.com/wordpress/trunk@18630 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
1fd69ecf36
commit
4852c5887f
|
@ -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'] ); ?>
|
||||
|
|
|
@ -218,6 +218,7 @@ add_action( 'wp_footer', 'wp_print_footer_scripts', 20 );
|
|||
add_action( 'wp_head', 'wp_shortlink_wp_head', 10, 0 );
|
||||
add_action( 'template_redirect', 'wp_shortlink_header', 11, 0 );
|
||||
add_action( 'wp_print_footer_scripts', '_wp_footer_scripts' );
|
||||
add_action( 'init', 'check_theme_switched', 99 );
|
||||
|
||||
if ( isset( $_GET['replytocom'] ) )
|
||||
add_filter( 'pre_option_blog_public', '__return_zero' );
|
||||
|
|
|
@ -1248,19 +1248,26 @@ function preview_theme_ob_filter_callback( $matches ) {
|
|||
function switch_theme($template, $stylesheet) {
|
||||
global $wp_theme_directories;
|
||||
|
||||
$old_theme = get_current_theme();
|
||||
|
||||
update_option('template', $template);
|
||||
update_option('stylesheet', $stylesheet);
|
||||
|
||||
if ( count($wp_theme_directories) > 1 ) {
|
||||
update_option('template_root', get_raw_theme_root($template, true));
|
||||
update_option('stylesheet_root', get_raw_theme_root($stylesheet, true));
|
||||
}
|
||||
|
||||
delete_option('current_theme');
|
||||
$theme = get_current_theme();
|
||||
|
||||
if ( is_admin() && false === get_option( "theme_mods_$stylesheet" ) ) {
|
||||
$default_theme_mods = (array) get_option( "mods_$theme" );
|
||||
add_option( "theme_mods_$stylesheet", $default_theme_mods );
|
||||
}
|
||||
do_action('switch_theme', $theme);
|
||||
|
||||
update_option( 'theme_switched', $old_theme );
|
||||
do_action( 'switch_theme', $theme );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -547,6 +547,7 @@ function register_sidebar($args = array()) {
|
|||
'name' => sprintf(__('Sidebar %d'), $i ),
|
||||
'id' => "sidebar-$i",
|
||||
'description' => '',
|
||||
'class' => '',
|
||||
'before_widget' => '<li id="%1$s" class="widget %2$s">',
|
||||
'after_widget' => "</li>\n",
|
||||
'before_title' => '<h2 class="widgettitle">',
|
||||
|
@ -1055,30 +1056,7 @@ function wp_get_sidebars_widgets($deprecated = true) {
|
|||
unset($_sidebars_widgets);
|
||||
|
||||
case 2 :
|
||||
$sidebars = array_keys( $wp_registered_sidebars );
|
||||
if ( !empty( $sidebars ) ) {
|
||||
// Move the known-good ones first
|
||||
foreach ( (array) $sidebars as $id ) {
|
||||
if ( array_key_exists( $id, $sidebars_widgets ) ) {
|
||||
$_sidebars_widgets[$id] = $sidebars_widgets[$id];
|
||||
unset($sidebars_widgets[$id], $sidebars[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
// move the rest to wp_inactive_widgets
|
||||
if ( !isset($_sidebars_widgets['wp_inactive_widgets']) )
|
||||
$_sidebars_widgets['wp_inactive_widgets'] = array();
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
$sidebars_widgets = $_sidebars_widgets;
|
||||
unset($_sidebars_widgets);
|
||||
}
|
||||
$sidebars_widgets = retrieve_widgets();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1215,3 +1193,102 @@ function the_widget($widget, $instance = array(), $args = array()) {
|
|||
function _get_widget_id_base($id) {
|
||||
return preg_replace( '/-[0-9]+$/', '', $id );
|
||||
}
|
||||
|
||||
function check_theme_switched() {
|
||||
if ( false !== ( $old_theme = get_option( 'theme_switched' ) ) && !empty( $old_theme ) ) {
|
||||
global $sidebars_widgets;
|
||||
|
||||
if ( ! is_array( $sidebars_widgets ) )
|
||||
$sidebars_widgets = wp_get_sidebars_widgets();
|
||||
|
||||
$key = md5( $old_theme );
|
||||
// Store widgets for 1 week so we can restore if needed
|
||||
set_transient( 'old_widgets_' . $key, $sidebars_widgets, 604800 );
|
||||
|
||||
retrieve_widgets();
|
||||
update_option( 'theme_switched', false );
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
$key = md5( get_current_theme() );
|
||||
if ( false !== ( $_sidebars_widgets = get_transient( "old_widgets_{$key}" ) ) ) {
|
||||
delete_transient( "old_widgets_{$key}" );
|
||||
} else {
|
||||
if ( ! is_array( $sidebars_widgets ) )
|
||||
$sidebars_widgets = wp_get_sidebars_widgets();
|
||||
|
||||
$sidebars = array_keys($wp_registered_sidebars);
|
||||
|
||||
unset( $sidebars_widgets['array_version'] );
|
||||
|
||||
$old = array_keys($sidebars_widgets);
|
||||
sort($old);
|
||||
sort($sidebars);
|
||||
|
||||
if ( $old == $sidebars )
|
||||
return;
|
||||
|
||||
$_sidebars_widgets = array(
|
||||
'wp_inactive_widgets' => $sidebars_widgets['wp_inactive_widgets']
|
||||
);
|
||||
|
||||
unset( $sidebars_widgets['wp_inactive_widgets'] );
|
||||
|
||||
foreach ( $wp_registered_sidebars as $id => $settings ) {
|
||||
if ( ! empty( $sidebars_widgets ) )
|
||||
$_sidebars_widgets[$id] = array_shift( $sidebars_widgets );
|
||||
}
|
||||
|
||||
if ( !empty($sidebars_widgets) ) {
|
||||
$orphaned = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue