From 0632395ad623deefe472837f766c0e0b15dc2268 Mon Sep 17 00:00:00 2001 From: azaozz Date: Fri, 22 May 2009 12:08:51 +0000 Subject: [PATCH] Fix saving and deleting of widgets settings for no-js and for some non-standard widgets, run the actions from the widgets screen when saving with ajax, see #9511 git-svn-id: http://svn.automattic.com/wordpress/trunk@11427 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/admin-ajax.php | 59 +++----- wp-admin/css/widgets.css | 4 +- wp-admin/widgets.php | 243 +++++++++++++++----------------- wp-includes/default-widgets.php | 5 +- wp-includes/widgets.php | 82 +++++------ 5 files changed, 172 insertions(+), 221 deletions(-) diff --git a/wp-admin/admin-ajax.php b/wp-admin/admin-ajax.php index 52f70c4a0a..31ee3282dc 100644 --- a/wp-admin/admin-ajax.php +++ b/wp-admin/admin-ajax.php @@ -1282,64 +1282,34 @@ case 'save-widget' : unset( $_POST['savewidgets'], $_POST['action'] ); + do_action('load-widgets.php'); + do_action('widgets.php'); + do_action('sidebar_admin_setup'); + $id_base = $_POST['id_base']; - $number = isset($_POST['widget_number']) ? $_POST['widget_number'] : ''; + $widget_id = $_POST['widget-id']; $sidebar_id = $_POST['sidebar']; + $sidebars = wp_get_sidebars_widgets(); $sidebar = isset($sidebars[$sidebar_id]) ? $sidebars[$sidebar_id] : array(); // delete if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) { - $del_id = $_POST['widget-id']; - $widget = isset($wp_registered_widgets[$del_id]) ? $wp_registered_widgets[$del_id] : false; - if ( !in_array($del_id, $sidebar, true) ) + if ( !isset($wp_registered_widgets[$widget_id]) ) die('-1'); - if ( $widget ) { - $option = str_replace( '-', '_', 'widget_' . $id_base ); - $data = get_option($option); - - if ( isset($widget['params'][0]['number']) ) { - $number = $widget['params'][0]['number']; - if ( is_array($data) && isset($data[$number]) ) { - unset( $data[$number] ); - update_option($option, $data); - } - } else { - if ( $data ) { - $data = array(); - update_option($option, $data); - } - } - } - - $sidebar = array_diff( $sidebar, array($del_id) ); - $sidebars[$sidebar_id] = $sidebar; - wp_set_sidebars_widgets($sidebars); - - echo "deleted:$del_id"; - die(); + $sidebar = array_diff( $sidebar, array($widget_id) ); + $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1'); } + $_POST['widget-id'] = $sidebar; - // save foreach ( (array) $wp_registered_widget_updates as $name => $control ) { + if ( $name == $id_base ) { if ( !is_callable( $control['callback'] ) ) continue; - if ( $number ) { - // don't delete other instances of the same multi-widget - foreach ( $sidebar as $_widget_id ) { - $_widget = $wp_registered_widgets[$_widget_id]; - - if ( isset($_widget['params']) && - is_array($_widget['params'][0]) && - array_key_exists('number', $_widget['params'][0]) ) - unset($wp_registered_widgets[$_widget_id]['params'][0]['number']); - } - } - ob_start(); call_user_func_array( $control['callback'], $control['params'] ); ob_end_clean(); @@ -1347,6 +1317,13 @@ case 'save-widget' : } } + if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) { + $sidebars[$sidebar_id] = $sidebar; + wp_set_sidebars_widgets($sidebars); + echo "deleted:$widget_id"; + die(); + } + die('1'); break; default : diff --git a/wp-admin/css/widgets.css b/wp-admin/css/widgets.css index 268f95d76a..c2e170b9c4 100644 --- a/wp-admin/css/widgets.css +++ b/wp-admin/css/widgets.css @@ -240,7 +240,7 @@ div#sidebar-info { display: block; font-size: 11px; font-weight: normal; - line-height: 24px; + line-height: 26px; padding: 0 8px 0 0; } @@ -256,7 +256,7 @@ a.widget-control-edit { #available-widgets .widget-control-edit .add, #widgets-right .widget-control-edit .edit, #wp_inactive_widgets .widget-control-edit .edit { - display: block; + display: inline; } .editwidget { diff --git a/wp-admin/widgets.php b/wp-admin/widgets.php index 79258c9c7f..2c7fc98967 100644 --- a/wp-admin/widgets.php +++ b/wp-admin/widgets.php @@ -47,8 +47,11 @@ function retrieve_widgets() { unset( $sidebars_widgets['array_version'] ); - $diff = array_diff( array_keys($sidebars_widgets), $sidebars ); - if ( empty($diff) ) + $old = array_keys($sidebars_widgets); + sort($old); + sort($sidebars); + + if ( $old == $sidebars ) return; // Move the known-good ones first @@ -68,6 +71,7 @@ function retrieve_widgets() { } // discard invalid, theme-specific widgets from sidebars + $shown_widgets = array(); foreach ( $_sidebars_widgets as $sidebar => $widgets ) { if ( !is_array($widgets) ) continue; @@ -78,39 +82,24 @@ function retrieve_widgets() { $_widgets[] = $widget; } $_sidebars_widgets[$sidebar] = $_widgets; + $shown_widgets = array_merge($shown_widgets, $_widgets); } $sidebars_widgets = $_sidebars_widgets; unset($_sidebars_widgets, $_widgets); // find hidden/lost multi-widget instances - $shown_widgets = array(); - foreach ( $sidebars_widgets as $sidebar ) { - if ( is_array($sidebar) ) - $shown_widgets = array_merge($shown_widgets, $sidebar); - } - - $all_widgets = array(); - foreach ( $wp_registered_widget_updates as $key => $val ) { - if ( isset($val['id_base']) ) - $all_widgets[] = $val['id_base']; - else - $all_widgets[] = $key; - } - - $all_widgets = array_unique($all_widgets); - $lost_widgets = array(); - foreach ( $all_widgets as $name ) { - $data = get_option( str_replace('-', '_', "widget_$name") ); - if ( is_array($data) ) { - foreach ( $data as $num => $value ) { - if ( !is_numeric($num) ) // skip single widgets, some don't delete their settings - continue; - if ( is_array($value) && !in_array("$name-$num", $shown_widgets, true) ) - $lost_widgets[] = "$name-$num"; - } - } + foreach ( $wp_registered_widgets as $key => $val ) { + if ( in_array($key, $shown_widgets, true) ) + continue; + + $number = preg_replace('/.+?-([0-9]+)$/', '$1', $key); + + if ( 2 > (int) $number ) + continue; + + $lost_widgets[] = $key; } $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']); @@ -142,74 +131,59 @@ if ( isset($_POST['savewidget']) || isset($_POST['removewidget']) ) { $widget_id = $_POST['widget-id']; check_admin_referer("save-delete-widget-$widget_id"); - $sidebar_id = $_POST['insidebar']; + $number = isset($_POST['multi_number']) ? (int) $_POST['multi_number'] : ''; + if ( $number ) { + foreach ( $_POST as $key => $val ) { + if ( is_array($val) && preg_match('/__i__|%i%/', key($val)) ) { + $_POST[$key] = array( $number => array_shift($val) ); + break; + } + } + } + + $sidebar_id = $_POST['sidebar']; $position = isset($_POST[$sidebar_id . '_position']) ? (int) $_POST[$sidebar_id . '_position'] - 1 : 0; - $_POST['sidebar'] = $sidebar_id; $id_base = $_POST['id_base']; - $number = isset($_POST['multi_number']) ? $_POST['multi_number'] : ''; $sidebar = isset($sidebars_widgets[$sidebar_id]) ? $sidebars_widgets[$sidebar_id] : array(); // delete if ( isset($_POST['removewidget']) && $_POST['removewidget'] ) { - $widget = isset($wp_registered_widgets[$widget_id]) ? $wp_registered_widgets[$widget_id] : false; - if ( !in_array($widget_id, $sidebar, true) || !$widget ) { + if ( !in_array($widget_id, $sidebar, true) ) { wp_redirect('widgets.php?error=0'); exit; } - $option = str_replace( '-', '_', 'widget_' . $id_base ); - $data = get_option($option); - - if ( isset($widget['params'][0]['number']) ) { - $number = $widget['params'][0]['number']; - if ( is_array($data) && isset($data[$number]) ) { - unset( $data[$number] ); - update_option($option, $data); - } - } else { - if ( $data ) { - $data = array(); - update_option($option, $data); - } - } - $sidebar = array_diff( $sidebar, array($widget_id) ); - } else { - // save - foreach ( (array) $wp_registered_widget_updates as $name => $control ) { - if ( $name != $id_base || !is_callable($control['callback']) ) - continue; + $_POST = array('sidebar' => $sidebar_id, 'widget-' . $id_base => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1'); + } - if ( $number ) { - // don't delete other instances of the same multi-widget - foreach ( $sidebar as $_widget_id ) { - if ( isset($wp_registered_widgets[$_widget_id]['params'][0]['number']) ) - unset($wp_registered_widgets[$_widget_id]['params'][0]['number']); - } - $widget_id = "$id_base-$number"; - } + $_POST['widget-id'] = $sidebar; - ob_start(); - call_user_func_array( $control['callback'], $control['params'] ); - ob_end_clean(); + foreach ( (array) $wp_registered_widget_updates as $name => $control ) { + if ( $name != $id_base || !is_callable($control['callback']) ) + continue; - // remove old position - $sidebar = array_diff( $sidebar, array($widget_id) ); - foreach ( $sidebars_widgets as $key => $sb ) { - if ( is_array($sb) && in_array($widget_id, $sb, true) ) - $sidebars_widgets[$key] = array_diff( $sb, array($widget_id) ); - } + ob_start(); + call_user_func_array( $control['callback'], $control['params'] ); + ob_end_clean(); - array_splice( $sidebar, $position, 0, $widget_id ); - break; - } + break; } $sidebars_widgets[$sidebar_id] = $sidebar; - wp_set_sidebars_widgets($sidebars_widgets); + // remove old position + if ( !isset($_POST['delete_widget']) ) { + foreach ( $sidebars_widgets as $key => $sb ) { + if ( is_array($sb) ) + $sidebars_widgets[$key] = array_diff( $sb, array($widget_id) ); + } + array_splice( $sidebars_widgets[$sidebar_id], $position, 0, $widget_id ); + } + + wp_set_sidebars_widgets($sidebars_widgets); wp_redirect('widgets.php?message=0'); exit; } @@ -228,8 +202,8 @@ if ( isset($_GET['editwidget']) && $_GET['editwidget'] ) { if ( $_GET['base'] === $control['id_base'] ) { $control_callback = $control['callback']; $multi_number = (int) $_GET['num']; - $control['params'][0]['number'] = $multi_number; - $control['id'] = $control['id_base'] . '-' . $multi_number; + $control['params'][0]['number'] = -1; + $widget_id = $control['id'] = $control['id_base'] . '-' . $multi_number; $wp_registered_widget_controls[$control['id']] = $control; break; } @@ -240,8 +214,13 @@ if ( isset($_GET['editwidget']) && $_GET['editwidget'] ) { if ( isset($wp_registered_widget_controls[$widget_id]) && !isset($control) ) { $control = $wp_registered_widget_controls[$widget_id]; $control_callback = $control['callback']; + } elseif ( !isset($wp_registered_widget_controls[$widget_id]) && isset($wp_registered_widgets[$widget_id]) ) { + $name = esc_html( strip_tags($wp_registered_widgets[$widget_id]['name']) ); } + if ( !isset($name) ) + $name = esc_html( strip_tags($control['name']) ); + if ( !isset($sidebar) ) $sidebar = isset($_GET['sidebar']) ? $_GET['sidebar'] : 'wp_inactive_widgets'; @@ -251,73 +230,73 @@ if ( isset($_GET['editwidget']) && $_GET['editwidget'] ) { $id_base = isset($control['id_base']) ? $control['id_base'] : $control['id']; // show the widget form - if ( is_callable( $control_callback ) ) { - $width = ' style="width:' . max($control['width'], 350) . 'px"'; - $key = isset($_GET['key']) ? (int) $_GET['key'] : 0; + $width = ' style="width:' . max($control['width'], 350) . 'px"'; + $key = isset($_GET['key']) ? (int) $_GET['key'] : 0; - require_once( 'admin-header.php' ); ?> -
- -

