[wp-trac] [WordPress Trac] #36851: Widgets don't remove hooks after being unregistered

WordPress Trac noreply at wordpress.org
Mon May 16 15:28:59 UTC 2016


#36851: Widgets don't remove hooks after being unregistered
--------------------------+----------------------------
 Reporter:  westonruter   |      Owner:
     Type:  defect (bug)  |     Status:  new
 Priority:  normal        |  Milestone:  Future Release
Component:  Widgets       |    Version:  2.8
 Severity:  normal        |   Keywords:  needs-patch
  Focuses:                |
--------------------------+----------------------------
 In `WP_Widget_Recent_Comments::__construct()`, there is this bit of code:

 {{{#!php
 <?php
 if ( is_active_widget( false, false, $this->id_base ) ||
 is_customize_preview() ) {
         add_action( 'wp_head', array( $this, 'recent_comments_style' ) );
 }
 }}}

 If `unregister_widget( 'WP_Widget_Recent_Comments' )` is called, this
 added `wp_head` action is still going to persist unexpectedly. At the
 moment, I believe the only way to remedy this inside such widgets
 themselves would be to check to see if the widget is still among
 `$wp_widget_factory->widgets` when the action callback is called (here the
 `recent_comments_style` method). From outside the widget, the alternative
 is would be to do:

 {{{#!php
 <?php
 $widget = $wp_widget_factory->widgets['WP_Widget_Recent_Comments'];
 unregister_widget( get_class( $widget ) );
 remove_action( 'wp_head', array( $widget, 'recent_comments_style' ) );
 }}}

 Neither of these options are great.

 Perhaps there should be new `widget_registered` and `widget_unregistered`
 actions that widgets could listen to to do this cleanup? Or there could be
 a new `unregister` method on `WP_Widget` that a subclass could have this
 logic inside of. (We wouldn't be able to use the PHP destructor since it
 would never be called since the reference to the class would be still
 captured among the registered hooks.) Likewise, instead of adding the
 hooks inside of the constructor, perhaps there should also be a
 `WP_Widget::register()` method that gets called inside of the faux-private
 `WP_Widget::_register()` (and `_register` should be `final`, no?)

--
Ticket URL: <https://core.trac.wordpress.org/ticket/36851>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list