WordPress.org

Make WordPress Core

Opened 2 months ago

Last modified 2 months ago

#53766 new defect (bug)

Legacy Widget block triggers update() method multiple times for one update

Reported by: GDragoN Owned by:
Milestone: Awaiting Review Priority: normal
Severity: critical Version:
Component: Widgets Keywords: reporter-feedback
Focuses: Cc:

Description

I can't catch how it does it exactly, but, when the widget is saved, the update() method is called more than once in a chain.

I have placed debug code (to log in to log file) in my widget at the end of the update() method, and I add a new element into the $instance array, and if that element is not set, I set it to 1, if it is, I increment it. After one save, I would expect that that value is set to 1, but it is set to 2 after every save. After every save, it is clear that the update() is called twice. The problem is that result from the first save, is used as an input for the new save. And, if some of the values of the $instance change type during save, that causes a major issue for the processing.

Why the Legacy Widget runs update() twice in a chain (using the previous result as input for the next call), that needs to be fixed.

Change History (3)

#1 @zieladam
2 months ago

Hey @GDragoN, I tried reproducing the problem and couldn't. Would you mind sharing the widget class you're using?

#2 @zieladam
2 months ago

  • Keywords reporter-feedback added

#3 @GDragoN
2 months ago

All my plugins use a similar basic widget structure and base class. Plugin: https://wordpress.org/plugins/gd-members-directory-for-bbpress/ has one widget, and I have noticed the problem because of one of the settings.

Base widget class has a setting '_caps' that is in widget stored as an array. But, in the plugin interface, it is a single INPUT TEXT field. When the update() method is called, the plugin takes value from this text input and converts it into an array to save it. But, when using Legacy Widget, the update method is called more than once, and the update() function expects the input value for _caps to be string, and convert it to the array, on subsequent calls, update() seems to be called with the $Instace array that is already processed and _caps is already array at that point.

As I said, I added dummy/fake value in an update() method to see it gets' propagated to the second update() call (value set to 0, with ++ operation), it should end up as 1, but, because the second call, it ends up as 2, providing the duplicated call to update() method.

With a lot of widgets, this is not a big deal, but if the update() method does some additional processing to settings, changing types, it is noticeable problem. And, my widgets usually do this for BOOLEAN values too.

Milan

Note: See TracTickets for help on using tickets.