Ticket #5583: 5583.diff

File 5583.diff, 82.8 KB (added by mdawaffe, 4 years ago)

big

  • wp-includes/widgets.php

     
    22 
    33/* Global Variables */ 
    44 
    5 global $wp_registered_sidebars, $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_widget_styles, $wp_registered_widget_defaults; 
     5global $wp_registered_sidebars, $wp_registered_widgets, $wp_registered_widget_controls; 
    66 
    77$wp_registered_sidebars = array(); 
    88$wp_registered_widgets = array(); 
    99$wp_registered_widget_controls = array(); 
    10 $wp_registered_widget_styles = array(); 
    11 $wp_register_widget_defaults = false; 
    1210 
    1311/* Template tags & API functions */ 
    1412 
     
    9593} 
    9694 
    9795function wp_register_sidebar_widget($id, $name, $output_callback, $options = array()) { 
     96        global $wp_registered_widgets; 
    9897 
    99         global $wp_registered_widgets, $wp_register_widget_defaults; 
    100  
    10198        if ( empty($output_callback) ) { 
    10299                unset($wp_registered_widgets[$id]); 
    103100                return; 
     
    113110        ); 
    114111        $widget = array_merge($widget, $options); 
    115112 
    116         if ( is_callable($output_callback) && ( !isset($wp_registered_widgets[$id]) || !$wp_register_widget_defaults) ) 
     113        if ( is_callable($output_callback) && ( !isset($wp_registered_widgets[$id]) || did_action( 'widgets_init' ) ) ) 
    117114                $wp_registered_widgets[$id] = $widget; 
    118115} 
    119116 
     117function wp_widget_description( $id ) { 
     118        if ( !is_scalar($id) ) 
     119                return; 
     120 
     121        global $wp_registered_widgets; 
     122 
     123        if ( isset($wp_registered_widgets[$id]['description']) ) 
     124                return wp_specialchars( $wp_registered_widgets[$id]['description'] ); 
     125} 
     126 
    120127function unregister_sidebar_widget($id) { 
    121128        return wp_unregister_sidebar_widget($id); 
    122129} 
     
    149156        call_user_func_array('wp_register_widget_control', $args); 
    150157} 
    151158 
     159/* $options: height, width, id_base 
     160 *   height: never used 
     161 *   width:  width of fully expanded control form.  Try hard to use the default width. 
     162 *   id_base: for widgets which allow multiple instances (such as the text widget), an id_base must be provided. 
     163 *            the widget id will ennd up looking like {$id_base}-{$unique_number} 
     164 */ 
    152165function wp_register_widget_control($id, $name, $control_callback, $options = array()) { 
    153         global $wp_registered_widget_controls, $wp_register_widget_defaults; 
     166        global $wp_registered_widget_controls; 
    154167 
    155168        if ( empty($control_callback) ) { 
    156169                unset($wp_registered_widget_controls[$id]); 
    157170                return; 
    158171        } 
    159172 
    160         if ( isset($wp_registered_widget_controls[$id]) && $wp_register_widget_defaults ) 
     173        if ( isset($wp_registered_widget_controls[$id]) && !did_action( 'widgets_init' ) ) 
    161174                return; 
    162175 
    163         $defaults = array('width' => 300, 'height' => 200); 
     176        $defaults = array('width' => 250, 'height' => 200 ); // height is never used 
    164177        $options = wp_parse_args($options, $defaults); 
    165178        $options['width'] = (int) $options['width']; 
    166179        $options['height'] = (int) $options['height']; 
    167         $options['width'] = $options['width'] > 90 ? $options['width'] + 60 : 360; 
    168         $options['height'] = $options['height'] > 60 ? $options['height'] + 40 : 240; 
    169180 
    170181        $widget = array( 
    171182                'name' => $name, 
     
    234245        return $did_one; 
    235246} 
    236247 
     248/* @return mixed false if widget is not active or id of sidebar in which the widget is active 
     249 */ 
    237250function is_active_widget($callback) { 
    238251        global $wp_registered_widgets; 
    239252 
    240253        $sidebars_widgets = wp_get_sidebars_widgets(false); 
    241254 
    242         if ( is_array($sidebars_widgets) ) foreach ( $sidebars_widgets as $widgets ) 
     255        if ( is_array($sidebars_widgets) ) foreach ( $sidebars_widgets as $sidebar => $widgets ) 
    243256                if ( is_array($widgets) ) foreach ( $widgets as $widget ) 
    244257                        if ( $wp_registered_widgets[$widget]['callback'] == $callback ) 
    245                                 return true; 
     258                                return $sidebar; 
    246259 
    247260        return false; 
    248261} 
     
    387400        $title = attribute_escape($options['title']); 
    388401        $exclude = attribute_escape( $options['exclude'] ); 
    389402?> 
    390                         <p><label for="pages-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="pages-title" name="pages-title" type="text" value="<?php echo $title; ?>" /></label></p> 
    391                         <p><label for="pages-sortby"><?php _e( 'Sort by:' ); ?> 
    392                                 <select name="pages-sortby" id="pages-sortby"> 
     403                <p><label for="pages-title"><?php _e('Title:'); ?> <input class="widefat" id="pages-title" name="pages-title" type="text" value="<?php echo $title; ?>" /></label></p> 
     404                <p> 
     405                        <label for="pages-sortby"><?php _e( 'Sort by:' ); ?> 
     406                                <select name="pages-sortby" id="pages-sortby" class="widefat"> 
    393407                                        <option value="post_title"<?php selected( $options['sortby'], 'post_title' ); ?>><?php _e('Page title'); ?></option> 
    394408                                        <option value="menu_order"<?php selected( $options['sortby'], 'menu_order' ); ?>><?php _e('Page order'); ?></option> 
    395409                                        <option value="ID"<?php selected( $options['sortby'], 'ID' ); ?>><?php _e( 'Page ID' ); ?></option> 
    396                                 </select></label></p> 
    397                         <p><label for="pages-exclude"><?php _e( 'Exclude:' ); ?> <input type="text" value="<?php echo $exclude; ?>" name="pages-exclude" id="pages-exclude" style="width: 180px;" /></label><br /> 
    398                         <small><?php _e( 'Page IDs, separated by commas.' ); ?></small></p> 
    399                         <input type="hidden" id="pages-submit" name="pages-submit" value="1" /> 
     410                                </select> 
     411                        </label> 
     412                </p> 
     413                <p> 
     414                        <label for="pages-exclude"><?php _e( 'Exclude:' ); ?> <input type="text" value="<?php echo $exclude; ?>" name="pages-exclude" id="pages-exclude" class="widefat" /></label> 
     415                        <br /> 
     416                        <small><?php _e( 'Page IDs, separated by commas.' ); ?></small> 
     417                </p> 
     418                <input type="hidden" id="pages-submit" name="pages-submit" value="1" /> 
    400419<?php 
    401420} 
    402421 
     
    463482        $dropdown = $options['dropdown'] ? 'checked="checked"' : ''; 
    464483        $title = attribute_escape($options['title']); 
    465484?> 
    466                         <p><label for="archives-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="archives-title" name="archives-title" type="text" value="<?php echo $title; ?>" /></label></p> 
    467                         <p style="text-align:right;margin-right:40px;"><label for="archives-count"><?php _e('Show post counts'); ?> <input class="checkbox" type="checkbox" <?php echo $count; ?> id="archives-count" name="archives-count" /></label></p> 
    468                         <p style="text-align:right;margin-right:40px;"><label for="archives-dropdown"><?php _e('Display as a drop down'); ?> <input class="checkbox" type="checkbox" <?php echo $dropdown; ?> id="archives-dropdown" name="archives-dropdown" /></label></p> 
     485                        <p><label for="archives-title"><?php _e('Title:'); ?> <input class="widefat" id="archives-title" name="archives-title" type="text" value="<?php echo $title; ?>" /></label></p> 
     486                        <p> 
     487                                <label for="archives-count"><input class="checkbox" type="checkbox" <?php echo $count; ?> id="archives-count" name="archives-count" /> <?php _e('Show post counts'); ?></label> 
     488                                <br /> 
     489                                <label for="archives-dropdown"><input class="checkbox" type="checkbox" <?php echo $dropdown; ?> id="archives-dropdown" name="archives-dropdown" /> <?php _e('Display as a drop down'); ?></label> 
     490                        </p> 
    469491                        <input type="hidden" id="archives-submit" name="archives-submit" value="1" /> 
    470492<?php 
    471493} 
     
    499521        } 
    500522        $title = attribute_escape($options['title']); 
    501523?> 
    502                         <p><label for="meta-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="meta-title" name="meta-title" type="text" value="<?php echo $title; ?>" /></label></p> 
     524                        <p><label for="meta-title"><?php _e('Title:'); ?> <input class="widefat" id="meta-title" name="meta-title" type="text" value="<?php echo $title; ?>" /></label></p> 
    503525                        <input type="hidden" id="meta-submit" name="meta-submit" value="1" /> 
    504526<?php 
    505527} 
     
    527549        } 
    528550        $title = attribute_escape($options['title']); 
    529551?> 
    530                         <p><label for="calendar-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="calendar-title" name="calendar-title" type="text" value="<?php echo $title; ?>" /></label></p> 
     552                        <p><label for="calendar-title"><?php _e('Title:'); ?> <input class="widefat" id="calendar-title" name="calendar-title" type="text" value="<?php echo $title; ?>" /></label></p> 
    531553                        <input type="hidden" id="calendar-submit" name="calendar-submit" value="1" /> 
    532554<?php 
    533555} 
    534556 
    535 function wp_widget_text($args, $number = 1) { 
    536         extract($args); 
     557// See large comment section at end of this file 
     558function wp_widget_text($args, $widget_args = 1) { 
     559        extract( $args, EXTR_SKIP ); 
     560        if ( is_numeric($widget_args) ) 
     561                $widget_args = array( 'number' => $widget_args ); 
     562        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); 
     563        extract( $widget_args, EXTR_SKIP ); 
     564 
    537565        $options = get_option('widget_text'); 
     566        if ( !isset($options[$number]) ) 
     567                return; 
     568 
    538569        $title = $options[$number]['title']; 
    539570        $text = apply_filters( 'widget_text', $options[$number]['text'] ); 
    540571?> 
     
    545576<?php 
    546577} 
    547578 
    548 function wp_widget_text_control($number) { 
    549         $options = $newoptions = get_option('widget_text'); 
     579function wp_widget_text_control($widget_args) { 
     580        global $wp_registered_widgets; 
     581        static $updated = false; 
     582 
     583        if ( is_numeric($widget_args) ) 
     584                $widget_args = array( 'number' => $widget_args ); 
     585        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); 
     586        extract( $widget_args, EXTR_SKIP ); 
     587 
     588        $options = get_option('widget_text'); 
    550589        if ( !is_array($options) ) 
    551                 $options = $newoptions = array(); 
    552         if ( $_POST["text-submit-$number"] ) { 
    553                 $newoptions[$number]['title'] = strip_tags(stripslashes($_POST["text-title-$number"])); 
    554                 $newoptions[$number]['text'] = stripslashes($_POST["text-text-$number"]); 
    555                 if ( !current_user_can('unfiltered_html') ) 
    556                         $newoptions[$number]['text'] = stripslashes(wp_filter_post_kses($newoptions[$number]['text'])); 
    557         } 
    558         if ( $options != $newoptions ) { 
    559                 $options = $newoptions; 
     590                $options = array(); 
     591 
     592        if ( !$updated && !empty($_POST['sidebar']) ) { 
     593                $sidebar = (string) $_POST['sidebar']; 
     594 
     595                $sidebars_widgets = wp_get_sidebars_widgets(); 
     596                if ( isset($sidebars_widgets[$sidebar]) ) 
     597                        $this_sidebar =& $sidebars_widgets[$sidebar]; 
     598                else 
     599                        $this_sidebar = array(); 
     600 
     601                foreach ( $this_sidebar as $_widget_id ) { 
     602                        if ( 'wp_widget_text' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) { 
     603                                $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number']; 
     604                                unset($options[$widget_number]); 
     605                        } 
     606                } 
     607 
     608                foreach ( (array) $_POST['widget-text'] as $widget_number => $widget_text ) { 
     609                        $title = strip_tags(stripslashes($widget_text['title'])); 
     610                        if ( current_user_can('unfiltered_html') ) 
     611                                $text = stripslashes( $widget_text['text'] ); 
     612                        else 
     613                                $text = stripslashes(wp_filter_post_kses( $widget_text['text'] )); 
     614                        $options[$widget_number] = compact( 'title', 'text' ); 
     615                } 
     616 
    560617                update_option('widget_text', $options); 
     618                $updated = true; 
    561619        } 
    562         $title = attribute_escape($options[$number]['title']); 
    563         $text = format_to_edit($options[$number]['text']); 
    564 ?> 
    565                         <input style="width: 450px;" id="text-title-<?php echo $number; ?>" name="text-title-<?php echo $number; ?>" type="text" value="<?php echo $title; ?>" /> 
    566                         <textarea style="width: 450px; height: 280px;" id="text-text-<?php echo $number; ?>" name="text-text-<?php echo $number; ?>"><?php echo $text; ?></textarea> 
    567                         <input type="hidden" id="text-submit-<?php echo "$number"; ?>" name="text-submit-<?php echo "$number"; ?>" value="1" /> 
    568 <?php 
    569 } 
    570620 
    571 function wp_widget_text_setup() { 
    572         $options = $newoptions = get_option('widget_text'); 
    573         if ( isset($_POST['text-number-submit']) ) { 
    574                 $number = (int) $_POST['text-number']; 
    575                 if ( $number > 9 ) $number = 9; 
    576                 if ( $number < 1 ) $number = 1; 
    577                 $newoptions['number'] = $number; 
     621        if ( -1 == $number ) { 
     622                $title = ''; 
     623                $text = ''; 
     624                $number = '%i%'; 
     625        } else { 
     626                $title = attribute_escape($options[$number]['title']); 
     627                $text = format_to_edit($options[$number]['text']); 
    578628        } 
    579         if ( $options != $newoptions ) { 
    580                 $options = $newoptions; 
    581                 update_option('widget_text', $options); 
    582                 wp_widget_text_register($options['number']); 
    583         } 
    584 } 
    585  
    586 function wp_widget_text_page() { 
    587         $options = get_option('widget_text'); 
    588629?> 
    589         <div class="wrap"> 
    590                 <form method="POST"> 
    591                         <h2><?php _e('Text Widgets'); ?></h2> 
    592                         <p style="line-height: 30px;"><?php _e('How many text widgets would you like?'); ?> 
    593                         <select id="text-number" name="text-number" value="<?php echo $options['number']; ?>"> 
    594 <?php for ( $i = 1; $i < 10; ++$i ) echo "<option value='$i' ".($options['number']==$i ? "selected='selected'" : '').">$i</option>"; ?> 
    595                         </select> 
    596                         <span class="submit"><input type="submit" name="text-number-submit" id="text-number-submit" value="<?php echo attribute_escape(__('Save')); ?>" /></span></p> 
    597                 </form> 
    598         </div> 
     630                <p> 
     631                        <input class="widefat" id="text-title-<?php echo $number; ?>" name="widget-text[<?php echo $number; ?>][title]" type="text" value="<?php echo $title; ?>" /> 
     632                        <textarea class="widefat" rows="16" cols="20" id="text-text-<?php echo $number; ?>" name="widget-text[<?php echo $number; ?>][text]"><?php echo $text; ?></textarea> 
     633                        <input type="hidden" id="text-submit-<?php echo $number; ?>" name="text-submit-<?php echo $number; ?>" value="1" /> 
     634                </p> 
    599635<?php 
    600636} 
    601637 
    602638function wp_widget_text_register() { 
    603639        $options = get_option('widget_text'); 
    604         $number = $options['number']; 
    605         if ( $number < 1 ) $number = 1; 
    606         if ( $number > 9 ) $number = 9; 
    607         $dims = array('width' => 460, 'height' => 350); 
    608         $class = array('classname' => 'widget_text'); 
    609         for ($i = 1; $i <= 9; $i++) { 
    610                 $name = sprintf(__('Text %d'), $i); 
    611                 $id = "text-$i"; // Never never never translate an id 
    612                 wp_register_sidebar_widget($id, $name, $i <= $number ? 'wp_widget_text' : /* unregister */ '', $class, $i); 
    613                 wp_register_widget_control($id, $name, $i <= $number ? 'wp_widget_text_control' : /* unregister */ '', $dims, $i); 
     640        $widget_ops = array('classname' => 'widget_text', 'description' => __('Arbitrary text or HTML')); 
     641        $control_ops = array('width' => 460, 'height' => 350, 'id_base' => 'text'); 
     642        $name = __('Text'); 
     643 
     644        // If there are none, we register the widget's existance with a generic template 
     645        if ( !$options ) { 
     646                wp_register_sidebar_widget( 'text-1', $name, 'wp_widget_text', $widget_ops, array( 'number' => -1 ) ); 
     647                wp_register_widget_control( 'text-1', $name, 'wp_widget_text_control', $control_ops, array( 'number' => -1 ) ); 
    614648        } 
    615         add_action('sidebar_admin_setup', 'wp_widget_text_setup'); 
    616         add_action('sidebar_admin_page', 'wp_widget_text_page'); 
     649 
     650        foreach ( array_keys($options) as $o ) { 
     651                // Old widgets can have null values for some reason 
     652                if ( !isset($options[$o]['title']) || !isset($options[$o]['text']) ) 
     653                        continue; 
     654                $id = "text-$o"; // Never never never translate an id 
     655                wp_register_sidebar_widget($id, $name, 'wp_widget_text', $widget_ops, array( 'number' => $o )); 
     656                wp_register_widget_control($id, $name, 'wp_widget_text_control', $control_ops, array( 'number' => $o )); 
     657        } 
    617658} 
    618659 
    619 function wp_widget_categories($args, $number = 1) { 
    620         extract($args); 
     660// See large comment section at end of this file 
     661function wp_widget_categories($args, $widget_args = 1) { 
     662        extract($args, EXTR_SKIP); 
     663        if ( is_numeric($widget_args) ) 
     664                $widget_args = array( 'number' => $widget_args ); 
     665        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); 
     666        extract($widget_args, EXTR_SKIP); 
     667 
    621668        $options = get_option('widget_categories'); 
     669        if ( !isset($options[$number]) ) 
     670                return; 
    622671 
    623672        $c = $options[$number]['count'] ? '1' : '0'; 
    624673        $h = $options[$number]['hierarchical'] ? '1' : '0'; 
     
    635684                wp_dropdown_categories($cat_args . '&show_option_none= ' . __('Select Category')); 
    636685?> 
    637686 
    638 <script type='text/javascript'><!-- 
     687<script type='text/javascript'> 
     688/* <![CDATA[ */ 
    639689    var dropdown = document.getElementById("cat"); 
    640690    function onCatChange() { 
    641691                if ( dropdown.options[dropdown.selectedIndex].value > 0 ) { 
     
    643693                } 
    644694    } 
    645695    dropdown.onchange = onCatChange; 
    646 --></script> 
     696/* ]]> */ 
     697</script> 
    647698 
    648699<?php 
    649700        } else { 
     
    657708        echo $after_widget; 
    658709} 
    659710 
    660 function wp_widget_categories_control( $number ) { 
    661         $options = $newoptions = get_option('widget_categories'); 
     711function wp_widget_categories_control( $widget_args ) { 
     712        global $wp_registered_widgets; 
     713        static $updated = false; 
    662714 
    663         if ( !is_array( $options ) ) { 
    664                 $options = $newoptions = get_option( 'widget_categories' ); 
    665         } 
     715        if ( is_numeric($widget_args) ) 
     716                $widget_args = array( 'number' => $widget_args ); 
     717        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); 
     718        extract($widget_args, EXTR_SKIP); 
    666719 
    667         if ( $_POST['categories-submit-' . $number] ) { 
    668                 $newoptions[$number]['count'] = isset($_POST['categories-count-' . $number]); 
    669                 $newoptions[$number]['hierarchical'] = isset($_POST['categories-hierarchical-' . $number]); 
    670                 $newoptions[$number]['dropdown'] = isset($_POST['categories-dropdown-' . $number]); 
    671                 $newoptions[$number]['title'] = strip_tags(stripslashes($_POST['categories-title-' . $number])); 
    672         } 
     720        $options = get_option('widget_categories'); 
    673721 
    674         if ( $options != $newoptions ) { 
    675                 $options = $newoptions; 
     722        if ( !is_array( $options ) ) 
     723                $options = array(); 
     724 
     725        if ( !$updated && !empty($_POST['sidebar']) ) { 
     726                $sidebar = (string) $_POST['sidebar']; 
     727                 
     728                $sidebars_widgets = wp_get_sidebars_widgets(); 
     729                if ( isset($sidebars_widgets[$sidebar]) ) 
     730                        $this_sidebar =& $sidebars_widgets[$sidebar]; 
     731                else 
     732                        $this_sidebar = array(); 
     733                 
     734                foreach ( $this_sidebar as $_widget_id ) { 
     735                        if ( 'wp_widget_categories' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) { 
     736                                $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number']; 
     737                                unset($options[$widget_number]); 
     738                        }    
     739                } 
     740 
     741                foreach ( (array) $_POST['widget-categories'] as $widget_number => $widget_cat ) { 
     742                        $title = trim(strip_tags(stripslashes($widget_cat['title']))); 
     743                        $count = isset($widget_cat['count']); 
     744                        $hierarchical = isset($widget_cat['hierarchical']); 
     745                        $dropdown = isset($widget_cat['dropdown']); 
     746                        $options[$widget_number] = compact( 'title', 'count', 'hierarchical', 'dropdown' ); 
     747                } 
     748 
    676749                update_option('widget_categories', $options); 
     750                $updated = true; 
    677751        } 
    678752 
    679         $title = attribute_escape( $options[$number]['title'] ); 
     753        if ( -1 == $number ) { 
     754                $title = ''; 
     755                $count = false; 
     756                $hierarchical = false; 
     757                $dropdown = false; 
     758                $number = '%i%'; 
     759        } else { 
     760                $title = attribute_escape( $options[$number]['title'] ); 
     761                $count = (bool) $options[$number]['count']; 
     762                $hierarchical = (bool) $options[$number]['hierarchical']; 
     763                $dropdown = (bool) $options[$number]['dropdown']; 
     764        } 
    680765?> 
    681                         <p><label for="categories-title-<?php echo $number; ?>"> 
    682                                 <?php _e( 'Title:' ); ?> <input style="width:300px" id="categories-title-<?php echo $number; ?>" name="categories-title-<?php echo $number; ?>" type="text" value="<?php echo $title; ?>" /> 
    683                         </label></p> 
     766                        <p> 
     767                                <label for="categories-title-<?php echo $number; ?>"> 
     768                                        <?php _e( 'Title:' ); ?>  
     769                                        <input class="widefat" id="categories-title-<?php echo $number; ?>" name="widget-categories[<?php echo $number; ?>][title]" type="text" value="<?php echo $title; ?>" /> 
     770                                </label> 
     771                        </p> 
    684772 
    685                         <p><label for="categories-dropdown-<?php echo $number; ?>"> 
    686                                 <input type="checkbox" class="checkbox" id="categories-dropdown-<?php echo $number; ?>" name="categories-dropdown-<?php echo $number; ?>"<?php echo $options[$number]['dropdown'] ? ' checked="checked"' : ''; ?> /> <?php _e( 'Show as dropdown' ); ?> 
    687                         </label></p> 
     773                        <p> 
     774                                <label for="categories-dropdown-<?php echo $number; ?>"> 
     775                                        <input type="checkbox" class="checkbox" id="categories-dropdown-<?php echo $number; ?>" name="widget-categories[<?php echo $number; ?>][dropdown]"<?php checked( $dropdown, true ); ?> /> 
     776                                        <?php _e( 'Show as dropdown' ); ?> 
     777                                </label> 
     778                                <br /> 
     779                                <label for="categories-count-<?php echo $number; ?>"> 
     780                                        <input type="checkbox" class="checkbox" id="categories-count-<?php echo $number; ?>" name="widget-categories[<?php echo $number; ?>][count]"<?php checked( $count, true ); ?> /> 
     781                                        <?php _e( 'Show post counts' ); ?> 
     782                                </label> 
     783                                <br /> 
     784                                <label for="categories-hierarchical-<?php echo $number; ?>"> 
     785                                        <input type="checkbox" class="checkbox" id="categories-hierarchical-<?php echo $number; ?>" name="widget-categories[<?php echo $number; ?>][hierarchical]"<?php checked( $hierarchical, true ); ?> /> 
     786                                        <?php _e( 'Show hierarchy' ); ?> 
     787                                </label> 
     788                        </p> 
    688789 
    689                         <p><label for="categories-count-<?php echo $number; ?>"> 
    690                                 <input type="checkbox" class="checkbox" id="categories-count-<?php echo $number; ?>" name="categories-count-<?php echo $number; ?>"<?php echo $options[$number]['count'] ? ' checked="checked"' : ''; ?> /> <?php _e( 'Show post counts' ); ?> 
    691                         </label></p> 
    692  
    693                         <p><label for="categories-hierarchical-<?php echo $number; ?>"> 
    694                                 <input type="checkbox" class="checkbox" id="categories-hierarchical-<?php echo $number; ?>" name="categories-hierarchical-<?php echo $number; ?>"<?php echo $options[$number]['hierarchical'] ? ' checked="checked"' : ''; ?> /> <?php _e( 'Show hierarchy' ); ?> 
    695                         </label></p> 
    696  
    697790                        <input type="hidden" id="categories-submit-<?php echo $number; ?>" name="categories-submit-<?php echo $number; ?>" value="1" /> 
    698791<?php 
    699792} 
    700793 
    701 function wp_widget_categories_setup() { 
    702         $options = $newoptions = get_option( 'widget_categories' ); 
     794function wp_widget_categories_register() { 
     795        $options = get_option( 'widget_categories' ); 
     796        if ( isset($options['title']) ) 
     797                $options = wp_widget_categories_upgrade(); 
    703798 
    704         if ( isset( $_POST['categories-number-submit'] ) ) { 
    705                 $number = (int) $_POST['categories-number']; 
     799        $widget_ops = array( 'classname' => 'widget_categories', 'description' => __( "A list or dropdown of categories" ) ); 
    706800 
    707                 if ( $number > 9 ) { 
    708                         $number = 9; 
    709                 } elseif ( $number < 1 ) { 
    710                         $number = 1; 
    711                 } 
     801        $name = __( 'Categories' ); 
    712802 
    713                 $newoptions['number'] = $number; 
     803        // If there are none, we register the widget's existance with a generic template 
     804        if ( !$options ) { 
     805                wp_register_sidebar_widget( 'categories-1', $name, 'wp_widget_categories', $widget_ops, array( 'number' => -1 ) ); 
     806                wp_register_widget_control( 'categories-1', $name, 'wp_widget_categories_control', array( 'id_base' => 'categories' ), array( 'number' => -1 ) ); 
    714807        } 
    715808 
    716         if ( $newoptions != $options ) { 
    717                 $options = $newoptions; 
    718                 update_option( 'widget_categories', $options ); 
    719                 wp_widget_categories_register( $options['number'] ); 
     809        foreach ( array_keys($options) as $o ) { 
     810                // Old widgets can have null values for some reason 
     811                if ( !isset($options[$o]['title']) ) 
     812                        continue; 
     813                $id = "categories-$o"; 
     814                wp_register_sidebar_widget( $id, $name, 'wp_widget_categories', $widget_ops, array( 'number' => $o ) ); 
     815                wp_register_widget_control( $id, $name, 'wp_widget_categories_control', array( 'id_base' => 'categories' ), array( 'number' => $o ) ); 
    720816        } 
    721 } 
    722817 
    723 function wp_widget_categories_page() { 
    724         $options = get_option( 'widget_categories' ); 
    725 ?> 
    726         <div class="wrap"> 
    727                 <form method="post"> 
    728                         <h2><?php _e( 'Categories Widgets' ); ?></h2> 
    729                         <p style="line-height: 30px;"><?php _e( 'How many categories widgets would you like?' ); ?> 
    730                                 <select id="categories-number" name="categories-number" value="<?php echo attribute_escape( $options['number'] ); ?>"> 
    731                                         <?php 
    732                                                 for ( $i = 1; $i < 10; $i++ ) { 
    733                                                         echo '<option value="' . $i . '"' . ( $i == $options['number'] ? ' selected="selected"' : '' ) . '>' . $i . "</option>\n"; 
    734                                                 } 
    735                                         ?> 
    736                                 </select> 
    737                                 <span class="submit"> 
    738                                         <input type="submit" value="<?php echo attribute_escape( __( 'Save' ) ); ?>" id="categories-number-submit" name="categories-number-submit" /> 
    739                                 </span> 
    740                         </p> 
    741                 </form> 
    742         </div> 
    743 <?php 
    744818} 
    745819 
    746820function wp_widget_categories_upgrade() { 
    747821        $options = get_option( 'widget_categories' ); 
    748822 
    749         $newoptions = array( 'number' => 1, 1 => $options ); 
     823        if ( !isset( $options['title'] ) ) 
     824                return $options; 
    750825 
     826        $newoptions = array( 1 => $options ); 
     827 
    751828        update_option( 'widget_categories', $newoptions ); 
    752829 
    753830        $sidebars_widgets = get_option( 'sidebars_widgets' ); 
     
    764841                        update_option( 'sidebars_widgets', $new_widgets ); 
    765842        } 
    766843 
    767         if ( isset( $_POST['categories-submit'] ) ) { 
    768                 $_POST['categories-submit-1'] = $_POST['categories-submit']; 
    769                 $_POST['categories-count-1'] = $_POST['categories-count']; 
    770                 $_POST['categories-hierarchical-1'] = $_POST['categories-hierarchical']; 
    771                 $_POST['categories-dropdown-1'] = $_POST['categories-dropdown']; 
    772                 $_POST['categories-title-1'] = $_POST['categories-title']; 
    773                 foreach ( $_POST as $k => $v ) 
    774                         if ( substr($k, -5) == 'order' ) 
    775                                 $_POST[$k] = str_replace('categories', 'categories-1', $v); 
    776         } 
    777  
    778844        return $newoptions; 
    779845} 
    780846 
    781 function wp_widget_categories_register() { 
    782         $options = get_option( 'widget_categories' ); 
    783         if ( !isset($options['number']) ) 
    784                 $options = wp_widget_categories_upgrade(); 
    785         $number = (int) $options['number']; 
    786  
    787         if ( $number > 9 ) { 
    788                 $number = 9; 
    789         } elseif ( $number < 1 ) { 
    790                 $number = 1; 
    791         } 
    792  
    793         $dims = array( 'width' => 350, 'height' => 170 ); 
    794         $class = array( 'classname' => 'widget_categories' ); 
    795  
    796         for ( $i = 1; $i <= 9; $i++ ) { 
    797                 $name = sprintf( __( 'Categories %d' ), $i ); 
    798                 $id = 'categories-' . $i; 
    799  
    800                 $widget_callback = ( $i <= $number ) ? 'wp_widget_categories' : ''; 
    801                 $control_callback = ( $i <= $number ) ? 'wp_widget_categories_control' : ''; 
    802  
    803                 wp_register_sidebar_widget( $id, $name, $widget_callback, $class, $i ); 
    804                 wp_register_widget_control( $id, $name, $control_callback, $dims, $i ); 
    805         } 
    806  
    807         add_action( 'sidebar_admin_setup', 'wp_widget_categories_setup' ); 
    808         add_action( 'sidebar_admin_page', 'wp_widget_categories_page' ); 
    809 } 
    810  
    811847function wp_widget_recent_entries($args) { 
    812848        if ( $output = wp_cache_get('widget_recent_entries') ) 
    813849                return print($output); 
     
    861897        if ( !$number = (int) $options['number'] ) 
    862898                $number = 5; 
    863899?> 
    864                         <p><label for="recent-entries-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="recent-entries-title" name="recent-entries-title" type="text" value="<?php echo $title; ?>" /></label></p> 
    865                         <p><label for="recent-entries-number"><?php _e('Number of posts to show:'); ?> <input style="width: 25px; text-align: center;" id="recent-entries-number" name="recent-entries-number" type="text" value="<?php echo $number; ?>" /></label> <?php _e('(at most 15)'); ?></p> 
     900 
     901                        <p><label for="recent-entries-title"><?php _e('Title:'); ?> <input class="widefat" id="recent-entries-title" name="recent-entries-title" type="text" value="<?php echo $title; ?>" /></label></p> 
     902                        <p> 
     903                                <label for="recent-entries-number"><?php _e('Number of posts to show:'); ?> <input style="width: 25px; text-align: center;" id="recent-entries-number" name="recent-entries-number" type="text" value="<?php echo $number; ?>" /></label> 
     904                                <br /> 
     905                                <small><?php _e('(at most 15)'); ?></small> 
     906                        </p> 
    866907                        <input type="hidden" id="recent-entries-submit" name="recent-entries-submit" value="1" /> 
    867908<?php 
    868909} 
     
    916957        if ( !$number = (int) $options['number'] ) 
    917958                $number = 5; 
    918959?> 
    919                         <p><label for="recent-comments-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="recent-comments-title" name="recent-comments-title" type="text" value="<?php echo $title; ?>" /></label></p> 
    920                         <p><label for="recent-comments-number"><?php _e('Number of comments to show:'); ?> <input style="width: 25px; text-align: center;" id="recent-comments-number" name="recent-comments-number" type="text" value="<?php echo $number; ?>" /></label> <?php _e('(at most 15)'); ?></p> 
     960                        <p><label for="recent-comments-title"><?php _e('Title:'); ?> <input class="widefat" id="recent-comments-title" name="recent-comments-title" type="text" value="<?php echo $title; ?>" /></label></p> 
     961                        <p> 
     962                                <label for="recent-comments-number"><?php _e('Number of comments to show:'); ?> <input style="width: 25px; text-align: center;" id="recent-comments-number" name="recent-comments-number" type="text" value="<?php echo $number; ?>" /></label> 
     963                                <br /> 
     964                                <small><?php _e('(at most 15)'); ?></small> 
     965                        </p> 
    921966                        <input type="hidden" id="recent-comments-submit" name="recent-comments-submit" value="1" /> 
    922967<?php 
    923968} 
     
    929974} 
    930975 
    931976function wp_widget_recent_comments_register() { 
    932         $dims = array('width' => 320, 'height' => 90); 
    933         $class = array('classname' => 'widget_recent_comments'); 
    934         wp_register_sidebar_widget('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments', $class); 
    935         wp_register_widget_control('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments_control', $dims); 
     977        $widget_ops = array('classname' => 'widget_recent_comments', 'description' => __( 'The most recent comments' ) ); 
     978        wp_register_sidebar_widget('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments', $widget_ops); 
     979        wp_register_widget_control('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments_control'); 
    936980 
    937981        if ( is_active_widget('wp_widget_recent_comments') ) 
    938982                add_action('wp_head', 'wp_widget_recent_comments_style'); 
    939983} 
    940984 
    941 function wp_widget_rss($args, $number = 1) { 
    942         require_once(ABSPATH . WPINC . '/rss.php'); 
    943         extract($args); 
     985// See large comment section at end of this file 
     986function wp_widget_rss($args, $widget_args = 1) { 
     987        extract($args, EXTR_SKIP); 
     988        if ( is_numeric($widget_args) ) 
     989                $widget_args = array( 'number' => $widegt_args ); 
     990        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); 
     991        extract($widget_args, EXTR_SKIP); 
     992 
    944993        $options = get_option('widget_rss'); 
    945         if ( isset($options['error']) && $options['error'] ) 
     994 
     995        if ( !isset($options[$number]) ) 
    946996                return; 
     997 
     998        if ( isset($options[$number]['error']) && $options[$number]['error'] ) 
     999                return; 
     1000 
    9471001        $num_items = (int) $options[$number]['items']; 
    9481002        $show_summary = $options[$number]['show_summary']; 
    9491003        if ( empty($num_items) || $num_items < 1 || $num_items > 10 ) $num_items = 10; 
     
    9521006                $url = substr($url, 1); 
    9531007        if ( empty($url) ) 
    9541008                return; 
     1009 
     1010        require_once(ABSPATH . WPINC . '/rss.php'); 
     1011 
    9551012        $rss = fetch_rss($url); 
    9561013        $link = clean_url(strip_tags($rss->channel['link'])); 
    9571014        while ( strstr($link, 'http') != $link ) 
     
    10021059        echo $after_widget; 
    10031060} 
    10041061 
    1005 function wp_widget_rss_control($number) { 
    1006         $options = $newoptions = get_option('widget_rss'); 
    1007         if ( $_POST["rss-submit-$number"] ) { 
    1008                 $newoptions[$number]['items'] = (int) $_POST["rss-items-$number"]; 
    1009                 $url = sanitize_url(strip_tags(stripslashes($_POST["rss-url-$number"]))); 
    1010                 $newoptions[$number]['title'] = trim(strip_tags(stripslashes($_POST["rss-title-$number"]))); 
    1011                 if ( $url !== $options[$number]['url'] ) { 
    1012                         require_once(ABSPATH . WPINC . '/rss.php'); 
    1013                         $rss = fetch_rss($url); 
    1014                         if ( is_object($rss) ) { 
    1015                                 $newoptions[$number]['url'] = $url; 
    1016                                 $newoptions[$number]['error'] = false; 
    1017                         } else { 
    1018                                 $newoptions[$number]['error'] = true; 
    1019                                 $newoptions[$number]['url'] = wp_specialchars(__('Error: could not find an RSS or ATOM feed at that URL.'), 1); 
     1062function wp_widget_rss_control($widget_args) { 
     1063        global $wp_registered_widgets; 
     1064        static $updated = false; 
     1065 
     1066        if ( is_numeric($widget_args) ) 
     1067                $widget_args = array( 'number' => $widget_args ); 
     1068        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); 
     1069        extract($widget_args, EXTR_SKIP); 
     1070 
     1071        $options = get_option('widget_rss'); 
     1072        if ( !is_array($options) ) 
     1073                $options = array(); 
     1074 
     1075        $urls = array(); 
     1076        foreach ( $options as $option ) 
     1077                if ( isset($option['url']) ) 
     1078                        $urls[$option['url']] = true; 
     1079 
     1080        if ( !$updated && !empty($_POST['sidebar']) ) { 
     1081                $sidebar = (string) $_POST['sidebar']; 
     1082 
     1083                $sidebars_widgets = wp_get_sidebars_widgets(); 
     1084                if ( isset($sidebars_widgets[$sidebar]) ) 
     1085                        $this_sidebar =& $sidebars_widgets[$sidebar]; 
     1086                else 
     1087                        $this_sidebar = array(); 
     1088         
     1089                foreach ( $this_sidebar as $_widget_id ) { 
     1090                        if ( 'wp_widget_rss' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) { 
     1091                                $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number']; 
     1092                                unset($options[$widget_number]); 
    10201093                        } 
    10211094                } 
    1022         } 
    1023         if ( $options != $newoptions ) { 
    1024                 $options = $newoptions; 
     1095 
     1096                foreach( (array) $_POST['widget-rss'] as $widget_number => $widget_rss ) { 
     1097                        $items = (int) $widget_rss['items']; 
     1098                        if ( $items < 1 ) 
     1099                                $items = 10; 
     1100                        $url = sanitize_url(strip_tags(stripslashes($widget_rss['url']))); 
     1101                        $title = trim(strip_tags(stripslashes($widget_rss['title']))); 
     1102 
     1103                        if ( !isset($urls[$url]) ) { 
     1104                                require_once(ABSPATH . WPINC . '/rss.php'); 
     1105                                $rss = fetch_rss($url); 
     1106                                $error = false; 
     1107                                if ( !is_object($rss) ) { 
     1108                                        $url = wp_specialchars(__('Error: could not find an RSS or ATOM feed at that URL.'), 1); 
     1109                                        $error = sprintf(__('Error in RSS %1$d'), $widget_number ); 
     1110                                } 
     1111                        } 
     1112                        $options[$widget_number] = compact( 'title', 'url', 'items', 'error' ); 
     1113                } 
     1114 
    10251115                update_option('widget_rss', $options); 
     1116                $updated = true; 
    10261117        } 
    1027         $url = attribute_escape($options[$number]['url']); 
    1028         $items = (int) $options[$number]['items']; 
    1029         $title = attribute_escape($options[$number]['title']); 
    1030         if ( empty($items) || $items < 1 ) $items = 10; 
    1031 ?> 
    1032                         <p style="text-align:center;"><?php _e('Enter the RSS feed URL here:'); ?></p> 
    1033                         <input style="width: 400px;" id="rss-url-<?php echo "$number"; ?>" name="rss-url-<?php echo "$number"; ?>" type="text" value="<?php echo $url; ?>" /> 
    1034                         <p style="text-align:center;"><?php _e('Give the feed a title (optional):'); ?></p> 
    1035                         <input style="width: 400px;" id="rss-title-<?php echo "$number"; ?>" name="rss-title-<?php echo "$number"; ?>" type="text" value="<?php echo $title; ?>" /> 
    1036                         <p style="text-align:center; line-height: 30px;"><?php _e('How many items would you like to display?'); ?> <select id="rss-items-<?php echo $number; ?>" name="rss-items-<?php echo $number; ?>"><?php for ( $i = 1; $i <= 10; ++$i ) echo "<option value='$i' ".($items==$i ? "selected='selected'" : '').">$i</option>"; ?></select></p> 
    1037                         <input type="hidden" id="rss-submit-<?php echo "$number"; ?>" name="rss-submit-<?php echo $number; ?>" value="1" /> 
    1038 <?php 
    1039 } 
    10401118 
    1041 function wp_widget_rss_setup() { 
    1042         $options = $newoptions = get_option('widget_rss'); 
    1043         if ( isset($_POST['rss-number-submit']) ) { 
    1044                 $number = (int) $_POST['rss-number']; 
    1045                 if ( $number > 9 ) $number = 9; 
    1046                 if ( $number < 1 ) $number = 1; 
    1047                 $newoptions['number'] = $number; 
     1119        if ( -1 == $number ) { 
     1120                $title = ''; 
     1121                $url = ''; 
     1122                $items = 10; 
     1123                $error = false; 
     1124                $number = '%i%'; 
     1125        } else { 
     1126                $title = attribute_escape($options[$number]['title']); 
     1127                $url = attribute_escape($options[$number]['url']); 
     1128                $items = (int) $options[$number]['items']; 
     1129                if ( $items < 1 ) 
     1130                        $items = 10; 
     1131                $error = $options[$number]['error']; 
    10481132        } 
    1049         if ( $options != $newoptions ) { 
    1050                 $options = $newoptions; 
    1051                 update_option('widget_rss', $options); 
    1052                 wp_widget_rss_register($options['number']); 
    1053         } 
    1054 } 
    10551133 
    1056 function wp_widget_rss_page() { 
    1057         $options = get_option('widget_rss'); 
    10581134?> 
    1059         <div class="wrap"> 
    1060                 <form method="POST"> 
    1061                         <h2><?php _e('RSS Feed Widgets'); ?></h2> 
    1062                         <p style="line-height: 30px;"><?php _e('How many RSS widgets would you like?'); ?> 
    1063                         <select id="rss-number" name="rss-number" value="<?php echo $options['number']; ?>"> 
    1064 <?php for ( $i = 1; $i < 10; ++$i ) echo "<option value='$i' ".($options['number']==$i ? "selected='selected'" : '').">$i</option>"; ?> 
    1065                         </select> 
    1066                         <span class="submit"><input type="submit" name="rss-number-submit" id="rss-number-submit" value="<?php echo attribute_escape(__('Save')); ?>" /></span></p> 
    1067                 </form> 
    1068         </div> 
     1135                        <p> 
     1136                                <label for="rss-url-<?php echo $number; ?>"><?php _e('Enter the RSS feed URL here:'); ?> 
     1137                                        <input class="widefat" id="rss-url-<?php echo $number; ?>" name="widget-rss[<?php echo $number; ?>][url]" type="text" value="<?php echo $url; ?>" /> 
     1138                                </label> 
     1139                        </p> 
     1140                        <p> 
     1141                                <label for="rss-title-<?php echo $number; ?>"><?php _e('Give the feed a title (optional):'); ?> 
     1142                                        <input class="widefat" id="rss-title-<?php echo $number; ?>" name="widget-rss[<?php echo $number; ?>][title]" type="text" value="<?php echo $title; ?>" /> 
     1143                                </label> 
     1144                        </p> 
     1145                        <p> 
     1146                                <label for="rss-items-<?php echo $number; ?>"><?php _e('How many items would you like to display?'); ?> 
     1147                                        <select id="rss-items-<?php echo $number; ?>" name="widget-rss[<?php echo $number; ?>][items]"> 
     1148                                                <?php 
     1149                                                        for ( $i = 1; $i <= 10; ++$i ) 
     1150                                                                echo "<option value='$i' " . ( $items == $i ? "selected='selected'" : '' ) . ">$i</option>"; 
     1151                                                ?> 
     1152                                        </select> 
     1153                                </label> 
     1154                        </p> 
     1155                        <input type="hidden" id="rss-submit-<?php echo $number; ?>" name="rss-submit-<?php echo $number; ?>" value="1" /> 
    10691156<?php 
    10701157} 
    10711158 
    10721159function wp_widget_rss_register() { 
    10731160        $options = get_option('widget_rss'); 
    1074         $number = $options['number']; 
    1075         if ( $number < 1 ) $number = 1; 
    1076         if ( $number > 9 ) $number = 9; 
    1077         $dims = array('width' => 410, 'height' => 200); 
    1078         $class = array('classname' => 'widget_rss'); 
    1079         for ($i = 1; $i <= 9; $i++) { 
    1080                 $name = sprintf(__('RSS %d'), $i); 
    1081                 $id = "rss-$i"; // Never never never translate an id 
    1082                 wp_register_sidebar_widget($id, $name, $i <= $number ? 'wp_widget_rss' : /* unregister */ '', $class, $i); 
    1083                 wp_register_widget_control($id, $name, $i <= $number ? 'wp_widget_rss_control' : /* unregister */ '', $dims, $i); 
     1161        $widget_ops = array('classname' => 'widget_rss', 'description' => __( 'Entries from any RSS or Atom feed' )); 
     1162        $control_ops = array('width' => 410, 'height' => 200, 'id_base' => 'rss'); 
     1163        $name = __('RSS'); 
     1164 
     1165        // If there are none, we register the widget's existance with a generic template 
     1166        if ( !$options ) { 
     1167                wp_register_sidebar_widget( 'rss-1', $name, 'wp_widget_rss', $widget_ops, array( 'number' => -1 ) ); 
     1168                wp_register_widget_control( 'rss-1', $name, 'wp_widget_rss_control', $control_ops, array( 'number' => -1 ) ); 
    10841169        } 
    1085         add_action('sidebar_admin_setup', 'wp_widget_rss_setup'); 
    1086         add_action('sidebar_admin_page', 'wp_widget_rss_page'); 
     1170 
     1171        foreach ( array_keys($options) as $o ) { 
     1172                // Old widgets can have null values for some reason 
     1173                if ( !isset($options[$o]['url']) || !isset($options[$o]['title']) || !isset($options[$o]['items']) ) 
     1174                        contine; 
     1175                $id = "rss-$o"; // Never never never translate an id 
     1176                wp_register_sidebar_widget($id, $name, 'wp_widget_rss', $widget_ops, array( 'number' => $o )); 
     1177                wp_register_widget_control($id, $name, 'wp_widget_rss_control', $control_ops, array( 'number' => $o )); 
     1178        } 
    10871179} 
    10881180 
    10891181function wp_widget_tag_cloud($args) { 
     
    11121204        $title = attribute_escape( $options['title'] ); 
    11131205?> 
    11141206        <p><label for="tag-cloud-title"> 
    1115         <?php _e('Title:') ?> <input type="text" style="width:300px" id="tag-cloud-title" name="tag-cloud-title" value="<?php echo $title ?>" /></label> 
     1207        <?php _e('Title:') ?> <input type="text" class="widefat" id="tag-cloud-title" name="tag-cloud-title" value="<?php echo $title ?>" /></label> 
    11161208        </p> 
    11171209        <input type="hidden" name="tag-cloud-submit" id="tag-cloud-submit" value="1" /> 
    11181210<?php 
     
    11221214        if ( !is_blog_installed() ) 
    11231215                return; 
    11241216 
    1125         $GLOBALS['wp_register_widget_defaults'] = true; 
     1217        $widget_ops = array('classname' => 'widget_pages', 'description' => __( "Your blog's WordPress Pages") ); 
     1218        wp_register_sidebar_widget('pages', __('Pages'), 'wp_widget_pages', $widget_ops); 
     1219        wp_register_widget_control('pages', __('Pages'), 'wp_widget_pages_control' ); 
    11261220 
    1127         $dims90 = array( 'height' => 90, 'width' => 300 ); 
    1128         $dims100 = array( 'height' => 100, 'width' => 300 ); 
    1129         $dims150 = array( 'height' => 150, 'width' => 300 ); 
     1221        $widget_ops = array('classname' => 'widget_calendar', 'description' => __( "A calendar of your blog's posts") ); 
     1222        wp_register_sidebar_widget('calendar', __('Calendar'), 'wp_widget_calendar', $widget_ops); 
     1223        wp_register_widget_control('calendar', __('Calendar'), 'wp_widget_calendar_control' ); 
    11301224 
    1131         $class = array('classname' => 'widget_pages'); 
    1132         wp_register_sidebar_widget('pages', __('Pages'), 'wp_widget_pages', $class); 
    1133         wp_register_widget_control('pages', __('Pages'), 'wp_widget_pages_control', $dims150); 
     1225        $widget_ops = array('classname' => 'widget_archive', 'description' => __( "A monthly archive of your blog's posts") ); 
     1226        wp_register_sidebar_widget('archives', __('Archives'), 'wp_widget_archives', $widget_ops); 
     1227        wp_register_widget_control('archives', __('Archives'), 'wp_widget_archives_control' ); 
    11341228 
    1135         $class['classname'] = 'widget_calendar'; 
    1136         wp_register_sidebar_widget('calendar', __('Calendar'), 'wp_widget_calendar', $class); 
    1137         wp_register_widget_control('calendar', __('Calendar'), 'wp_widget_calendar_control', $dims90); 
     1229        $widget_ops = array('classname' => 'widget_links', 'description' => __( "Your blogroll") ); 
     1230        wp_register_sidebar_widget('links', __('Links'), 'wp_widget_links', $widget_ops); 
    11381231 
    1139         $class['classname'] = 'widget_archives'; 
    1140         wp_register_sidebar_widget('archives', __('Archives'), 'wp_widget_archives', $class); 
    1141         wp_register_widget_control('archives', __('Archives'), 'wp_widget_archives_control', $dims100); 
     1232        $widget_ops = array('classname' => 'widget_meta', 'description' => __( "Log in/out, admin, feed and WordPress links") ); 
     1233        wp_register_sidebar_widget('meta', __('Meta'), 'wp_widget_meta', $widget_ops); 
     1234        wp_register_widget_control('meta', __('Meta'), 'wp_widget_meta_control' ); 
    11421235 
    1143         $class['classname'] = 'widget_links'; 
    1144         wp_register_sidebar_widget('links', __('Links'), 'wp_widget_links', $class); 
     1236        $widget_ops = array('classname' => 'widget_search', 'description' => __( "A search form for your blog") ); 
     1237        wp_register_sidebar_widget('search', __('Search'), 'wp_widget_search', $widget_ops); 
    11451238 
    1146         $class['classname'] = 'widget_meta'; 
    1147         wp_register_sidebar_widget('meta', __('Meta'), 'wp_widget_meta', $class); 
    1148         wp_register_widget_control('meta', __('Meta'), 'wp_widget_meta_control', $dims90); 
     1239        $widget_ops = array('classname' => 'widget_recent_entries', 'description' => __( "The most recent posts on your blog") ); 
     1240        wp_register_sidebar_widget('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries', $widget_ops); 
     1241        wp_register_widget_control('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries_control' ); 
    11491242 
    1150         $class['classname'] = 'widget_search'; 
    1151         wp_register_sidebar_widget('search', __('Search'), 'wp_widget_search', $class); 
     1243        $widget_ops = array('classname' => 'widget_tag_cloud', 'description' => __( "Your most used tags in cloud format") ); 
     1244        wp_register_sidebar_widget('tag_cloud', __('Tag Cloud'), 'wp_widget_tag_cloud', $widget_ops); 
     1245        wp_register_widget_control('tag_cloud', __('Tag Cloud'), 'wp_widget_tag_cloud_control' ); 
    11521246 
    1153         $class['classname'] = 'widget_recent_entries'; 
    1154         wp_register_sidebar_widget('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries', $class); 
    1155         wp_register_widget_control('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries_control', $dims90); 
    1156  
    1157         $class['classname'] = 'widget_tag_cloud'; 
    1158         wp_register_sidebar_widget('tag_cloud', __('Tag Cloud'), 'wp_widget_tag_cloud', $class); 
    1159         wp_register_widget_control('tag_cloud', __('Tag Cloud'), 'wp_widget_tag_cloud_control', 'width=300&height=160'); 
    1160  
    11611247        wp_widget_categories_register(); 
    11621248        wp_widget_text_register(); 
    11631249        wp_widget_rss_register(); 
    11641250        wp_widget_recent_comments_register(); 
    11651251 
    1166         $GLOBALS['wp_register_widget_defaults'] = false; 
    1167  
    11681252        do_action('widgets_init'); 
    11691253} 
    11701254 
    11711255add_action('init', 'wp_widgets_init', 1); 
    11721256 
     1257/* Pattern for widget which allows multiple instances (such as the text widget) 
     1258 
     1259// Displays widget on blag 
     1260// $widget_args: number 
     1261//    number: which of the several widgets of this type do we mean 
     1262function widget_many( $args, $widget_args = 1 ) { 
     1263        extract( $args, EXTR_SKIP ); 
     1264        if ( is_numeric($widget_args) ) 
     1265                $widget_args = array( 'number' => $widget_args ); 
     1266        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); 
     1267        extract( $widget_args, EXTR_SKIP ); 
     1268         
     1269        // Data should be stored as array:  array( number => data for that instance of the widget, ... ) 
     1270        $options = get_option('widget_many'); 
     1271        if ( !isset($options[$number]) ) 
     1272                return; 
     1273 
     1274        echo $before_widget; 
     1275 
     1276        // Do stuff for this widget, drawing data from $options[$number] 
     1277 
     1278        echo $after_widget; 
     1279} 
     1280 
     1281// Displays form for a particular instance of the widget.  Also updates the data after a POST submit 
     1282// $widget_args: number 
     1283//    number: which of the several widgets of this type do we mean 
     1284function widget_many_control( $widget_args = 1 ) { 
     1285        global $wp_registered_widgets; 
     1286        static $updated = false; // Whether or not we have already updated the data after a POST submit 
     1287 
     1288        if ( is_numeric($widget_args) ) 
     1289                $widget_args = array( 'number' => $widget_args ); 
     1290        $widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) ); 
     1291        extract( $widget_args, EXTR_SKIP ); 
     1292 
     1293        // Data should be stored as array:  array( number => data for that instance of the widget, ... ) 
     1294        $options = get_option('widget_many'); 
     1295        if ( !is_array($options) ) 
     1296                $options = array(); 
     1297 
     1298        // We need to update the data 
     1299        if ( !$updated && !empty($_POST['sidebar']) ) { 
     1300                // Tells us what sidebar to put the data in 
     1301                $sidebar = (string) $_POST['sidebar']; 
     1302 
     1303                $sidebars_widgets = wp_get_sidebars_widgets(); 
     1304                if ( isset($sidebars_widgets[$sidebar]) ) 
     1305                        $this_sidebar =& $sidebars_widgets[$sidebar]; 
     1306                else 
     1307                        $this_sidebar = array(); 
     1308 
     1309                foreach ( $this_sidebar as $_widget_id ) { 
     1310                        // Remove all widgets of this type from the sidebar.  We'll add the new data in a second.  This makes sure we don't get any duplicate data 
     1311                        // since widget ids aren't necessarily persistent across multiple updates 
     1312                        if ( 'widget_many' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) { 
     1313                                $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number']; 
     1314                                unset($options[$widget_number]); 
     1315                        } 
     1316                } 
     1317 
     1318                foreach ( (array) $_POST['widget-many'] as $widget_number => $widget_many_instance ) { 
     1319                        // compile data from $widget_many_instance 
     1320                        $something = wp_specialchars( $widget_many_instance['something'] ); 
     1321                        $options[$widget_number] = array( 'something' => $something );  // Even simple widgets should store stuff in array, rather than in scalar 
     1322                } 
     1323 
     1324                update_option('widget_text', $options); 
     1325 
     1326                $updated = true; // So that we don't go through this more than once 
     1327        } 
     1328 
     1329 
     1330        // Here we echo out the form 
     1331        if ( -1 == $number ) { // We echo out a template for a form which can be converted to a specific form later via JS 
     1332                $something = ''; 
     1333                $number = '%i%'; 
     1334        } else { 
     1335                $something = attribute_escape($options[$number]['something']); 
     1336        } 
     1337 
     1338        // The form has inputs with names like widget-many[$number][something] so that all data for that instance of 
     1339        // the widget are stored in one $_POST variable: $_POST['widget-many'][$number] 
    11731340?> 
     1341                <p> 
     1342                        <input class="widefat" id="widget-many-something-<?php echo $number; ?>" name="widget-many[<?php echo $number; ?>][something]" type="text" value="<?php echo $data; ?>" /> 
     1343                        <input type="hidden" id="widget-many-submit-<?php echo $number; ?>" name="widget-many-<?php echo $number; ?>" value="1" /> 
     1344                </p> 
     1345<?php 
     1346} 
     1347 
     1348// Registers each instance of our widget on startup 
     1349function widget_many_register() { 
     1350        $options = get_option('widget_many'); 
     1351        $widget_ops = array('classname' => 'widget_many', 'description' => __('Widget which allows multiple instances')); 
     1352        $control_ops = array('width' => 400, 'height' => 350, 'id_base' => 'many'); 
     1353        $name = __('Many'); 
     1354 
     1355        // If there are none, we register the widget's existance with a generic template 
     1356        if ( !$options ) { 
     1357                wp_register_sidebar_widget( 'many-1', $name, 'widget_many', $widget_ops, array( 'number' => -1 ) ); 
     1358                wp_register_widget_control( 'many-1', $name, 'widget_many_control', $control_ops, array( 'number' => -1 ) ); 
     1359        } 
     1360 
     1361        foreach ( array_keys($options) as $o ) { 
     1362                // Old widgets can have null values for some reason 
     1363                if ( !isset($options[$o]['something']) ) // we used 'something' above in our exampple.  Replace with with whatever your real data are. 
     1364                        continue; 
     1365 
     1366                // $id should look like {$id_base}-{$o} 
     1367                $id = "many-$o"; // Never never never translate an id 
     1368                wp_register_sidebar_widget( $id, $name, 'wp_widget_text', $widget_ops, array( 'number' => $o ) ); 
     1369                wp_register_widget_control( $id, $name, 'wp_widget_text_control', $control_ops, array( 'number' => $o ) ); 
     1370        } 
     1371} 
     1372 
     1373// This is important 
     1374add_action( 'widgets_init', 'widget_many_register' ) 
     1375 
     1376*/ 
     1377 
     1378?> 
  • wp-includes/script-loader.php

     
    7979 
    8080                $this->add( 'jquery', '/wp-includes/js/jquery/jquery.js', false, '1.1.4'); 
    8181                $this->add( 'jquery-form', '/wp-includes/js/jquery/jquery.form.js', array('jquery'), '1.0.3'); 
    82                 $this->add( 'interface', '/wp-includes/js/jquery/interface.js', array('jquery'), '1.2'); 
     82                $this->add( 'interface', '/wp-includes/js/jquery/interface.js', array('jquery'), '1.2' ); 
    8383                $this->add( 'dimensions', '/wp-includes/js/jquery/jquery.dimensions.min.js', array('jquery'), '1.1.2'); 
    8484                $this->add( 'suggest', '/wp-includes/js/jquery/suggest.js', array('dimensions'), '1.1'); 
    8585                $this->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array('jquery'), '20'); 
     
    143143                                'saveText' => attribute_escape(__('Save &raquo;')), 
    144144                                'confirmText' => __("Are you sure you want to delete the file '%title%'?\nClick ok to delete or cancel to go back.") 
    145145                        ) ); 
     146                        $this->add( 'admin-widgets', '/wp-admin/js/widgets.js', array( 'interface' ), mt_rand() ); 
    146147                } 
    147148        } 
    148149 
  • wp-admin/admin-ajax.php

     
    11<?php 
     2define('DOING_AJAX', true); 
     3 
    24require_once('../wp-config.php'); 
    35require_once('includes/admin.php'); 
    46 
    5 define('DOING_AJAX', true); 
    6  
    77if ( !is_user_logged_in() ) 
    88        die('-1'); 
    99 
  • wp-admin/includes/widgets.php

     
     1<?php 
     2 
     3// $_search is unsanitized 
     4function wp_list_widgets( $show = 'all', $_search = false ) { 
     5        global $wp_registered_widgets, $sidebars_widgets; 
     6        if ( $_search ) { 
     7                // sanitize 
     8                $search = preg_replace( '/[^\w\s]/', '', $_search ); 
     9                // array of terms 
     10                $search_terms = preg_split( '/[\s]/', $search, -1, PREG_SPLIT_NO_EMPTY ); 
     11        } else { 
     12                $search_terms = array(); 
     13        } 
     14 
     15        if ( !in_array( $show, array( 'all', 'unused', 'used' ) ) ) 
     16                $show = 'all'; 
     17?> 
     18 
     19        <ul id='widget-list'> 
     20                <?php 
     21                $no_widgets_shown = true; 
     22                $already_shown = array(); 
     23                foreach ( $wp_registered_widgets as $name => $widget ) : 
     24                        if ( in_array( $widget['callback'], $already_shown ) ) 
     25                                continue; 
     26                        $already_shown[] = $widget['callback']; 
     27 
     28                        if ( $search_terms ) { 
     29                                $hit = false; 
     30                                // Simple case-insensitive search.  Boolean OR. 
     31                                $search_text = preg_replace( '/[^\w]/', '', $widget['name'] ); 
     32                                if ( isset($widget['description']) ) 
     33                                        $search_text .= preg_replace( '/[^\w]/', '', $widget['description'] ); 
     34 
     35                                foreach ( $search_terms as $search_term ) { 
     36                                        if ( stristr( $search_text, $search_term ) ) { 
     37                                                $hit = true; 
     38                                                break; 
     39                                        } 
     40                                } 
     41                                if ( !$hit ) 
     42                                        continue; 
     43                        } 
     44 
     45                        $sidebar = is_active_widget( $widget['callback'] ); 
     46                        if ( ( 'unused' == $show && $sidebar ) || ( 'used' == $show && !$sidebar ) ) 
     47                                continue; 
     48 
     49                        ob_start(); 
     50                                wp_widget_control( 'no-key', $widget['id'], 'template' ); 
     51                        $widget_control_template = ob_get_contents(); 
     52                        ob_end_clean(); 
     53 
     54                        if ( !$sidebar || false !== strpos( $widget_control_template, '%i%' ) ) { 
     55                                $action = 'add';  
     56                                $add_url = wp_nonce_url( add_query_arg( array( 
     57                                        'sidebar' => $sidebar, 
     58                                        'add' => $widget['id'], 
     59                                        'key' => false, 
     60                                        'edit' => false 
     61                                ) ), "add-widget_$widget[id]" ); 
     62                        } else { 
     63                                $action = 'edit'; 
     64                                $edit_url = add_query_arg( array( 
     65                                        'sidebar' => $sidebar, 
     66                                        'edit' => $widget['id'], 
     67                                        'key' => array_search( $widget['id'], $sidebars_widgets[$sidebar] ), 
     68                                ) ); 
     69                                $widget_control_template = "<textarea>$widget_control_template</textarea>"; 
     70                        } 
     71 
     72                        $no_widgets_shown = false; 
     73 
     74                ?> 
     75 
     76                <li id="widget-list-item-<?php echo attribute_escape( $widget['id'] ); ?>" class="widget-list-item"> 
     77                        <h4 class="widget-title widget-draggable"> 
     78 
     79                                <?php echo wp_specialchars( $widget['name'] ); ?> 
     80 
     81                                <?php if ( 'add' == $action ) : ?> 
     82 
     83                                <a class="widget-action widget-control-add" href="<?php echo $add_url; ?>"><?php _e( 'Add' ); ?></a> 
     84 
     85                                <?php elseif ( 'edit' == $action ) : 
     86                                        // We echo a hidden edit link for the sake of the JS.  Edit links are shown (needlessly?) after a widget is added. 
     87                                ?> 
     88 
     89                                <a class="widget-action widget-control-edit" href="<?php echo $edit_url; ?>" style="display: none;"><?php _e( 'Edit' ); ?></a> 
     90 
     91                                <?php endif; ?> 
     92 
     93                        </h4> 
     94 
     95 
     96                        <ul id="widget-control-info-<?php echo $widget['id']; ?>" class="widget-control-info"> 
     97 
     98                                <?php echo $widget_control_template; ?> 
     99 
     100                        </ul> 
     101 
     102                        <?php if ( 'add' == $action ) : ?> 
     103                        <?php endif; ?> 
     104 
     105                        <div class="widget-description"> 
     106                                <?php echo wp_widget_description( $widget['id'] ); ?> 
     107                        </div> 
     108 
     109                        <br class="clear" /> 
     110 
     111                </li> 
     112 
     113                <?php endforeach; if ( $no_widgets_shown ) : ?> 
     114                 
     115                <li><?php _e( 'No matching widgets' ); ?></li> 
     116 
     117                <?php endif; ?> 
     118 
     119        </ul> 
     120<?php 
     121} 
     122 
     123function wp_list_widget_controls( $widgets, $edit_widget = -1 ) { 
     124?> 
     125 
     126                <ul class="widget-control-list"> 
     127 
     128<?php 
     129        foreach ( $widgets as $key => $widget ) 
     130                wp_widget_control( $key, $widget, $key == $edit_widget ? 'edit' : 'display' ); 
     131?> 
     132 
     133                </ul> 
     134 
     135<?php 
     136} 
     137 
     138 
     139/* 
     140 * Displays the control form for widget of type $widget at position $key. 
     141 * $display 
     142 *  == 'display': Normal, "closed" form. 
     143 *  == 'edit': "open" form 
     144 *  == 'template': generates a form template to be used by JS 
     145 */ 
     146function wp_widget_control( $key, $widget, $display = 'display' ) { 
     147        static $i = 0; 
     148        global $wp_registered_widgets, $wp_registered_widget_controls; 
     149        $control = $wp_registered_widget_controls[$widget]; 
     150        $widget  = $wp_registered_widgets[$widget]; 
     151 
     152        $id_format = $widget['id']; 
     153        if ( 'template' == $display && isset($control['params'][0]['number']) ) { 
     154                // number == -1 implies a template where id numbers are replaced by a generic '%i%' 
     155                $control['params'][0]['number'] = -1; 
     156                // if given, id_base means widget id's should be constructed like {$id_base}-{$id_number} 
     157                if ( isset($control['id_base']) ) 
     158                        $id_format = $control['id_base'] . '-%i%'; 
     159        } 
     160?> 
     161 
     162                <li id="widget-list-control-item-<?php echo ++$i; ?>-<?php echo $widget['id']; ?>" class="widget-list-control-item widget-sortable"> 
     163                        <h4 class="widget-title"> 
     164 
     165                                <?php echo $widget['name']; // TODO: Up/Down links for noJS reordering? ?> 
     166 
     167                                <?php if ( 'edit' == $display ) : ?> 
     168 
     169                                <a class="widget-action widget-control-edit" href="<?php echo remove_query_arg( array( 'edit', 'key' ) ); ?>"><?php _e('Cancel'); ?></a> 
     170 
     171                                <?php else : ?> 
     172 
     173                                <a class="widget-action widget-control-edit" href="<?php echo add_query_arg( array( 'edit' => $id_format, 'key' => $key ) ); ?>"><?php _e('Edit'); ?></a> 
     174 
     175                                <?php endif; ?> 
     176 
     177                        </h4> 
     178 
     179                        <div class="widget-control"<?php if ( 'edit' == $display ) echo ' style="display: block;"'; ?>> 
     180 
     181                                <?php 
     182                                if ( $control ) 
     183                                        call_user_func_array( $control['callback'], $control['params'] ); 
     184                                else 
     185                                        echo '<p>' . __('There are no options for this widget.') . '</p>'; 
     186                                ?> 
     187 
     188                                <input type="hidden" name="widget-id[]" value="<?php echo $id_format; ?>" /> 
     189                                <input type="hidden" class="widget-width" value="<?php echo $control['width']; ?>" /> 
     190 
     191                                <div class="widget-control-actions"> 
     192 
     193                                        <?php if ( $control && 'edit' != $display ) : ?> 
     194 
     195                                        <a class="widget-action widget-control-save edit alignleft" href="#save:<?php echo $id_format; ?>"><?php _e('Save'); ?></a> 
     196 
     197                                        <?php endif; ?> 
     198 
     199                                        <a class="widget-action widget-control-remove delete alignright" href="<?php echo add_query_arg( array( 'remove' => $id_format, 'key' => $key ), wp_nonce_url( null, "remove-widget_$widget[id]" ) ); ?>"><?php _e('Remove'); ?></a> 
     200                                        <br class="clear" /> 
     201                                </div> 
     202                        </div> 
     203                </li> 
     204 
     205<?php 
     206} 
     207 
     208function temp_widget_css() { 
     209?> 
     210 
     211<style type="text/css"> 
     212/* 2 column liquid layout */ 
     213div.widget-liquid-left-holder { 
     214        float: left; 
     215        clear: left; 
     216        width: 100%; 
     217        margin-right: -310px; 
     218} 
     219 
     220div.widget-liquid-left { 
     221        margin-right: 310px; 
     222} 
     223 
     224div.widget-liquid-right { 
     225        float: right; 
     226        clear: right; 
     227        width: 300px; 
     228} 
     229 
     230p.submit { 
     231        clear: both; 
     232} 
     233 
     234/* pasitioning etc. */ 
     235form#widgets-filter { 
     236        position: relative; 
     237} 
     238 
     239p#widget-search { 
     240        position: absolute; 
     241        right: 0; 
     242        top: 0; 
     243        margin: 0; 
     244} 
     245 
     246ul#widget-list { 
     247        list-style: none; 
     248        margin: 0; 
     249        padding: 0; 
     250} 
     251 
     252ul#widget-list li.widget-list-item { 
     253        padding: .7em 1em; 
     254        margin: 0; 
     255        border-top:    1px solid #ccc; 
     256        border-bottom: 1px solid #ccc; 
     257        background-color: transparent; 
     258        line-height: 1; 
     259} 
     260 
     261ul#widget-list li.widget-list-item h4.widget-title { 
     262        position: relative; 
     263        margin: 0; 
     264        padding: .5em 1em; 
     265        width: 200px; 
     266        float: left; 
     267        background-color: #ccc; 
     268        color: #000; 
     269} 
     270 
     271#dragHelper h4.widget-title { 
     272        color: #fff; 
     273        background-color: #2683ae; 
     274        padding: .5em 1em; 
     275        margin: 0; 
     276} 
     277 
     278ul#widget-list li.widget-list-item div.widget-description { 
     279        display: block; 
     280        margin: 0 0 0 200px; 
     281        padding: 0 0 0 4em; 
     282} 
     283 
     284 
     285ul#widget-list li.widget-list-item ul.widget-control-info { 
     286        display: none; 
     287} 
     288 
     289div#sidebar-info { 
     290        padding: 0 1em; 
     291        margin-bottom: 1em; 
     292} 
     293 
     294ul.widget-control-list { 
     295        list-style: none; 
     296        margin: 0; 
     297        padding: 0 1em; 
     298} 
     299 
     300li.widget-list-control-item { 
     301        background-color: #eaf3fa; 
     302        margin: 0 0 1em; 
     303} 
     304 
     305li.widget-list-control-item h4, #dragHelper li.widget-list-control-item h4 { 
     306        position: relative; 
     307        margin: 0; 
     308        background-color: #2683ae; 
     309        padding: .5em 1em; 
     310        color: #fff; 
     311} 
     312 
     313div.widget-control a.widget-action, div.widget-control a.widget-action:hover { 
     314        padding: .5em 1em; 
     315} 
     316 
     317h4.widget-title a { 
     318        position: absolute; 
     319        right: 1em; 
     320        text-decoration: underline; 
     321        border-bottom: none; 
     322} 
     323 
     324li.widget-list-control-item h4.widget-title a, li.widget-list-control-item h4.widget-title a:visited { 
     325        color: #fff; 
     326} 
     327 
     328li.widget-list-control-item h4.widget-title a:hover { 
     329        color: #fff; 
     330        text-decoration: none; 
     331        border-bottom: none; 
     332} 
     333 
     334li.widget-list-control-item div.widget-control { 
     335        display: none; 
     336        margin: 1em; 
     337        padding: 0 10px 0 0; /* Correction for padding, margin, border of inputs */ 
     338} 
     339 
     340li.widget-list-control-item div.widget-control p { 
     341        margin: 0 0 1em; 
     342        padding: 0; 
     343} 
     344 
     345ul.widget-control-list div.widget-control-actions { 
     346        margin-right: -10px; /* Correction for padding, margin, border of inputs */ 
     347        padding: 0 0 1em; 
     348} 
     349 
     350ul.widget-control-list .sorthelper { 
     351        background-color: #ccf3fa; 
     352 
     353} 
     354 
     355#current-widgets .drop-widget-here { 
     356        background-color: #ffc 
     357} 
     358 
     359ul.widget-control-list select option { 
     360} 
     361</style> 
     362 
     363<?php 
     364} 
     365 
     366add_action( 'admin_head', 'temp_widget_css' ); 
     367 
     368?> 
  • wp-admin/includes/admin.php

     
    1313require_once(ABSPATH . 'wp-admin/includes/theme.php'); 
    1414require_once(ABSPATH . 'wp-admin/includes/user.php'); 
    1515require_once(ABSPATH . 'wp-admin/includes/update.php'); 
     16require_once(ABSPATH . 'wp-admin/includes/widgets.php'); 
    1617 
    1718require_once(ABSPATH . WPINC . '/registration.php'); 
    1819 
  • wp-admin/js/widgets.js

     
     1jQuery(function($) { 
     2        $('.noscript-action').remove(); 
     3 
     4        // TODO: i18n 
     5        var addText  = 'Add'; 
     6        var editText = 'Edit'; 
     7        var cancText = 'Cancel'; 
     8        var increment = 1; 
     9 
     10        // Open or close widget control form 
     11        var toggleWidget = function( li ) { 
     12                var width = li.find('input.widget-width').val(); 
     13                return li.children('div.widget-control').each( function() { 
     14                        var t = $(this); 
     15                        if ( t.is(':visible') ) { 
     16                                t.animate( { height: 'hide' } ); 
     17                                if ( width > 250 ) 
     18                                        li.animate( { marginLeft: 0 } ); 
     19                                t.siblings('h4').children('a').text( editText ); 
     20                        } else { 
     21                                t.animate( { height: 'show' } ); 
     22                                if ( width > 250 ) 
     23                                        li.animate( { marginLeft: ( width - 250 ) * -1 } ); 
     24                                t.siblings('h4').children('a').text( cancText ); 
     25                        } 
     26                } ).end(); 
     27        }; 
     28 
     29        // onclick for edit links 
     30        var editClick = function() { 
     31                var q = wpAjax.unserialize( this.href ); 
     32                // if link is in available widgets list, make sure it points to the current sidebar 
     33                if ( ( q.sidebar && q.sidebar == $('#sidebar').val() ) || q.add ) { 
     34                        var w = q.edit || q.add; 
     35                        toggleWidget( $('#current-sidebar .widget-control-list input[@name^="widget-id"][@value=' + w + ']').parents('li:first') ).blur(); 
     36                        return false; 
     37                } else if ( q.sidebar ) { // otherwise, redirect to correct page 
     38                        return true; 
     39                } 
     40 
     41                // If link is in current widgets list, just open the form 
     42                toggleWidget( $(this).parents('li:first') ).blur(); 
     43                return false; 
     44        }; 
     45 
     46        // onclick for add links 
     47        var addClick = function() { 
     48                var oldLi = $(this).parents('li:first').find('ul.widget-control-info li'); 
     49                var newLi = oldLi.clone(); 
     50 
     51                if ( newLi.html().match( /%i%/ ) ) { 
     52                        // supplid form is a template, replace %i% by unique id 
     53                        var i = $('#generated-time').val() + increment.toString(); 
     54                        increment++; 
     55                        newLi.html( newLi.html().replace( /%i%/g, i ) ); 
     56                } else { 
     57                        $(this).text( editText ).unbind().click( editClick ); 
     58                        // save form content in textarea so we don't have any conflicting HTML ids 
     59                        oldLi.html( '<textarea>' + oldLi.html() + '</textarea>' ); 
     60                } 
     61 
     62                // add event handlers 
     63                addWidgetControls( newLi ); 
     64 
     65                // add widget to sidebar sortable 
     66                widgetSortable.append( newLi ).SortableAddItem( newLi[0] ); 
     67 
     68                // increment widget counter 
     69                var n = parseInt( $('#widget-count').text(), 10 ) + 1; 
     70                $('#widget-count').text( n.toString() ) 
     71 
     72                return false; 
     73        }; 
     74 
     75        // add event handlers to all links found in context 
     76        var addWidgetControls = function( context ) { 
     77                if ( !context ) 
     78                        context = document; 
     79                 
     80                $('a.widget-control-edit', context).click( editClick ); 
     81 
     82                // onclick for save links 
     83                $('a.widget-control-save', context).click( function() { 
     84                        toggleWidget( $(this).parents('li:first') ).blur() 
     85                        return false; 
     86                } ); 
     87 
     88                // onclick for remove links 
     89                $('a.widget-control-remove', context).click( function() { 
     90                        var w = $(this).parents('li:first').find('input[@name^="widget-id"]').val(); 
     91                        $(this).parents('li:first').remove(); 
     92                        var t = $('#widget-list ul#widget-control-info-' + w + ' textarea'); 
     93                        t.parent().html( t.text() ).parents('li.widget-list-item:first').children( 'h4' ).children('a.widget-action') 
     94                                .show().text( addText ).unbind().click( addClick ); 
     95                        var n = parseInt( $('#widget-count').text(), 10 ) - 1; 
     96                        $('#widget-count').text( n.toString() ) 
     97                        return false; 
     98                } ); 
     99        } 
     100 
     101        addWidgetControls(); 
     102 
     103        $('a.widget-control-add').click( addClick ); 
     104 
     105        // initialize sortable 
     106        var widgetSortable = $('#current-sidebar .widget-control-list').Sortable( { 
     107                accept: 'widget-sortable', 
     108                helperclass: 'sorthelper', 
     109                handle: 'h4.widget-title' 
     110        } ); 
     111 
     112}); 
  • wp-admin/widgets.php

     
    11<?php 
    22 
    3 require_once 'admin.php'; 
     3require_once( 'admin.php' ); 
    44 
    55if ( ! current_user_can('switch_themes') ) 
    66        wp_die( __( 'Cheatin&#8217; uh?' )); 
    77 
    8 wp_enqueue_script('interface'); 
     8wp_enqueue_script( array( 'wp-lists', 'admin-widgets' ) ); 
    99 
    10 function wp_widgets_admin_head() { 
    11         global $wp_registered_sidebars, $wp_registered_widgets, $wp_registered_widget_controls; 
    12 ?> 
    13         <?php wp_admin_css( 'css/widgets' ); ?> 
    14         <!--[if IE 7]> 
    15         <style type="text/css"> 
    16                 #palette { float: <?php echo ( get_bloginfo( 'text_direction' ) == 'rtl' ) ? 'right' : 'left'; ?>; } 
    17         </style> 
    18         <![endif]--> 
    19 <?php 
     10do_action( 'sidebar_admin_setup' ); 
    2011 
    21         $cols = array(); 
    22         foreach ( $wp_registered_sidebars as $index => $sidebar ) { 
    23                 $cols[] = '\'' . $index . '\''; 
    24         } 
    25         $cols = implode( ', ', $cols ); 
     12$title = __( 'Widgets' ); 
     13$parent_file = 'themes.php'; 
    2614 
    27         $widgets = array(); 
    28         foreach ( $wp_registered_widgets as $name => $widget ) { 
    29                 $widgets[] = '\'' . $widget['id'] . '\''; 
    30         } 
    31         $widgets = implode( ', ', $widgets ); 
     15// $sidebar = What sidebar are we editing? 
     16if ( isset($_GET['sidebar']) && isset($wp_registered_sidebars[$_GET['sidebar']]) ) { 
     17        $sidebar = attribute_escape( $_GET['sidebar'] ); 
     18} elseif ( is_array($wp_registered_sidebars) && !empty($wp_registered_sidebars) ) { 
     19        // By default we look at the first defined sidebar 
     20        $sidebar = array_shift( array_keys($wp_registered_sidebars) ); 
     21} else { 
     22        // If no sidebars, die. 
     23        require_once( 'admin-header.php' ); 
    3224?> 
    33 <script type="text/javascript"> 
    34 // <![CDATA[ 
    35         var cols = [<?php echo $cols; ?>]; 
    36         var widgets = [<?php echo $widgets; ?>]; 
    37         var controldims = new Array; 
    38         <?php foreach ( $wp_registered_widget_controls as $name => $widget ) : ?> 
    39                 controldims['#<?php echo $widget['id']; ?>control'] = new Array; 
    40                 controldims['#<?php echo $widget['id']; ?>control']['width'] = <?php echo (int) $widget['width']; ?>; 
    41                 controldims['#<?php echo $widget['id']; ?>control']['height'] = <?php echo (int) $widget['height']; ?>; 
    42         <?php endforeach; ?> 
    43         function initWidgets() { 
    44         <?php foreach ( $wp_registered_widget_controls as $name => $widget ) : ?> 
    45                 jQuery('#<?php echo $widget['id']; ?>popper').click(function() {popControl('#<?php echo $widget['id']; ?>control');}); 
    46                 jQuery('#<?php echo $widget['id']; ?>closer').click(function() {unpopControl('#<?php echo $widget['id']; ?>control');}); 
    47                 jQuery('#<?php echo $widget['id']; ?>control').Draggable({handle: '.controlhandle', zIndex: 1000}); 
    48                 if ( true && window.opera ) 
    49                         jQuery('#<?php echo $widget['id']; ?>control').css('border','1px solid #bbb'); 
    50         <?php endforeach; ?> 
    51                 jQuery('#shadow').css('opacity','0'); 
    52                 jQuery(widgets).each(function(o) {o='#widgetprefix-'+o; jQuery(o).css('position','relative');} ); 
    53         } 
    54         function resetDroppableHeights() { 
    55                 var max = 6; 
    56                 jQuery.map(cols, function(o) { 
    57                         var c = jQuery('#' + o + ' li').length; 
    58                         if ( c > max ) max = c; 
    59                 }); 
    60                 var maxheight = 35 * ( max + 1); 
    61                 jQuery.map(cols, function(o) { 
    62                         height = 0 == jQuery('#' + o + ' li').length ? maxheight - jQuery('#' + o + 'placemat').height() : maxheight; 
    63                         jQuery('#' + o).height(height); 
    64                 }); 
    65         } 
    66         function maxHeight(elm) { 
    67                 htmlheight = document.body.parentNode.clientHeight; 
    68                 bodyheight = document.body.clientHeight; 
    69                 var height = htmlheight > bodyheight ? htmlheight : bodyheight; 
    70                 jQuery(elm).height(height); 
    71         } 
    72         function getViewportDims() { 
    73                 var x,y; 
    74                 if (self.innerHeight) { // all except Explorer 
    75                         x = self.innerWidth; 
    76                         y = self.innerHeight; 
    77                 } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode 
    78                         x = document.documentElement.clientWidth; 
    79                         y = document.documentElement.clientHeight; 
    80                 } else if (document.body) { // other Explorers 
    81                         x = document.body.clientWidth; 
    82                         y = document.body.clientHeight; 
    83                 } 
    84                 return new Array(x,y); 
    85         } 
    86         function dragChange(o) { 
    87                 var p = getViewportDims(); 
    88                 var screenWidth = p[0]; 
    89                 var screenHeight = p[1]; 
    90                 var elWidth = parseInt( jQuery(o).css('width') ); 
    91                 var elHeight = parseInt( jQuery(o).css('height') ); 
    92                 var elLeft = parseInt( jQuery(o).css('left') ); 
    93                 var elTop = parseInt( jQuery(o).css('top') ); 
    94                 if ( screenWidth < ( parseInt(elLeft) + parseInt(elWidth) ) ) 
    95                         jQuery(o).css('left', ( screenWidth - elWidth ) + 'px' ); 
    96                 if ( screenHeight < ( parseInt(elTop) + parseInt(elHeight) ) ) 
    97                         jQuery(o).css('top', ( screenHeight - elHeight ) + 'px' ); 
    98                 if ( elLeft < 1 ) 
    99                         jQuery(o).css('left', '1px'); 
    100                 if ( elTop < 1 ) 
    101                         jQuery(o).css('top', '1px'); 
    102         } 
    103         function popControl(elm) { 
    104                 var x = ( document.body.clientWidth - controldims[elm]['width'] ) / 2; 
    105                 var y = ( document.body.parentNode.clientHeight - controldims[elm]['height'] ) / 2; 
    106                 jQuery(elm).css({display: 'block', width: controldims[elm]['width'] + 'px', height: controldims[elm]['height'] + 'px', position: 'absolute', right: x + 'px', top: y + 'px', zIndex: '1000' }); 
    107                 jQuery(elm).attr('class','control'); 
    108                 jQuery('#shadow').click(function() {unpopControl(elm);}); 
    109                 window.onresize = function(){maxHeight('#shadow');dragChange(elm);}; 
    110                 popShadow(); 
    111         } 
    112         function popShadow() { 
    113                 maxHeight('#shadow'); 
    114                 jQuery('#shadow').css({zIndex: '999', display: 'block'}); 
    115                 jQuery('#shadow').fadeTo('fast', 0.2); 
    116         } 
    117         function unpopShadow() { 
    118                 jQuery('#shadow').fadeOut('fast', function() {jQuery('#shadow').hide()}); 
    119         } 
    120         function unpopControl(el) { 
    121                 jQuery(el).attr('class','hidden'); 
    122                 jQuery(el).hide(); 
    123                 unpopShadow(); 
    124         } 
    125         function serializeAll() { 
    126         <?php $i = 0; foreach ( $wp_registered_sidebars as $index => $sidebar ) : $i++; ?> 
    127                 var serial<?php echo $i ?> = jQuery.SortSerialize('<?php echo $index ?>'); 
    128                 jQuery('#<?php echo $index ?>order').attr('value',serial<?php echo $i ?>.hash.replace(/widgetprefix-/g, '')); 
    129         <?php endforeach; ?> 
    130         } 
    131         function updateAll() { 
    132                 jQuery.map(cols, function(o) { 
    133                         if ( jQuery('#' + o + ' li').length ) 
    134                                 jQuery('#'+o+'placemat span.handle').hide(); 
    135                         else 
    136                                 jQuery('#'+o+'placemat span.handle').show(); 
    137                 }); 
    138                 resetDroppableHeights(); 
    139         } 
    140         jQuery(document).ready( function() { 
    141                 updateAll(); 
    142                 initWidgets(); 
    143         }); 
    144 // ]]> 
    145 </script> 
     25 
     26        <div class="error"> 
     27                <p><?php _e( 'No Sidebars Defined' ); ?></p> 
     28        </div> 
     29 
     30        <div class="wrap">  
     31                <p><?php _e( 'You are seeing this message because the theme you are currently using isn&#8217;t widget-aware, meaning that it has no sidebars that you are able to change. For information on making your theme widget-aware, please <a href="http://automattic.com/code/widgets/themes/">follow these instructions</a>.' ); /* TODO: article on codex */; ?></p> 
     32        </div> 
     33 
    14634<?php 
     35        require_once( 'admin-footer.php' ); 
     36        exit; 
    14737} 
    148 add_action( 'admin_head', 'wp_widgets_admin_head' ); 
    149 do_action( 'sidebar_admin_setup' ); 
    15038 
    151 function wp_widget_draggable( $name ) { 
    152         global $wp_registered_widgets, $wp_registered_widget_controls; 
     39// These are the widgets grouped by sidebar 
     40$sidebars_widgets = wp_get_sidebars_widgets(); 
     41if ( empty( $sidebars_widgets ) ) 
     42        $sidebars_widgets = wp_get_widget_defaults(); 
    15343 
    154         if ( !isset( $wp_registered_widgets[$name] ) ) { 
    155                 return; 
    156         } 
     44// for the sake of PHP warnings 
     45if ( empty( $sidebars_widgets[$sidebar] ) ) 
     46        $sidebars_widgets[$sidebar] = array(); 
    15747 
    158         $sanitized_name = sanitize_title( $wp_registered_widgets[$name]['id'] ); 
    159         $link_title = __( 'Configure' ); 
    160         $popper = ( isset( $wp_registered_widget_controls[$name] ) ) 
    161                 ? ' <div class="popper" id="' . $sanitized_name . 'popper" title="' . $link_title . '">&#8801;</div>' 
    162                 : ''; 
     48$http_post = ( 'POST' == $_SERVER['REQUEST_METHOD'] ); 
    16349 
    164         $output = '<li class="module" id="widgetprefix-%1$s"><span class="handle">%2$s</span></li>'; 
     50// We're updating a sidebar 
     51if ( $http_post && isset($sidebars_widgets[$_POST['sidebar']]) ) { 
    16552 
    166         printf( $output, $sanitized_name, $wp_registered_widgets[$name]['name'] . $popper ); 
    167 } 
     53        /* Hack #1 
     54         * The widget_control is overloaded.  It updates the widget's options AND echoes out the widget's HTML form. 
     55         * Since we want to update before sending out any headers, we have to catchi it with an output buffer 
     56         */ 
     57        ob_start(); 
     58                /* There can be multiple widgets of the same type, but the widget_control for that 
     59                 * widget type needs only be called once. 
     60                 */ 
     61                $already_done = array(); 
    16862 
    169 $title = __( 'Widgets' ); 
    170 $parent_file = 'themes.php'; 
     63                foreach ( $wp_registered_widget_controls as $name => $control ) { 
     64                        if ( in_array( $control['callback'], $already_done ) ) 
     65                                continue; 
    17166 
    172 require_once 'admin-header.php'; 
     67                        if ( is_callable( $control['callback'] ) ) 
     68                                call_user_func_array( $control['callback'], $control['params'] ); 
     69                } 
     70        ob_end_clean(); 
    17371 
    174 if ( count( $wp_registered_sidebars ) < 1 ) { 
    175 ?> 
    176         <div class="wrap"> 
    177                 <h2><?php _e( 'No Sidebars Defined' ); ?></h2> 
     72        // Prophylactic.  Take out empty ids. 
     73        foreach ( (array) $_POST['widget-id'] as $key => $val ) 
     74                if ( !$val ) 
     75                        unset($_POST['widget-id'][$key]); 
    17876 
    179                 <p><?php _e( 'You are seeing this message because the theme you are currently using isn&#8217;t widget-aware, meaning that it has no sidebars that you are able to change. For information on making your theme widget-aware, please <a href="http://automattic.com/code/widgets/themes/">follow these instructions</a>.' ); /* TODO: article on codex */; ?></p> 
    180         </div> 
    181 <?php 
     77        // Reset the key numbering and stare 
     78        $new_sidebar = array_values( $_POST['widget-id'] ); 
     79        $sidebars_widgets[$_POST['sidebar']] = $new_sidebar; 
     80        wp_set_sidebars_widgets( $sidebars_widgets ); 
    18281 
    183         require_once 'admin-footer.php'; 
     82        // Re-register just in case 
     83        wp_widgets_init(); 
     84 
     85        wp_redirect( add_query_arg( 'message', 'updated' ) ); 
    18486        exit; 
    18587} 
    18688 
    187 $sidebars_widgets = wp_get_sidebars_widgets(); 
    18889 
    189 if ( empty( $sidebars_widgets ) ) { 
    190         $sidebars_widgets = wp_get_widget_defaults(); 
     90 
     91 
     92// What widget (if any) are we editing 
     93$edit_widget = -1; 
     94 
     95$query_args = array('add', 'remove', 'key', 'edit', '_wpnonce', 'message' ); 
     96 
     97if ( isset($_GET['add']) && $_GET['add'] ) { 
     98        // Add to the end of the sidebar 
     99        if ( isset($wp_registered_widgets[$_GET['add']]) ) { 
     100                check_admin_referer( "add-widget_$_GET[add]" ); 
     101                $sidebars_widgets[$sidebar][] = $_GET['add']; 
     102                wp_set_sidebars_widgets( $sidebars_widgets ); 
     103        } 
     104        wp_redirect( remove_query_arg( $query_args ) ); 
     105        exit; 
     106} elseif ( isset($_GET['remove']) && $_GET['remove'] && isset($_GET['key']) && is_numeric($_GET['key']) ) { 
     107        // Remove from sidebar the widget of type $_GET['remove'] and in position $_GET['key'] 
     108        $key = (int) $_GET['key']; 
     109        if ( -1 < $key && ( $keys = array_keys($sidebars_widgets[$sidebar], $_GET['remove']) ) && in_array($key, $keys) ) { 
     110                check_admin_referer( "remove-widget_$_GET[remove]" ); 
     111                unset($sidebars_widgets[$sidebar][$key]); 
     112                $sidebars_widgets[$sidebar] = array_values($sidebars_widgets[$sidebar]); 
     113                wp_set_sidebars_widgets( $sidebars_widgets ); 
     114        } 
     115        wp_redirect( remove_query_arg( $query_args ) ); 
     116        exit; 
     117} elseif ( isset($_GET['edit']) && $_GET['edit'] && isset($_GET['key']) && is_numeric($_GET['key']) ) { 
     118        // Edit widget of type $_GET['edit'] and position $_GET['key'] 
     119        $key = (int) $_GET['key']; 
     120        if ( -1 < $key && ( $keys = array_keys($sidebars_widgets[$sidebar], $_GET['edit']) ) && in_array($key, $keys) ) 
     121                $edit_widget = $key; 
    191122} 
    192123 
    193 if ( isset( $_POST['action'] ) ) { 
    194         check_admin_referer( 'widgets-save-widget-order' ); 
     124// Total number of registered sidebars 
     125$sidebar_widget_count = count($sidebars_widgets[$sidebar]); 
    195126 
    196         switch ( $_POST['action'] ) { 
    197                 case 'default' : 
    198                         $sidebars_widgets = wp_get_widget_defaults(); 
    199                         wp_set_sidebars_widgets( $sidebars_widgets ); 
    200                 break; 
     127// This is sort of lame since "widget" won't be converted to "widgets" in the JS 
     128if ( 1 < $sidebars_count = count($wp_registered_sidebars) ) 
     129        $sidebar_info_text = __ngettext( 'You are using %1$s widget in the "%2$s" sidebar.', 'You are using %1$s widgets in the "%2$s" sidebar.', $sidebar_widget_count ); 
     130else 
     131        $sidebar_info_text = __ngettext( 'You are using %1$s widget in the sidebar.', 'You are using %1$s widgets in the sidebar.', $sidebar_widget_count ); 
    201132 
    202                 case 'save_widget_order' : 
    203                         $sidebars_widgets = array(); 
    204133 
    205                         foreach ( $wp_registered_sidebars as $index => $sidebar ) { 
    206                                 $postindex = $index . 'order'; 
     134$sidebar_info_text = sprintf( wp_specialchars( $sidebar_info_text ), "<span id='widget-count'>$sidebar_widget_count</span>", $wp_registered_sidebars[$sidebar]['name'] ); 
    207135 
    208                                 parse_str( $_POST[$postindex], $order ); 
     136$page = isset($_GET['apage']) ? abs( (int) $_GET['apage'] ) : 1; 
    209137 
    210                                 $new_order = $order[$index]; 
     138/* TODO: Paginate widgets list 
     139$page_links = paginate_links( array( 
     140        'base'    => add_query_arg( 'apage', '%#%' ), 
     141        'format'  => '', 
     142        'total'   => ceil(($total = 105 )/ 10), 
     143        'current' => $page 
     144)); 
     145*/ 
     146$page_links = false; 
    211147 
    212                                 if ( is_array( $new_order ) ) { 
    213                                         foreach ( $new_order as $sanitized_name ) { 
    214                                                 foreach ( $wp_registered_widgets as $name => $widget ) { 
    215                                                         if ( $sanitized_name == $widget['id'] ) { 
    216                                                                 $sidebars_widgets[$index][] = $name; 
    217                                                         } 
    218                                                 } 
    219                                         } 
    220                                 } 
    221                         } 
     148// Unsanitized! 
     149$widget_search = isset($_GET['s']) ? $_GET['s'] : false; 
    222150 
    223                         wp_set_sidebars_widgets( $sidebars_widgets ); 
    224                 break; 
    225         } 
    226 } 
     151// Not entirely sure what all should be here 
     152$show_values = array( 
     153        ''       => $widget_search ? __( 'Show any widgets' ) : __( 'Show all widgets' ), 
     154        'unused' => __( 'Show unused widgets' ), 
     155        'used'   => __( 'Show used widgets' ) 
     156); 
    227157 
    228 ksort( $wp_registered_widgets ); 
     158$show = isset($_GET['show']) && isset($show_values[$_GET['show']]) ? attribute_escape( $_GET['show'] ) : false; 
    229159 
    230 $inactive_widgets = array(); 
    231160 
    232 foreach ( $wp_registered_widgets as $name => $widget ) { 
    233         $is_active = false; 
     161$messages = array( 
     162        'updated' => __('Changes saved.') 
     163); 
    234164 
    235         foreach ( $wp_registered_sidebars as $index => $sidebar ) { 
    236                 if ( is_array( $sidebars_widgets[$index] ) && in_array( $name, $sidebars_widgets[$index] ) ) { 
    237                         $is_active = true; 
    238                         break; 
    239                 } 
    240         } 
     165require_once( 'admin-header.php' ); 
    241166 
    242         if ( !$is_active ) { 
    243                 $inactive_widgets[] = $name; 
    244         } 
    245 } 
     167if ( isset($_GET['message']) && isset($messages[$_GET['message']]) ) : ?> 
    246168 
    247 $containers = array( 'palette' ); 
     169<div id="message" class="updated fade"><p><?php echo $messages[$_GET['message']]; ?></p></div> 
    248170 
    249 foreach ( $wp_registered_sidebars as $index => $sidebar ) { 
    250         $containers[] = $index; 
    251 } 
     171<?php endif; ?> 
    252172 
    253 $c_string = ''; 
     173<div class="wrap"> 
    254174 
    255 foreach ( $containers as $container ) { 
    256         $c_string .= '"' . $container . '",'; 
    257 } 
     175        <form id="widgets-filter" action="" method="get"> 
    258176 
    259 $c_string = substr( $c_string, 0, -1 ); 
     177        <h2><?php _e( 'Widgets' ); ?></h2> 
     178        <p id="widget-search"> 
     179                <input type="text" id="widget-search-input" name="s" value="<?php echo attribute_escape( $widget_search ); ?>" /> 
     180                <input type="submit" value="<?php _e( 'Search Widgets' ); ?>" /> 
     181        </p> 
    260182 
    261 if ( isset( $_POST['action'] ) ) { 
    262 ?> 
    263         <div class="fade updated" id="message"> 
    264                 <p><?php printf( __( 'Sidebar updated. <a href="%s">View site &raquo;</a>' ), get_bloginfo( 'url' ) . '/' ); ?></p> 
     183        <div class="widget-liquid-left-holder"> 
     184        <div id="available-widgets-filter" class="widget-liquid-left"> 
     185                <h3><?php printf( __('Available Widgets %s'), '<a href="#help:avaliable-widgets" class="wp-context-help">?</a>' ); ?></h3> 
     186                <p> 
     187                        <select name="show"> 
     188<?php foreach ( $show_values as $show_value => $show_text ) : $show_value = attribute_escape( $show_value ); ?> 
     189                                <option value='<?php echo $show_value; ?>'<?php selected( $show_value, $show ); ?>><?php echo wp_specialchars( $show_text ); ?></option> 
     190<?php endforeach; ?> 
     191                        </select> 
     192                        <input type="submit" value="<?php _e('Show' ); ?>" /> 
     193                </p> 
     194<?php if ( $page_links ) : ?> 
     195                <p class="pagenav"> 
     196                        <?php echo $page_links; ?> 
     197 
     198                </p> 
     199<?php endif; ?> 
    265200        </div> 
    266 <?php 
    267 } 
    268 ?> 
    269         <div class="wrap"> 
    270                 <h2><?php _e( 'Sidebar Arrangement' ); ?></h2> 
     201        </div> 
    271202 
    272                 <p><?php _e( 'You can drag and drop widgets onto your sidebar below.' ); ?></p> 
     203        <div id="available-sidebars" class="widget-liquid-right"> 
     204                <h3><?php printf( __('Current Widgets %s'), '<a href="#help:current-widgets" class="wp-context-help">?</a>' ); ?></h3> 
    273205 
    274                 <form id="sbadmin" method="post" onsubmit="serializeAll();"> 
    275                         <p class="submit"> 
    276                                 <input type="submit" value="<?php _e( 'Save Changes &raquo;' ); ?>" /> 
    277                         </p> 
    278                         <div id="zones"> 
    279                         <?php 
    280                                 foreach ( $wp_registered_sidebars as $index => $sidebar ) { 
    281                         ?> 
    282                                 <input type="hidden" id="<?php echo $index; ?>order" name="<?php echo $index; ?>order" value="" /> 
     206<?php if ( 1 < $sidebars_count ) : ?> 
    283207 
    284                                 <div class="dropzone"> 
    285                                         <h3><?php echo $sidebar['name']; ?></h3> 
     208                <p> 
     209                        <select id="sidebar-selector" name="sidebar"> 
     210<?php foreach ( $wp_registered_sidebars as $sidebar_id => $registered_sidebar ) : $sidebar_id = attribute_escape( $sidebar_id ); ?> 
     211                                <option value='<?php echo $sidebar_id; ?>'<?php selected( $sidebar_id, $sidebar ); ?>><?php echo wp_specialchars( $registered_sidebar['name'] ); ?></option> 
     212<?php endforeach; ?> 
     213                        </select> 
     214                        <input type="submit" value="<?php _e('Go' ); ?>" /> 
     215                </p> 
    286216 
    287                                         <div id="<?php echo $index; ?>placemat" class="placemat"> 
    288                                                 <span class="handle"> 
    289                                                         <h4><?php _e( 'Default Sidebar' ); ?></h4> 
    290                                                         <?php _e( 'Your theme will display its usual sidebar when this box is empty. Dragging widgets into this box will replace the usual sidebar with your customized sidebar.' ); ?> 
    291                                                 </span> 
    292                                         </div> 
     217<?php endif; ?> 
    293218 
    294                                         <ul id="<?php echo $index; ?>"> 
    295                                         <?php 
    296                                                 if ( is_array( $sidebars_widgets[$index] ) ) { 
    297                                                         foreach ( $sidebars_widgets[$index] as $name ) { 
    298                                                                 wp_widget_draggable( $name ); 
    299                                                         } 
    300                                                 } 
    301                                         ?> 
    302                                         </ul> 
    303                                 </div> 
    304                         <?php 
    305                                 } 
    306                         ?> 
     219        </div> 
    307220 
    308                         </div> 
     221        </form> 
    309222 
    310                         <div id="palettediv"> 
    311                                 <h3><?php _e( 'Available Widgets' ); ?></h3> 
     223        <div id="widget-content" class="widget-liquid-left-holder"> 
    312224 
    313                                 <ul id="palette"> 
    314                                 <?php 
    315                                         foreach ( $inactive_widgets as $name ) { 
    316                                                 wp_widget_draggable( $name ); 
    317                                         } 
    318                                 ?> 
    319                                 </ul> 
    320                         </div> 
     225                <div id="available-widgets" class="widget-liquid-left"> 
    321226 
    322                         <script type="text/javascript"> 
    323                         // <![CDATA[ 
    324                                 jQuery(document).ready(function(){ 
    325                         <?php foreach ( $containers as $container ) { ?> 
    326                                         jQuery('ul#<?php echo $container; ?>').Sortable({ 
    327                                                 accept: 'module', activeclass: 'activeDraggable', opacity: 0.8, revert: true, onStop: updateAll 
    328                                         }); 
    329                         <?php } ?> 
    330                                 }); 
    331                         // ]]> 
    332                         </script> 
     227                        <?php wp_list_widgets( $show, $widget_search ); // This lists all the widgets for the query ( $show, $search ) ?> 
    333228 
    334                         <p class="submit"> 
    335                         <?php wp_nonce_field( 'widgets-save-widget-order' ); ?> 
    336                                 <input type="hidden" name="action" id="action" value="save_widget_order" /> 
    337                                 <input type="submit" value="<?php _e( 'Save Changes &raquo;' ); ?>" /> 
     229<?php if ( $page_links ) : ?> 
     230                        <p class="pagenav"> 
     231                                <?php echo $page_links; ?> 
     232 
    338233                        </p> 
     234<?php endif; ?> 
    339235 
    340                         <div id="controls"> 
    341                         <?php foreach ( $wp_registered_widget_controls as $name => $widget ) { ?> 
    342                                 <div class="hidden" id="<?php echo $widget['id']; ?>control"> 
    343                                         <span class="controlhandle"><?php echo $widget['name']; ?></span> 
    344                                         <span id="<?php echo $widget['id']; ?>closer" class="controlcloser">&#215;</span> 
    345                                         <div class="controlform"> 
    346                                         <?php call_user_func_array( $widget['callback'], $widget['params'] ); ?> 
    347                                         </div> 
    348                                 </div> 
    349                         <?php } ?> 
    350                         </div> 
    351                 </form> 
     236                </div> 
     237        </div> 
    352238 
    353                 <br class="clear" /> 
     239        <form id="widget-controls" action="" method="post"> 
     240 
     241        <div id="current-widgets-head" class="widget-liquid-right"> 
     242 
     243                <div id="sidebar-info"> 
     244                        <p><?php echo $sidebar_info_text; ?></p> 
     245                        <p><?php _e( 'Add more from the Available Widgets section.' ); ?></p> 
     246                </div> 
     247 
    354248        </div> 
    355249 
    356         <div id="shadow"> </div> 
     250        <div id="current-widgets" class="widget-liquid-right"> 
     251                <input type="hidden" id='sidebar' name='sidebar' value="<?php echo $sidebar; ?>" /> 
    357252 
    358         <?php do_action( 'sidebar_admin_page' ); ?> 
     253                <div id="current-sidebar"> 
    359254 
    360 <?php require_once 'admin-footer.php'; ?> 
     255                        <?php wp_list_widget_controls( $sidebars_widgets[$sidebar], $edit_widget ); // Show the control forms for each of the widgets in this sidebar ?> 
     256 
     257                </div> 
     258        </div> 
     259 
     260        <p class="submit"> 
     261                <input type="hidden" id="generated-time" name="generated-time" value="<?php echo time(); ?>" /> 
     262                <input type="submit" name="save-widgets" value="<?php _e( 'Save Changes' ); ?>" /> 
     263        </p> 
     264 
     265        </form> 
     266 
     267</div> 
     268 
     269<?php do_action( 'sidebar_admin_page' ); ?> 
     270 
     271<?php require_once( 'admin-footer.php' ); ?> 
     272