0

I think this should be relatively easy, but somehow I cannot figure out how to do this. essentially there's a preexisting plugin that does this:

add_action('widgets_init', create_function('', 'register_widget("Foo");'));
if ( ! class_exists( 'Foo' ) ) {
class Foo extends WP_Widget {
        /*constructs etc*/
}}

now i would like to write another plugin (extension essentially), that extends the above. I tried to do something like the following (and also tried - in vain - to find some examples/documentation )

add_action('widgets_init', create_function('', 'register_widget("Bar");'));
class Bar extends Foo {     
    function __construct() {
        /*do stuff*/
    }
}

but all i ever get is

<b>Fatal error</b>:  Class 'Foo' not found in ...

so I suppose it's a question of making 'Bar' execute AFTER Foo, but I dunno how.

any hints/ideas/snippets or even just links to docs etc would be much appreciated as I am failing at the first hurdle here..:(

2 Answers 2

1

I question the wisdom of extending a class from another plugin. You have no idea what will happen next time that other plugin gets updated.

However, generally speaking you can control when in a hook "queue" a function runs by passing a third parameter-- a priority. So pass a priority high enough and your function should run after the other plugin's function.

add_action(
  'widgets_init', 
  create_function('', 'register_widget("Bar");')
  ,100
);

I don't know if that will work in your case. I've never tried it.

You should also be aware that you could have trouble because of plugin load order.

Changing Plugin Load Order
Does an activated plugin automatically mean its methods are available to other WP functions?

widget_init runs after plugins_loaded so that probably won't be an issue in you case.

On further investigation... I get errors involving missing variables required by the constructor. The following works.

if ( ! class_exists( 'Foo' ) ) {
  class Foo extends WP_Widget {
      /*constructs etc*/
      function __construct($id = 'twidg', $descr = 'Test Widget', $opts = array()) {
    $widget_opts = array();
    parent::__construct($id,$descr,$widget_opts);
      /*do stuff*/
      }
  }
}
function rw_cb() {
register_widget("Foo");
}
add_action('widgets_init', 'rw_cb');

class Bar extends Foo {     
    function __construct() {
      $widget_opts = array();
      parent::__construct('twidgextended','Test Widget 2',$widget_opts);
    }
}
function rw_cb_2() {
  register_widget("Bar");
}
add_action('widgets_init', 'rw_cb_2');

When each component is pasted into a dummy plugin file, it works. The only time I get a fatal error involving a class file not found is if I try to activate the plugin with the Bar class definition, before the plugin with the Foo definition, which makes sense.

Wrapping that block as follows solves that issue though and you can activate in any order.

if (class_exists('Foo')) {
  class Bar extends Foo {     
      function __construct() {
    $widget_opts = array();
    parent::__construct('twidgextended','Test Widget 2',$widget_opts);
      }
  }

  function rw_cb_2() {
    register_widget("Bar");
  }
  add_action('widgets_init', 'rw_cb_2');
}
9
  • oh, and regarding: >I question the wisdom of extending a class from another plugin. You have no idea what will happen next time that other plugin gets updated. i actually do , as the "other one"(FOO) is mine, but I'm trying to - independently so to speak - extend it
    – olly
    May 25, 2013 at 16:03
  • If both plugins are yours, it makes more sense. You didn't mention that in the question.
    – s_ha_dum
    May 25, 2013 at 16:10
  • i know, sorry ...
    – olly
    May 25, 2013 at 16:12
  • anyway, it doesn't matter what I set the priority to unfortunately , I'll always get the same fatal error. I'll have a read through the docs/links you posted. maybe I'll find something there..thanks though
    – olly
    May 25, 2013 at 16:14
  • your edit / other solution looks a lot more elegant than what I was able to come up with below . I'll give that a go too. thanks for taking the time . much appreciated
    – olly
    May 25, 2013 at 17:11
1

ah, but you did point me in the right direction (specifically your second link). the following (as it stands in my scenario at least ) seems to do the trick. thank you.

  add_action( 'widgets_init', 'extend_foo' );
function extend_foo(){
    if (class_exists( 'Foo' ) ) {
        class Bar extends Foo {
            function __construct() {
                parent::__construct();          
            }   
        }
    }
}

(although I'm not sure if this is the most elegant way of doing things though...but if it works....)

1
  • edited my own answer as it appears I could make it a lot more concise..
    – olly
    May 27, 2013 at 12:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.