-
> -

+ require_once( 'admin-header.php' ); ?> +
+ +

+
> +

-
-
- -
+ +
+' . __('There are no options for this widget.') . "

\n"; ?> +
-

-
- +

+
+
$sbvalue ) { - echo "\t\t\n"; - } ?> -
"; - if ( 'wp_inactive_widgets' == $sbname ) { - echo ' '; + echo "\t\t
"; + if ( 'wp_inactive_widgets' == $sbname ) { + echo ' '; + } else { + if ( !isset($sidebars_widgets[$sbname]) || !is_array($sidebars_widgets[$sbname]) ) { + $j = 1; } else { - if ( !isset($sidebars_widgets[$sbname]) || !is_array($sidebars_widgets[$sbname]) ) { - $j = 1; - } else { - $j = count($sidebars_widgets[$sbname]); - if ( isset($_GET['addnew']) || !in_array($widget_id, $sidebars_widgets[$sbname], true) ) - $j++; - } - $selected = ''; - echo "\t\t\n"; + $j = count($sidebars_widgets[$sbname]); + if ( isset($_GET['addnew']) || !in_array($widget_id, $sidebars_widgets[$sbname], true) ) + $j++; } - echo "
-
+ $selected = ''; + echo "\t\t\n"; + } + echo "\n"; + } ?> + +
-
+
- + - + - - - - + + + + -
-
- -
-
+
+
+ +
+ '__i__', 'title' => '', 'url' => '', 'items' => 10, 'error' => false, 'show_summary' => 0, 'show_author' => 0, 'show_date' => 0 ); - else - $instance['number'] = $this->number; + $instance = array( 'title' => '', 'url' => '', 'items' => 10, 'error' => false, 'show_summary' => 0, 'show_author' => 0, 'show_date' => 0 ); + $instance['number'] = $this->number; wp_widget_rss_form( $instance ); } diff --git a/wp-includes/widgets.php b/wp-includes/widgets.php index 73e3253d65..f1285b7f72 100644 --- a/wp-includes/widgets.php +++ b/wp-includes/widgets.php @@ -191,58 +191,54 @@ class WP_Widget { $all_instances = $this->get_settings(); // We need to update the data - if ( !$this->updated && !empty($_POST['sidebar']) ) { + if ( $this->updated ) + return; - // Tells us what sidebar to put the data in - $sidebar = (string) $_POST['sidebar']; + $sidebars_widgets = wp_get_sidebars_widgets(); - $sidebars_widgets = wp_get_sidebars_widgets(); - if ( isset($sidebars_widgets[$sidebar]) ) - $this_sidebar =& $sidebars_widgets[$sidebar]; + if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) { + // Delete the settings for this instance of the widget + if ( isset($_POST['the-widget-id']) ) + $del_id = $_POST['the-widget-id']; else - $this_sidebar = array(); + return; - if ( isset($_POST['delete_widget']) && $_POST['delete_widget'] ) { - // Delete the settings for this instance of the widget - if ( isset($_POST['widget-id']) ) - $del_id = $_POST['widget-id']; - else - return; + if ( isset($wp_registered_widgets[$del_id]['params'][0]['number']) ) { + $number = $wp_registered_widgets[$del_id]['params'][0]['number']; - if ( $this->_get_display_callback() == $wp_registered_widgets[$del_id]['callback'] && isset($wp_registered_widgets[$del_id]['params'][0]['number']) ) { - $number = $wp_registered_widgets[$del_id]['params'][0]['number']; - - if ( $this->id_base . '-' . $number == $del_id ) { - unset($all_instances[$number]); - } - } + if ( $this->id_base . '-' . $number == $del_id ) + unset($all_instances[$number]); + } + } else { + if ( isset($_POST['widget-' . $this->id_base]) && is_array($_POST['widget-' . $this->id_base]) ) { + $settings = $_POST['widget-' . $this->id_base]; + } elseif ( isset($_POST['id_base']) && $_POST['id_base'] == $this->id_base ) { + $num = $_POST['multi_number'] ? (int) $_POST['multi_number'] : (int) $_POST['widget_number']; + $settings = array( $num => array() ); } else { - if ( isset($_POST['widget-' . $this->id_base]) && is_array($_POST['widget-' . $this->id_base]) ) { - $settings = $_POST['widget-' . $this->id_base]; - } else { - $num = $_POST['multi_number'] ? (int) $_POST['multi_number'] : (int) $_POST['widget_number']; - $settings = array( $num => array() ); - } - - foreach ( $settings as $number => $new_instance ) { - $new_instance = stripslashes_deep($new_instance); - $this->_set($number); - - if ( isset($all_instances[$number]) ) - $instance = $this->update($new_instance, $all_instances[$number]); - else - $instance = $this->update($new_instance, array()); - - // filters the widget's settings before saving, return false to cancel saving (keep the old settings if updating) - $instance = apply_filters('widget_update_callback', $instance, $new_instance, $this); - if ( false !== $instance ) - $all_instances[$number] = $instance; - } + return; } - $this->save_settings($all_instances); - $this->updated = true; + foreach ( $settings as $number => $new_instance ) { + $new_instance = stripslashes_deep($new_instance); + $this->_set($number); + + if ( isset($all_instances[$number]) ) + $instance = $this->update($new_instance, $all_instances[$number]); + else + $instance = $this->update($new_instance, array()); + + // filters the widget's settings before saving, return false to cancel saving (keep the old settings if updating) + $instance = apply_filters('widget_update_callback', $instance, $new_instance, $this); + if ( false !== $instance ) + $all_instances[$number] = $instance; + + break; // run only once + } } + + $this->save_settings($all_instances); + $this->updated = true; } /** Generate the control form.