Make WordPress Core

Opened 8 years ago

Closed 7 years ago

#35981 closed enhancement (wontfix)

Convert WP_Widget into an abstract class

Reported by: johnbillion's profile johnbillion Owned by: ocean90's profile ocean90
Milestone: Priority: low
Severity: normal Version: 2.8
Component: Widgets Keywords:
Focuses: Cc:

Description

The WP_Widget::widget() method is, for all incense and porpoises, an abstract method without actually being abstract. It contains a call to wp_die() with an instructional message stating that it must be overridden in a subclass, and a widget does not operate without this method (it's used for the widget output).

This method should be a real abstract method, and this, so should the WP_Widget class. That way, we can remove one more piece of janky code from WordPress.

I scanned the plugin and theme directories for instances of new WP_Widget() and found zero instances, so I predict breakage to be low to non-existent.

Attachments (1)

35981.diff (840 bytes) - added by johnbillion 8 years ago.

Download all attachments as: .zip

Change History (17)

@johnbillion
8 years ago

#1 @johnbillion
8 years ago

  • Keywords has-patch dev-feedback added
  • Version set to 2.8

#2 @westonruter
8 years ago

Good idea. I suggest putting this in 4.6 early in case there are widgets that fail to define a widget() method in their WP_Widget subclasses, as otherwise they'll get fatals.

#3 @swissspidy
8 years ago

  • Keywords 4.6-early added
  • Milestone changed from Awaiting Review to Future Release

I've always thought it's strange. Would be nice to clean this up.

#4 @westonruter
8 years ago

@swissspidy I'm pretty sure it's because abstract classes were introduced in PHP5, whereas WP_Widget was introduced when PHP4 support was still required.

#5 @ocean90
7 years ago

  • Keywords commit added; 4.6-early removed
  • Milestone changed from Future Release to 4.6

#6 @ocean90
7 years ago

  • Owner set to ocean90
  • Resolution set to fixed
  • Status changed from new to closed

In 37425:

Widgets: Make WP_Widget a real abstract class.

This removes the die() call from WP_Widget::widget() and converts it to an abstract method.
WP_Widgets (later renamed to WP_Widget) was introduced in [10764] where the minimum PHP requirement was 4.3, thus no abstract was available.

Props johnbillion.
Fixes #35981.

#7 @ocean90
7 years ago

In 37427:

Widgets: Create WP_Widget_Mock as a mock of WP_Widget which can be used for widget tests.

You cannot instantiate an abstract class. Not even in WordPress world.

See #35981.

#8 follow-up: @kraftbj
7 years ago

For plugin authors: If your widget does not include a widget() function, you'll need to add an noop function to prevent fatals.

#9 @ocean90
7 years ago

  • Keywords needs-dev-note added

#10 in reply to: ↑ 8 @netweb
7 years ago

  • Keywords changed from has-patch, dev-feedback, commit, needs-dev-note to has-patch dev-feedback commit needs-dev-note

Replying to kraftbj:

For plugin authors: If your widget does not include a widget() function, you'll need to add an noop function to prevent fatals.

It looks like this change has caused bbPress to fatal with PHP 5.2

Related: #bbPress2952

Edit: No idea whats going on with those keyword changes that didn't actually change ¯\_(ツ)_/¯

Last edited 7 years ago by netweb (previous) (diff)

#11 @dd32
7 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

Following on from the bbPress issues, I'm not certain that this is something we can realistically do until we require a much higher PHP version.

https://3v4l.org/rq2I9 shows that under PHP 5.4+ PHP is happy for you to mark the parameters as optional, but that PHP 5.2 requires the function signature to stay exactly the same, ie:

  • function widget( $args, $instance ) works in PHP 5.2+
  • function widget( $args = array(), $instance = array() ) only works in PHP 5.4+
  • function widget() and function widget( $args ) are no longer allowed - even if the widget has no per-widget settings.

I'm concerned that these changes will break existing code for no obvious gains.

We could mark the class as abstract only, leaving the function intact, however that would throw a Strict Standards warning in PHP 5.x, and a PHP Warning in PHP 7.x.

I'm re-opening this to keep it on the radar, I don't think this necessarily should be immediately reverted, but I'm not confident we could release 4.6 and not have a bunch of sites break when we could've prevented it.

#12 @kraftbj
7 years ago

For additional context for my previous comment:

For plugin authors: If your widget does not include a widget() function, you'll need to add an noop function to prevent fatals.

class PluginWidget extends WP_Widget{ ... } which provides some basic setup for a plugin's multiple widgets without the widget() call, then with a class PluginWidgetAwesome extends PluginWidget{...} which includes a widget() function for the actual widget.

This setup worked previously and now fatals. Need to add a function widget() {} in the PluginWidget class.

#13 @ocean90
7 years ago

  • Keywords revert added; has-patch dev-feedback commit needs-dev-note removed

This ticket was mentioned in Slack in #core by chriscct7. View the logs.


7 years ago

#15 @ocean90
7 years ago

In 37648:

Widgets: Revert [37425] and [37427].

The change can cause fatal errors under certain conditions, like when the subclass has a different function signature for widget() or doesn't even implement the method.

See #35981.

#16 @ocean90
7 years ago

  • Keywords revert removed
  • Milestone 4.6 deleted
  • Resolution set to wontfix
  • Status changed from reopened to closed
Note: See TracTickets for help on using tickets.