1

I guess I have a problem understanding inheritance.
I have 4 classes like so;

class FOO extends WP_Widget {
    protected $pluginOptions;
    function __construct() {
        $this->pluginOptions = get_option('option_name',0); 
        /*$this->pluginOptions['email'] returns /is set to [email protected] here*/
    }
}

class FOO_ACTIONS extends FOO {
    function __construct() {
        parent::__construct();
        /*some actions*/
    }
    /*some methods*/
}

class FOO_SEND_EMAIL extends FOO_ACTIONS {
    function __construct() {
        parent::__construct();
        /*some actions*/
    }
    /*some methods*/
}   

class BAR extends FOO{
    function __construct() {
        /*change email here */
        $this->pluginOptions['email']='[email protected]';
    }
}
$BAR=new BAR();

in another file i am calling:

$sendEmail=new FOO_SEND_EMAIL;

I thought that - as BAR gets called before FOO_SEND_EMAIL
$this->pluginOptions['email'] is now [email protected].

However, when doing $sendEmail it is still set to [email protected]. can anyone point me in the right direction perhaps as to where I'm going wrong here? (happy to provide more code of course if necessary).

4
  • It looks like PHP question to me. Commented Jul 12, 2013 at 9:05
  • yes and no i guess. as the whole thing is a plugin (extending WP_Widget) it's wordpress too .
    – olly
    Commented Jul 12, 2013 at 9:23
  • But it could be anything. It doesn't matter that it is class used in WordPress... Commented Jul 12, 2013 at 9:25
  • quite right, but if more info/code is required (including add_action calls) it most definitely ends up being a WP thing, no ?
    – olly
    Commented Jul 12, 2013 at 9:38

3 Answers 3

1

If you call BAR the e-mail address is set to [email protected]. But when you call FOO_SEND_EMAIL, the e-mail address is set to [email protected] because it is overwritten by FOO's constructor.

You run $sendEmail = new FOO_SEND_EMAIL, when you do this the constructor of FOO is called. It has nothing to do with whatever $BAR currently is.

3
  • hmm, yeah i figured that. however, i (would have) thought that as BAR extends FOO and FOO_SEND_EMAIL is a child of FOO FOO gets changed by BAR before FOO_SEND_EMAIL is called (obviously not, but I dont understand why not, or more importantly how to change that behaviour)...
    – olly
    Commented Jul 12, 2013 at 9:37
  • BAR and FOO_SEND_MAIL are two different objects that happen to inherit FOO. If one object changes it doesn't change for all objects that inherit FOO because they're all separate objects. If you want to change the e-mail address you have to do that in the same object. Commented Jul 12, 2013 at 9:51
  • ok then. i accept that as answer/explanation . i was hoping to be able to kind of glue them together without additional hooks, but after all it appears i can't do that. either way, thanks for your time clarifying things
    – olly
    Commented Jul 12, 2013 at 12:42
0

$pluginOptions is object property. It is not static property, so you set it's value for one instance of this class (object) and not for all of them. Every object has it's own value of this property/member.

You should use static property to do what you want, I guess.

1
  • hmm, i tried changing protected $pluginOptions to protected static $pluginOptions but it doesnt seem to make any difference...
    – olly
    Commented Jul 12, 2013 at 9:20
0

same boat, nine months later. Wordpress… hmph...

In widgets.php, there is a class called WP_Widget_Factory (line 319), in it’s constructor, it attaches _register_widgets to the widgets_init hook. This callback function, in all it's great wisdom, then decides to iterate through the array of registered widgets and any that are already registered, it deletes (line 341), so it can re-register them, calling the constructor __construct, directly (line 345, 324).

Also, none of this matters as your parent constructor is never being called in BAR's constructor anywayz. In php, if you define __construct(), you have to EXPLICITLY call parent::__construct(); to get the parent constructor to run.

However, if you DON'T define __constuct() the parent constructor will run by default.

Basic rules of inheritance that.

class WP_Widget_Factory {
    var $widgets = array();

    function WP_Widget_Factory() {
        add_action( 'widgets_init', array( $this, '_register_widgets' ), 100 );
    }

    function register($widget_class) {
        $this->widgets[$widget_class] = new $widget_class();
    }

    function unregister($widget_class) {
        if ( isset($this->widgets[$widget_class]) )
            unset($this->widgets[$widget_class]);
    }

    function _register_widgets() {
        global $wp_registered_widgets;
        $keys = array_keys($this->widgets);
        $registered = array_keys($wp_registered_widgets);
        $registered = array_map('_get_widget_id_base', $registered);

        foreach ( $keys as $key ) {
            // don't register new widget if old widget with the same id is already registered
            if ( in_array($this->widgets[$key]->id_base, $registered, true) ) {
                unset($this->widgets[$key]);
                continue;
            }

            $this->widgets[$key]->_register();
        }
    }
}

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.