WordPress.org

Make WordPress Core

Changeset 11427


Ignore:
Timestamp:
05/22/2009 12:08:51 PM (10 years ago)
Author:
azaozz
Message:

Fix saving and deleting of widgets settings for no-js and for some non-standard widgets, run the actions from the widgets screen when saving with ajax, see #9511

Location:
trunk
Files:
5 edited

Legend:

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

    r11401 r11427  
    12831283    unset( $_POST['savewidgets'], $_POST['action'] );
    12841284
     1285    do_action('load-widgets.php');
     1286    do_action('widgets.php');
     1287    do_action('sidebar_admin_setup');
     1288
    12851289    $id_base = $_POST['id_base'];
    1286     $number = isset($_POST['widget_number']) ? $_POST['widget_number'] : '';
     1290    $widget_id = $_POST['widget-id'];
    12871291    $sidebar_id = $_POST['sidebar'];
     1292
    12881293    $sidebars = wp_get_sidebars_widgets();
    12891294    $sidebar = isset($sidebars[$sidebar_id]) ? $sidebars[$sidebar_id] : array();
     
    12911296    // delete
    12921297    if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
    1293         $del_id = $_POST['widget-id'];
    1294         $widget = isset($wp_registered_widgets[$del_id]) ? $wp_registered_widgets[$del_id] : false;
    1295 
    1296         if ( !in_array($del_id, $sidebar, true) )
     1298
     1299        if ( !isset($wp_registered_widgets[$widget_id]) )
    12971300            die('-1');
    12981301
    1299         if ( $widget ) {
    1300             $option = str_replace( '-', '_', 'widget_' . $id_base );
    1301             $data = get_option($option);
    1302 
    1303             if ( isset($widget['params'][0]['number']) ) {
    1304                 $number = $widget['params'][0]['number'];
    1305                 if ( is_array($data) && isset($data[$number]) ) {
    1306                     unset( $data[$number] );
    1307                     update_option($option, $data);
    1308                 }
    1309             } else {
    1310                 if ( $data ) {
    1311                     $data = array();
    1312                     update_option($option, $data);
    1313                 }
    1314             }
    1315         }
    1316 
    1317         $sidebar = array_diff( $sidebar, array($del_id) );
    1318         $sidebars[$sidebar_id] = $sidebar;
    1319         wp_set_sidebars_widgets($sidebars);
    1320 
    1321         echo "deleted:$del_id";
    1322         die();
    1323     }
    1324 
    1325     // save
     1302        $sidebar = array_diff( $sidebar, array($widget_id) );
     1303        $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1');
     1304    }
     1305    $_POST['widget-id'] = $sidebar;
     1306
    13261307    foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
     1308
    13271309        if ( $name == $id_base ) {
    13281310            if ( !is_callable( $control['callback'] ) )
    13291311                continue;
    1330 
    1331             if ( $number ) {
    1332                 // don't delete other instances of the same multi-widget
    1333                 foreach ( $sidebar as $_widget_id ) {
    1334                     $_widget = $wp_registered_widgets[$_widget_id];
    1335 
    1336                     if ( isset($_widget['params']) &&
    1337                         is_array($_widget['params'][0]) &&
    1338                         array_key_exists('number', $_widget['params'][0]) )
    1339                             unset($wp_registered_widgets[$_widget_id]['params'][0]['number']);
    1340                 }
    1341             }
    13421312
    13431313            ob_start();
     
    13481318    }
    13491319
     1320    if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
     1321        $sidebars[$sidebar_id] = $sidebar;
     1322        wp_set_sidebars_widgets($sidebars);
     1323        echo "deleted:$widget_id";
     1324        die();
     1325    }
     1326   
    13501327    die('1');
    13511328    break;
  • trunk/wp-admin/css/widgets.css

    r11246 r11427  
    241241    font-size: 11px;
    242242    font-weight: normal;
    243     line-height: 24px;
     243    line-height: 26px;
    244244    padding: 0 8px 0 0;
    245245}
     
    257257#widgets-right .widget-control-edit .edit,
    258258#wp_inactive_widgets .widget-control-edit .edit {
    259     display: block;
     259    display: inline;
    260260}
    261261
  • trunk/wp-admin/widgets.php

    r11380 r11427  
    4848    unset( $sidebars_widgets['array_version'] );
    4949
    50     $diff = array_diff( array_keys($sidebars_widgets), $sidebars );
    51     if ( empty($diff) )
     50    $old = array_keys($sidebars_widgets);
     51    sort($old);
     52    sort($sidebars);
     53
     54    if ( $old == $sidebars )
    5255        return;
    5356
     
    6972   
    7073    // discard invalid, theme-specific widgets from sidebars
     74    $shown_widgets = array();
    7175    foreach ( $_sidebars_widgets as $sidebar => $widgets ) {
    7276        if ( !is_array($widgets) )
     
    7983        }
    8084        $_sidebars_widgets[$sidebar] = $_widgets;
     85        $shown_widgets = array_merge($shown_widgets, $_widgets);
    8186    }
    8287
     
    8590
    8691    // find hidden/lost multi-widget instances
    87     $shown_widgets = array();
    88     foreach ( $sidebars_widgets as $sidebar ) {
    89         if ( is_array($sidebar) )
    90             $shown_widgets = array_merge($shown_widgets, $sidebar);
    91     }
    92 
    93     $all_widgets = array();
    94     foreach ( $wp_registered_widget_updates as $key => $val ) {
    95         if ( isset($val['id_base']) )
    96             $all_widgets[] = $val['id_base'];
    97         else
    98             $all_widgets[] = $key;
    99     }
    100 
    101     $all_widgets = array_unique($all_widgets);
    102 
    10392    $lost_widgets = array();
    104     foreach ( $all_widgets as $name ) {
    105         $data = get_option( str_replace('-', '_', "widget_$name") );
    106         if ( is_array($data) ) {
    107             foreach ( $data as $num => $value ) {
    108                 if ( !is_numeric($num) ) // skip single widgets, some don't delete their settings
    109                     continue;
    110                 if ( is_array($value) && !in_array("$name-$num", $shown_widgets, true) )
    111                     $lost_widgets[] = "$name-$num";
    112             }
    113         }
     93    foreach ( $wp_registered_widgets as $key => $val ) {
     94        if ( in_array($key, $shown_widgets, true) )
     95            continue;
     96
     97        $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key);
     98
     99        if ( 2 > (int) $number )
     100            continue;
     101
     102        $lost_widgets[] = $key;
    114103    }
    115104
     
    143132    check_admin_referer("save-delete-widget-$widget_id");
    144133
    145     $sidebar_id = $_POST['insidebar'];
     134    $number = isset($_POST['multi_number']) ? (int) $_POST['multi_number'] : '';
     135    if ( $number ) {
     136        foreach ( $_POST as $key => $val ) {
     137            if ( is_array($val) && preg_match('/__i__|%i%/', key($val)) ) {
     138                $_POST[$key] = array( $number => array_shift($val) );
     139                break;
     140            }
     141        }
     142    }
     143
     144    $sidebar_id = $_POST['sidebar'];
    146145    $position = isset($_POST[$sidebar_id . '_position']) ? (int) $_POST[$sidebar_id . '_position'] - 1 : 0;
    147     $_POST['sidebar'] = $sidebar_id;
    148146
    149147    $id_base = $_POST['id_base'];
    150     $number = isset($_POST['multi_number']) ? $_POST['multi_number'] : '';
    151148    $sidebar = isset($sidebars_widgets[$sidebar_id]) ? $sidebars_widgets[$sidebar_id] : array();
    152149
    153150    // delete
    154151    if ( isset($_POST['removewidget']) && $_POST['removewidget'] ) {
    155         $widget = isset($wp_registered_widgets[$widget_id]) ? $wp_registered_widgets[$widget_id] : false;
    156 
    157         if ( !in_array($widget_id, $sidebar, true) || !$widget ) {
     152
     153        if ( !in_array($widget_id, $sidebar, true) ) {
    158154            wp_redirect('widgets.php?error=0');
    159155            exit;
    160156        }
    161157
    162         $option = str_replace( '-', '_', 'widget_' . $id_base );
    163         $data = get_option($option);
    164 
    165         if ( isset($widget['params'][0]['number']) ) {
    166             $number = $widget['params'][0]['number'];
    167             if ( is_array($data) && isset($data[$number]) ) {
    168                 unset( $data[$number] );
    169                 update_option($option, $data);
    170             }
    171         } else {
    172             if ( $data ) {
    173                 $data = array();
    174                 update_option($option, $data);
    175             }
    176         }
    177 
    178158        $sidebar = array_diff( $sidebar, array($widget_id) );
    179     } else {
    180         // save
    181         foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
    182             if ( $name != $id_base || !is_callable($control['callback']) )
    183                 continue;
    184 
    185             if ( $number ) {
    186                 // don't delete other instances of the same multi-widget
    187                 foreach ( $sidebar as $_widget_id ) {
    188                     if ( isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) )
    189                         unset($wp_registered_widgets[$_widget_id]['params'][0]['number']);
    190                 }
    191                 $widget_id = "$id_base-$number";
    192             }
    193 
    194             ob_start();
    195                 call_user_func_array( $control['callback'], $control['params'] );
    196             ob_end_clean();
    197 
    198             // remove old position
    199             $sidebar = array_diff( $sidebar, array($widget_id) );
    200             foreach ( $sidebars_widgets as $key => $sb ) {
    201                 if ( is_array($sb) && in_array($widget_id, $sb, true) )
    202                     $sidebars_widgets[$key] = array_diff( $sb, array($widget_id) );
    203             }
    204 
    205             array_splice( $sidebar, $position, 0, $widget_id );
    206             break;
    207         }
     159        $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1');
     160    }
     161
     162    $_POST['widget-id'] = $sidebar;
     163
     164    foreach ( (array) $wp_registered_widget_updates as $name => $control ) {
     165        if ( $name != $id_base || !is_callable($control['callback']) )
     166            continue;
     167
     168        ob_start();
     169            call_user_func_array( $control['callback'], $control['params'] );
     170        ob_end_clean();
     171
     172        break;
    208173    }
    209174
    210175    $sidebars_widgets[$sidebar_id] = $sidebar;
     176
     177    // remove old position
     178    if ( !isset($_POST['delete_widget']) ) {
     179        foreach ( $sidebars_widgets as $key => $sb ) {
     180            if ( is_array($sb) )
     181                $sidebars_widgets[$key] = array_diff( $sb, array($widget_id) );
     182        }
     183        array_splice( $sidebars_widgets[$sidebar_id], $position, 0, $widget_id );
     184    }
     185
    211186    wp_set_sidebars_widgets($sidebars_widgets);
    212 
    213187    wp_redirect('widgets.php?message=0');
    214188    exit;
     
    229203                    $control_callback = $control['callback'];
    230204                    $multi_number = (int) $_GET['num'];
    231                     $control['params'][0]['number'] = $multi_number;
    232                     $control['id'] = $control['id_base'] . '-' . $multi_number;
     205                    $control['params'][0]['number'] = -1;
     206                    $widget_id = $control['id'] = $control['id_base'] . '-' . $multi_number;
    233207                    $wp_registered_widget_controls[$control['id']] = $control;
    234208                    break;
     
    241215        $control = $wp_registered_widget_controls[$widget_id];
    242216        $control_callback = $control['callback'];
    243     }
    244 
     217    } elseif ( !isset($wp_registered_widget_controls[$widget_id]) && isset($wp_registered_widgets[$widget_id]) ) {
     218        $name = esc_html( strip_tags($wp_registered_widgets[$widget_id]['name']) );
     219    }
     220
     221    if ( !isset($name) )
     222        $name = esc_html( strip_tags($control['name']) );
     223   
    245224    if ( !isset($sidebar) )
    246225        $sidebar = isset($_GET['sidebar']) ? $_GET['sidebar'] : 'wp_inactive_widgets';
     
    252231
    253232    // show the widget form
    254     if ( is_callable( $control_callback ) ) {
    255         $width = ' style="width:' . max($control['width'], 350) . 'px"';
    256         $key = isset($_GET['key']) ? (int) $_GET['key'] : 0;
    257 
    258         require_once( 'admin-header.php' ); ?>
    259         <div class="wrap">
    260         <?php screen_icon(); ?>
    261         <h2><?php echo esc_html( $title ); ?></h2>
    262         <div class="editwidget"<?php echo $width; ?>>
    263         <h3><?php printf( __( 'Widget %s' ), esc_html( strip_tags($control['name']) ) ); ?></h3>
    264 
    265         <form action="widgets.php" method="post">
    266         <div class="widget-inside">
    267 <?php   call_user_func_array( $control_callback, $control['params'] ); ?>
    268         </div>
    269 
    270         <p class="describe"><?php _e('Select both the sidebar for this widget and the position of the widget in that sidebar.'); ?></p>
    271         <div class="widget-position">
    272         <table class="widefat"><thead><tr><th><?php _e('Sidebar'); ?></th><th><?php _e('Position'); ?></th></tr></thead><tbody>
     233    $width = ' style="width:' . max($control['width'], 350) . 'px"';
     234    $key = isset($_GET['key']) ? (int) $_GET['key'] : 0;
     235
     236    require_once( 'admin-header.php' ); ?>
     237    <div class="wrap">
     238    <?php screen_icon(); ?>
     239    <h2><?php echo esc_html( $title ); ?></h2>
     240    <div class="editwidget"<?php echo $width; ?>>
     241    <h3><?php printf( __( 'Widget %s' ), $name ); ?></h3>
     242
     243    <form action="widgets.php" method="post">
     244    <div class="widget-inside">
     245<?php   
     246    if ( is_callable( $control_callback ) )
     247        call_user_func_array( $control_callback, $control['params'] );
     248    else
     249        echo '<p>' . __('There are no options for this widget.') . "</p>\n"; ?>
     250    </div>
     251
     252    <p class="describe"><?php _e('Select both the sidebar for this widget and the position of the widget in that sidebar.'); ?></p>
     253    <div class="widget-position">
     254    <table class="widefat"><thead><tr><th><?php _e('Sidebar'); ?></th><th><?php _e('Position'); ?></th></tr></thead><tbody>
    273255<?php   foreach ( $wp_registered_sidebars as $sbname => $sbvalue ) {
    274             echo "\t\t<tr><td><label><input type='radio' name='insidebar' value='" . esc_attr($sbname) . "'" . checked( $sbname, $sidebar, false ) . " /> $sbvalue[name]</label></td><td>";
    275             if ( 'wp_inactive_widgets' == $sbname ) {
    276                 echo '&nbsp;';
     256        echo "\t\t<tr><td><label><input type='radio' name='sidebar' value='" . esc_attr($sbname) . "'" . checked( $sbname, $sidebar, false ) . " /> $sbvalue[name]</label></td><td>";
     257        if ( 'wp_inactive_widgets' == $sbname ) {
     258            echo '&nbsp;';
     259        } else {
     260            if ( !isset($sidebars_widgets[$sbname]) || !is_array($sidebars_widgets[$sbname]) ) {
     261                $j = 1;
    277262            } else {
    278                 if ( !isset($sidebars_widgets[$sbname]) || !is_array($sidebars_widgets[$sbname]) ) {
    279                     $j = 1;
    280                 } else {
    281                     $j = count($sidebars_widgets[$sbname]);
    282                     if ( isset($_GET['addnew']) || !in_array($widget_id, $sidebars_widgets[$sbname], true) )
    283                         $j++;
    284                 }
    285                 $selected = '';
    286                 echo "\t\t<select name='{$sbname}_position'>\n";
    287                 echo "\t\t<option value=''>" . __('-- select --') . "</option>\n";
    288                 for ( $i = 1; $i <= $j; $i++ ) {
    289                     if ( in_array($widget_id, $sidebars_widgets[$sbname], true) )
    290                         $selected = selected( $i, $key + 1, false );
    291                     echo "\t\t<option value='$i'$selected> $i </option>\n";
    292                 }
    293                 echo "\t\t</select>\n";
     263                $j = count($sidebars_widgets[$sbname]);
     264                if ( isset($_GET['addnew']) || !in_array($widget_id, $sidebars_widgets[$sbname], true) )
     265                    $j++;
    294266            }
    295             echo "</td></tr>\n";
    296         } ?>
    297         </tbody></table>
    298         </div>
    299 
    300         <div class="widget-control-actions">
     267            $selected = '';
     268            echo "\t\t<select name='{$sbname}_position'>\n";
     269            echo "\t\t<option value=''>" . __('-- select --') . "</option>\n";
     270            for ( $i = 1; $i <= $j; $i++ ) {
     271                if ( in_array($widget_id, $sidebars_widgets[$sbname], true) )
     272                    $selected = selected( $i, $key + 1, false );
     273                echo "\t\t<option value='$i'$selected> $i </option>\n";
     274            }
     275            echo "\t\t</select>\n";
     276        }
     277        echo "</td></tr>\n";
     278    } ?>
     279    </tbody></table>
     280    </div>
     281
     282    <div class="widget-control-actions">
    301283<?php   if ( isset($_GET['addnew']) ) { ?>
    302         <a href="widgets.php" class="button alignleft"><?php _e('Cancel'); ?></a>
     284    <a href="widgets.php" class="button alignleft"><?php _e('Cancel'); ?></a>
    303285<?php   } else { ?>
    304         <input type="submit" name="removewidget" class="button alignleft" value="<?php esc_attr_e('Remove'); ?>" />
     286    <input type="submit" name="removewidget" class="button alignleft" value="<?php esc_attr_e('Remove'); ?>" />
    305287<?php   } ?>
    306         <input type="submit" name="savewidget" class="button-primary alignright" value="<?php esc_attr_e('Save Widget'); ?>" />
    307         <input type="hidden" name="widget-id" class="widget-id" value="<?php echo esc_attr($widget_id); ?>" />
    308         <input type="hidden" name="id_base" class="id_base" value="<?php echo esc_attr($id_base); ?>" />
    309         <input type="hidden" name="multi_number" class="multi_number" value="<?php echo esc_attr($multi_number); ?>" />
     288    <input type="submit" name="savewidget" class="button-primary alignright" value="<?php esc_attr_e('Save Widget'); ?>" />
     289    <input type="hidden" name="widget-id" class="widget-id" value="<?php echo esc_attr($widget_id); ?>" />
     290    <input type="hidden" name="id_base" class="id_base" value="<?php echo esc_attr($id_base); ?>" />
     291    <input type="hidden" name="multi_number" class="multi_number" value="<?php echo esc_attr($multi_number); ?>" />
    310292<?php   wp_nonce_field("save-delete-widget-$widget_id"); ?>
    311         <br class="clear" />
    312         </div>
    313         </form>
    314         </div>
    315         </div>
    316 <?php
    317         require_once( 'admin-footer.php' );
    318         exit;
    319     }
    320     wp_redirect('widgets.php?error=1');
     293    <br class="clear" />
     294    </div>
     295    </form>
     296    </div>
     297    </div>
     298<?php
     299    require_once( 'admin-footer.php' );
    321300    exit;
    322301}
  • trunk/wp-includes/default-widgets.php

    r11383 r11427  
    760760
    761761        if ( empty($instance) )
    762             $instance = array( 'number' => '__i__', 'title' => '', 'url' => '', 'items' => 10, 'error' => false, 'show_summary' => 0, 'show_author' => 0, 'show_date' => 0 );
    763         else
    764             $instance['number'] = $this->number;
     762            $instance = array( 'title' => '', 'url' => '', 'items' => 10, 'error' => false, 'show_summary' => 0, 'show_author' => 0, 'show_date' => 0 );
     763        $instance['number'] = $this->number;
    765764
    766765        wp_widget_rss_form( $instance );
  • trunk/wp-includes/widgets.php

    r11380 r11427  
    192192
    193193        // We need to update the data
    194         if ( !$this->updated && !empty($_POST['sidebar']) ) {
    195 
    196             // Tells us what sidebar to put the data in
    197             $sidebar = (string) $_POST['sidebar'];
    198 
    199             $sidebars_widgets = wp_get_sidebars_widgets();
    200             if ( isset($sidebars_widgets[$sidebar]) )
    201                 $this_sidebar =& $sidebars_widgets[$sidebar];
     194        if ( $this->updated )
     195            return;
     196
     197        $sidebars_widgets = wp_get_sidebars_widgets();
     198
     199        if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
     200            // Delete the settings for this instance of the widget
     201            if ( isset($_POST['the-widget-id']) )
     202                $del_id = $_POST['the-widget-id'];
    202203            else
    203                 $this_sidebar = array();
    204 
    205             if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) {
    206                 // Delete the settings for this instance of the widget
    207                 if ( isset($_POST['widget-id']) )
    208                     $del_id = $_POST['widget-id'];
     204                return;
     205
     206            if ( isset($wp_registered_widgets[$del_id]['params'][0]['number']) ) {
     207                $number = $wp_registered_widgets[$del_id]['params'][0]['number'];
     208
     209                if ( $this->id_base . '-' . $number == $del_id )
     210                    unset($all_instances[$number]);
     211            }
     212        } else {
     213            if ( isset($_POST['widget-' . $this->id_base]) && is_array($_POST['widget-' . $this->id_base]) ) {
     214                $settings = $_POST['widget-' . $this->id_base];
     215            } elseif ( isset($_POST['id_base']) && $_POST['id_base'] == $this->id_base ) {
     216                $num = $_POST['multi_number'] ? (int) $_POST['multi_number'] : (int) $_POST['widget_number'];
     217                $settings = array( $num => array() );
     218            } else {
     219                return;
     220            }
     221
     222            foreach ( $settings as $number => $new_instance ) {
     223                $new_instance = stripslashes_deep($new_instance);
     224                $this->_set($number);
     225
     226                if ( isset($all_instances[$number]) )
     227                    $instance = $this->update($new_instance, $all_instances[$number]);
    209228                else
    210                     return;
    211 
    212                 if ( $this->_get_display_callback() == $wp_registered_widgets[$del_id]['callback'] && isset($wp_registered_widgets[$del_id]['params'][0]['number']) ) {
    213                     $number = $wp_registered_widgets[$del_id]['params'][0]['number'];
    214 
    215                     if ( $this->id_base . '-' . $number == $del_id ) {
    216                         unset($all_instances[$number]);
    217                     }
    218                 }
    219             } else {
    220                 if ( isset($_POST['widget-' . $this->id_base]) && is_array($_POST['widget-' . $this->id_base]) ) {
    221                     $settings = $_POST['widget-' . $this->id_base];
    222                 } else {
    223                     $num = $_POST['multi_number'] ? (int) $_POST['multi_number'] : (int) $_POST['widget_number'];
    224                     $settings = array( $num => array() );
    225                 }
    226 
    227                 foreach ( $settings as $number => $new_instance ) {
    228                     $new_instance = stripslashes_deep($new_instance);
    229                     $this->_set($number);
    230 
    231                     if ( isset($all_instances[$number]) )
    232                         $instance = $this->update($new_instance, $all_instances[$number]);
    233                     else
    234                         $instance = $this->update($new_instance, array());
    235 
    236                     // filters the widget's settings before saving, return false to cancel saving (keep the old settings if updating)
    237                     $instance = apply_filters('widget_update_callback', $instance, $new_instance, $this);
    238                     if ( false !== $instance )
    239                         $all_instances[$number] = $instance;
    240                 }
     229                    $instance = $this->update($new_instance, array());
     230
     231                // filters the widget's settings before saving, return false to cancel saving (keep the old settings if updating)
     232                $instance = apply_filters('widget_update_callback', $instance, $new_instance, $this);
     233                if ( false !== $instance )
     234                    $all_instances[$number] = $instance;
     235
     236                break; // run only once
    241237            }
    242 
    243             $this->save_settings($all_instances);
    244             $this->updated = true;
    245         }
     238        }
     239
     240        $this->save_settings($all_instances);
     241        $this->updated = true;
    246242    }
    247243
Note: See TracChangeset for help on using the changeset viewer.