• One plugin we use has some widget declared as

    if ( ! class_exists( 'thewidget' ) ) {
    	class thewidget extends WP_Widget {...}
    }
    add_action( 'widgets_init', create_function( '', 'register_widget( "thewidget" );' ) );

    We need to override this widget code (not creating an alternate version, but actually replacing it with the same name but different code) but we don’t know how to plug our own version of thewidget in either our theme’s functions.php or our, preferably, a custom plugin.
    If we declare our own thewidget class, it throws a ‘Cannot redeclared class…’ error; we understand this is because at this point the plugin function has already run and the class already exists.

    We’ve tried wrapping our class declaration in a function and hooking this at various points to get our class declared before the plugin’s, but to no effect, it either is too late or gets ignored:

    function thewidget_override() {
    	class thewidget extends WP_Widget {...}
    }
    add_action('muplugins_loaded', 'thewidget_override', 10);

    (this is ignored)

    So, if our approach is correct, where should we hook our class definition?
    Else, what would be the correct way to override this code?

    Thanks a lot for your help.

Viewing 4 replies - 1 through 4 (of 4 total)
  • Moderator bcworkz

    (@bcworkz)

    You can actually use ‘widgets_init’ just like the original plugin does. This plugin does not use a priority parameter when adding the action hook, so the value defaults to 10. You just need to declare your widget with an earlier priority (smaller number), for example:
    add_action('widgets_init', 'thewidget_override', 5 );

    Thanks for the help, bcwokz.

    We actually tried that, but strangely enough it didn’t work; we got a ‘Cannot redeclare class’ error. Actually, this simple check

    function thewidget_override() {
    if ( class_exists('thewidget') ) { /* Returns TRUE */ };
    }
    add_action('widgets_init', 'thewidget_override', 5);

    Tells us that at widgets_init priority 5 the class is already defined. We checked it is declared once, by that plugin function only, because hard removing the plugin function turns our check to false.
    We run the same check at plugins_loaded (which is even earlier), and it also checks true for the class being already defined. We cannot go any earlier because the previous hook is muplugins_loaded, at which point we cannot extend WP_Widget yet.

    We are really buffled by this one. Any clue?
    Thanks once again.

    Moderator bcworkz

    (@bcworkz)

    We need to separate the class declaration from the use of register_widget(). The ‘widget_init’ action registers a widget for WP based on a class that is already declared. The action priority only manages the registration order, not the class declaration order. Unless the class declaration itself is wrapped in a hook callback, it is declared when the plugin is loaded.

    WP offers no mechanism to manage the order plugins are loaded, which is the only way to get your class declared first. Officially, the plugin load order is undefined, but the word is that plugins load in their slug’s alphabetical order. Try renaming your plugin to come alphabetically before the plugin with the class you are trying to override.

    You are absolutely right. Our plugin was alphabetically below the one we tried to override; placing it above got our class definition loaded before the other one.
    Good tip on the undocumented way to control plugin load order, nice to know; let’s hope some proper way to manage this gets developed in the future, it would be really helpful.
    Many, many thanks, bcworkz.

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘Override plugin widget class’ is closed to new replies.