Make WordPress Core

Opened 12 years ago

Closed 11 years ago

#24493 closed defect (bug) (duplicate)

widget programming using the function checked inside form bug

Reported by: frumph's profile Frumph Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.5.1
Component: Widgets Keywords:
Focuses: Cc:

Description

So what happens is if the wp_parse_args sets a value to true or 1, the checked box messes up the contents of the next input value if it contains a < or &lt; however, setting the value to false or 0 it doesn't modify the contents of the next input box

Example code:

<?php

class ceo_do_nothing_widget extends WP_Widget {
	
	function ceo_do_nothing_widget() {
		$widget_ops = array('classname' => __CLASS__, 'description' => __('Does Nothing','comiceasel') );
		$this->WP_Widget(__CLASS__, __('Does Nothing','comiceasel'), $widget_ops);
	}
	
	
	function widget($args, $instance) {
		extract($args, EXTR_SKIP);
		var_dump($args);
	}
	
	function update($new_instance, $old_instance) {
		$instance = $old_instance;
		$instance['title'] = $new_instance['title'];
		$instance['dosomething'] = $new_instance['dosomething'];
		return $instance;
	}
	
	function form($instance) {
		$instance = wp_parse_args( (array)$instance, array(
					'title' => '&lt;&lt two',
					'dosomething' => true  // set this to false to see behavior
					));
		?>
		<input id="<?php echo $this->get_field_id('dosomething'); ?>" name="<?php echo $this->get_field_name('dosomething'); ?>" type="checkbox" value="1" <?php checked(true, $instance['dosomething']); ?> /> <strong><?php _e('First','comiceasel'); ?></strong><br />
		<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $instance['title']; ?>" /><br /> 
<?php
	}
}

function ceo_widget_do_nothing_register() {
	register_widget('ceo_do_nothing_widget');
}

add_action( 'widgets_init', 'ceo_widget_do_nothing_register');

Notice the default value 'dosomething' currently set to true, if you set it to false the behavior doesn't happen.

This *only* happens on the first time adding the widget to the sidebar and then clicking update for the widget that it clears the data. Every subsequent time everything's fine.

Attachments (1)

donothing.php (1.8 KB) - added by Frumph 12 years ago.
.php example file that shows how TWO input boxes change removing either the &lt; or the &gt; at different times dependant on the state of a checkbox

Download all attachments as: .zip

Change History (5)

@Frumph
12 years ago

.php example file that shows how TWO input boxes change removing either the &lt; or the &gt; at different times dependant on the state of a checkbox

#1 @nofearinc
12 years ago

Have you tested that widget with the latest trunk version?

I have tried several times while deactivating widgets and adding new widget instances in sidebar (since you said that it happens only the first time it's added to the sidebar) the following configurations:

1) 1 or 0 to wp_parse_args
2) checked or unchecked checkbox param
3) Lots of saves and different placement of widgets

Value is stored and displayed properly, at least the one provided by default. Anything missing in the flow?

#2 @Frumph
12 years ago

Firefox 21.0, IE 8 browser, windows.

Doesn't happen in chrome or safari

#3 @nofearinc
12 years ago

Confirmed, I can reproduce it on Firefox.

There is a problem with the base_id while fetching widgets. In wp-includes/widgets.php the update_callback function is fetching the $settings array as an array with a single element (the widget ID) for Chrome and 2 elements (widget ID + the literal __i__) on Firefox.

The __i__ literal is set to widgets when the widget number is equal to -1 (to avoid bad referencing for non-existing widget ID). wp-admin/js/widgets.js is calling some replace functions over i and it is probably not handled correctly (maybe order of operations issue for non-WebKit as widgets being saved before widget ID has been initialized). Still looking at it, but apparently the i string is causing a second array to be fetched in widgets.php where one of the values is stored there instead of in the original widget ID referred array.

Edit: The problem is in widgets.js, this line in particular:

ui.item.html( ui.item.html().replace(/<[^<>]+>/g, function(m){ return m.replace(/__i__|%i%/g, n); }) );

It seems to properly recognize tags in WebKit but fails in FF/IE and one of the inputs is left with i instead of replaced by widget ID. Therefore the data is not passed properly in the array and not stored into the DB.

I'm not sure if that's an accepted use case for input data at the first place, otherwise I would think of a way to explicitly convert < and > characters into lt/gt or other format to unify them as to how WebKit understands them so that the regex works (or think of another regex that would work for all engines).

Last edited 12 years ago by nofearinc (previous) (diff)

#4 @SergeyBiryukov
11 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed

Duplicate of #18446.

Note: See TracTickets for help on using tickets.