WordPress.org

Make WordPress Core

Changeset 18630


Ignore:
Timestamp:
09/02/11 22:13:55 (6 years ago)
Author:
azaozz
Message:

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

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/widgets.php

    r18577 r18630  
    4545add_contextual_help($current_screen, $help); 
    4646 
     47// These are the widgets grouped by sidebar 
     48$sidebars_widgets = wp_get_sidebars_widgets(); 
     49 
     50if ( empty( $sidebars_widgets ) ) 
     51    $sidebars_widgets = wp_get_widget_defaults(); 
     52 
    4753// register the inactive_widgets area as sidebar 
    4854register_sidebar(array( 
    4955    'name' => __('Inactive Widgets'), 
    5056    'id' => 'wp_inactive_widgets', 
     57    'class' => 'inactive', 
    5158    'description' => '', 
    5259    'before_widget' => '', 
     
    5663)); 
    5764 
    58 // These are the widgets grouped by sidebar 
    59 $sidebars_widgets = wp_get_sidebars_widgets(); 
    60 if ( empty( $sidebars_widgets ) ) 
    61     $sidebars_widgets = wp_get_widget_defaults(); 
    62  
    63 // look for "lost" widgets, this has to run at least on each theme change 
    64 function retrieve_widgets() { 
    65     global $wp_registered_widget_updates, $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets; 
    66  
    67     $_sidebars_widgets = array(); 
    68     $sidebars = array_keys($wp_registered_sidebars); 
    69  
    70     unset( $sidebars_widgets['array_version'] ); 
    71  
    72     $old = array_keys($sidebars_widgets); 
    73     sort($old); 
    74     sort($sidebars); 
    75  
    76     if ( $old == $sidebars ) 
    77         return; 
    78  
    79     // Move the known-good ones first 
    80     foreach ( $sidebars as $id ) { 
    81         if ( array_key_exists( $id, $sidebars_widgets ) ) { 
    82             $_sidebars_widgets[$id] = $sidebars_widgets[$id]; 
    83             unset($sidebars_widgets[$id], $sidebars[$id]); 
    84         } 
    85     } 
    86  
    87     // if new theme has less sidebars than the old theme 
    88     if ( !empty($sidebars_widgets) ) { 
    89         foreach ( $sidebars_widgets as $lost => $val ) { 
    90             if ( is_array($val) ) 
    91                 $_sidebars_widgets['wp_inactive_widgets'] = array_merge( (array) $_sidebars_widgets['wp_inactive_widgets'], $val ); 
    92         } 
    93     } 
    94  
    95     // discard invalid, theme-specific widgets from sidebars 
    96     $shown_widgets = array(); 
    97     foreach ( $_sidebars_widgets as $sidebar => $widgets ) { 
    98         if ( !is_array($widgets) ) 
    99             continue; 
    100  
    101         $_widgets = array(); 
    102         foreach ( $widgets as $widget ) { 
    103             if ( isset($wp_registered_widgets[$widget]) ) 
    104                 $_widgets[] = $widget; 
    105         } 
    106         $_sidebars_widgets[$sidebar] = $_widgets; 
    107         $shown_widgets = array_merge($shown_widgets, $_widgets); 
    108     } 
    109  
    110     $sidebars_widgets = $_sidebars_widgets; 
    111     unset($_sidebars_widgets, $_widgets); 
    112  
    113     // find hidden/lost multi-widget instances 
    114     $lost_widgets = array(); 
    115     foreach ( $wp_registered_widgets as $key => $val ) { 
    116         if ( in_array($key, $shown_widgets, true) ) 
    117             continue; 
    118  
    119         $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key); 
    120  
    121         if ( 2 > (int) $number ) 
    122             continue; 
    123  
    124         $lost_widgets[] = $key; 
    125     } 
    126  
    127     $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']); 
    128     wp_set_sidebars_widgets($sidebars_widgets); 
    129 } 
     65foreach ( $sidebars_widgets as $sidebar_id => $widgets ) { 
     66    if ( empty( $wp_registered_sidebars[ $sidebar_id ] ) && ! empty( $widgets ) ) { 
     67        // register the inactive_widgets area as sidebar 
     68        register_sidebar(array( 
     69            'name' => __( 'Inactive Widgets (Previous Theme)' ), 
     70            'id' => $sidebar_id, 
     71            'class' => 'orphaned', 
     72            'description' => __( 'This is a left over sidebar from an old theme and does not show anywhere on your site' ), 
     73            'before_widget' => '', 
     74            'after_widget' => '', 
     75            'before_title' => '', 
     76            'after_title' => '', 
     77        )); 
     78    } 
     79} 
     80 
    13081retrieve_widgets(); 
    13182 
     
    388339    if ( 'wp_inactive_widgets' == $sidebar ) 
    389340        continue; 
    390     $closed = $i ? ' closed' : ''; ?> 
    391     <div class="widgets-holder-wrap<?php echo $closed; ?>"> 
     341 
     342    $wrap_class = 'widgets-holder-wrap'; 
     343    if ( !empty( $registered_sidebar['class'] ) ) 
     344        $wrap_class .= ' sidebar-' . $registered_sidebar['class']; 
     345 
     346    if ( $i ) 
     347        $wrap_class .= ' closed'; ?> 
     348 
     349    <div class="<?php esc_attr_e( $wrap_class ); ?>"> 
    392350    <div class="sidebar-name"> 
    393351    <div class="sidebar-name-arrow"><br /></div> 
  • trunk/wp-includes/default-filters.php

    r18617 r18630  
    219219add_action( 'template_redirect',   'wp_shortlink_header',             11, 0 ); 
    220220add_action( 'wp_print_footer_scripts', '_wp_footer_scripts'                 ); 
     221add_action( 'init',                'check_theme_switched',            99    ); 
    221222 
    222223if ( isset( $_GET['replytocom'] ) ) 
  • trunk/wp-includes/theme.php

    r18325 r18630  
    12491249    global $wp_theme_directories; 
    12501250 
     1251    $old_theme = get_current_theme(); 
     1252 
    12511253    update_option('template', $template); 
    12521254    update_option('stylesheet', $stylesheet); 
     1255 
    12531256    if ( count($wp_theme_directories) > 1 ) { 
    12541257        update_option('template_root', get_raw_theme_root($template, true)); 
    12551258        update_option('stylesheet_root', get_raw_theme_root($stylesheet, true)); 
    12561259    } 
     1260 
    12571261    delete_option('current_theme'); 
    12581262    $theme = get_current_theme(); 
     1263 
    12591264    if ( is_admin() && false === get_option( "theme_mods_$stylesheet" ) ) { 
    12601265        $default_theme_mods = (array) get_option( "mods_$theme" ); 
    12611266        add_option( "theme_mods_$stylesheet", $default_theme_mods ); 
    12621267    } 
    1263     do_action('switch_theme', $theme); 
     1268 
     1269    update_option( 'theme_switched', $old_theme ); 
     1270    do_action( 'switch_theme', $theme ); 
    12641271} 
    12651272 
  • trunk/wp-includes/widgets.php

    r18532 r18630  
    548548        'id' => "sidebar-$i", 
    549549        'description' => '', 
     550        'class' => '', 
    550551        'before_widget' => '<li id="%1$s" class="widget %2$s">', 
    551552        'after_widget' => "</li>\n", 
     
    10561057 
    10571058            case 2 : 
    1058                 $sidebars = array_keys( $wp_registered_sidebars ); 
    1059                 if ( !empty( $sidebars ) ) { 
    1060                     // Move the known-good ones first 
    1061                     foreach ( (array) $sidebars as $id ) { 
    1062                         if ( array_key_exists( $id, $sidebars_widgets ) ) { 
    1063                             $_sidebars_widgets[$id] = $sidebars_widgets[$id]; 
    1064                             unset($sidebars_widgets[$id], $sidebars[$id]); 
    1065                         } 
    1066                     } 
    1067  
    1068                     // move the rest to wp_inactive_widgets 
    1069                     if ( !isset($_sidebars_widgets['wp_inactive_widgets']) ) 
    1070                         $_sidebars_widgets['wp_inactive_widgets'] = array(); 
    1071  
    1072                     if ( !empty($sidebars_widgets) ) { 
    1073                         foreach ( $sidebars_widgets as $lost => $val ) { 
    1074                             if ( is_array($val) ) 
    1075                                 $_sidebars_widgets['wp_inactive_widgets'] = array_merge( (array) $_sidebars_widgets['wp_inactive_widgets'], $val ); 
    1076                         } 
    1077                     } 
    1078  
    1079                     $sidebars_widgets = $_sidebars_widgets; 
    1080                     unset($_sidebars_widgets); 
    1081                 } 
     1059                $sidebars_widgets = retrieve_widgets(); 
    10821060        } 
    10831061    } 
     
    12161194    return preg_replace( '/-[0-9]+$/', '', $id ); 
    12171195} 
     1196 
     1197function check_theme_switched() { 
     1198    if ( false !== ( $old_theme = get_option( 'theme_switched' ) ) && !empty( $old_theme ) ) { 
     1199        global $sidebars_widgets; 
     1200 
     1201        if ( ! is_array( $sidebars_widgets ) ) 
     1202            $sidebars_widgets = wp_get_sidebars_widgets(); 
     1203 
     1204        $key = md5( $old_theme ); 
     1205        // Store widgets for 1 week so we can restore if needed 
     1206        set_transient( 'old_widgets_' . $key, $sidebars_widgets, 604800 ); 
     1207 
     1208        retrieve_widgets(); 
     1209        update_option( 'theme_switched', false ); 
     1210    } 
     1211} 
     1212 
     1213// look for "lost" widgets, this has to run at least on each theme change 
     1214function retrieve_widgets() { 
     1215    global $wp_registered_widget_updates, $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets; 
     1216 
     1217    $key = md5( get_current_theme() ); 
     1218    if ( false !== ( $_sidebars_widgets = get_transient( "old_widgets_{$key}" ) ) ) { 
     1219        delete_transient( "old_widgets_{$key}" ); 
     1220    } else { 
     1221        if ( ! is_array( $sidebars_widgets ) ) 
     1222            $sidebars_widgets = wp_get_sidebars_widgets(); 
     1223 
     1224        $sidebars = array_keys($wp_registered_sidebars); 
     1225 
     1226        unset( $sidebars_widgets['array_version'] ); 
     1227 
     1228        $old = array_keys($sidebars_widgets); 
     1229        sort($old); 
     1230        sort($sidebars); 
     1231 
     1232        if ( $old == $sidebars ) 
     1233            return; 
     1234 
     1235        $_sidebars_widgets = array( 
     1236            'wp_inactive_widgets' => $sidebars_widgets['wp_inactive_widgets'] 
     1237        ); 
     1238 
     1239        unset( $sidebars_widgets['wp_inactive_widgets'] ); 
     1240 
     1241        foreach ( $wp_registered_sidebars as $id => $settings ) { 
     1242            if ( ! empty( $sidebars_widgets ) ) 
     1243                $_sidebars_widgets[$id] = array_shift( $sidebars_widgets ); 
     1244        } 
     1245 
     1246        if ( !empty($sidebars_widgets) ) { 
     1247            $orphaned = 0; 
     1248 
     1249            foreach ( $sidebars_widgets as $val ) { 
     1250                if ( is_array($val) && ! empty( $val ) ) 
     1251                    $_sidebars_widgets['orphaned_widgets_' . ++$orphaned] = $val; 
     1252            } 
     1253        } 
     1254    } 
     1255 
     1256    // discard invalid, theme-specific widgets from sidebars 
     1257    $shown_widgets = array(); 
     1258 
     1259    foreach ( $_sidebars_widgets as $sidebar => $widgets ) { 
     1260        if ( !is_array($widgets) ) 
     1261            continue; 
     1262 
     1263        $_widgets = array(); 
     1264        foreach ( $widgets as $widget ) { 
     1265            if ( isset($wp_registered_widgets[$widget]) ) 
     1266                $_widgets[] = $widget; 
     1267        } 
     1268 
     1269        $_sidebars_widgets[$sidebar] = $_widgets; 
     1270        $shown_widgets = array_merge($shown_widgets, $_widgets); 
     1271    } 
     1272 
     1273    $sidebars_widgets = $_sidebars_widgets; 
     1274    unset($_sidebars_widgets, $_widgets); 
     1275 
     1276    // find hidden/lost multi-widget instances 
     1277    $lost_widgets = array(); 
     1278    foreach ( $wp_registered_widgets as $key => $val ) { 
     1279        if ( in_array($key, $shown_widgets, true) ) 
     1280            continue; 
     1281 
     1282        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key); 
     1283 
     1284        if ( 2 > (int) $number ) 
     1285            continue; 
     1286 
     1287        $lost_widgets[] = $key; 
     1288    } 
     1289 
     1290    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']); 
     1291    wp_set_sidebars_widgets($sidebars_widgets); 
     1292 
     1293    return $sidebars_widgets; 
     1294} 
Note: See TracChangeset for help on using the changeset viewer.