Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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@domain.com 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']='anotheremail@anotherdomain.com';
    }
}
$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 anotheremail@anotherdomain.com.

However, when doing $sendEmail it is still set to email@domain.com. 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).

share|improve this question
    
It looks like PHP question to me. –  Krzysiek Dróżdż Jul 12 '13 at 9:05
    
yes and no i guess. as the whole thing is a plugin (extending WP_Widget) it's wordpress too . –  olly Jul 12 '13 at 9:23
    
But it could be anything. It doesn't matter that it is class used in WordPress... –  Krzysiek Dróżdż Jul 12 '13 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 Jul 12 '13 at 9:38
add comment

3 Answers 3

up vote 1 down vote accepted

If you call BAR the e-mail address is set to anotheremail@anotherdomain.com. But when you call FOO_SEND_EMAIL, the e-mail address is set to email@domain.com 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.

share|improve this answer
    
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 Jul 12 '13 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. –  Mike Madern Jul 12 '13 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 Jul 12 '13 at 12:42
add comment

$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.

share|improve this answer
    
hmm, i tried changing protected $pluginOptions to protected static $pluginOptions but it doesnt seem to make any difference... –  olly Jul 12 '13 at 9:20
add comment

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();
        }
    }
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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