Magento 1.9 – Overriding Parent Class Method _construct()

inheritancemagento-1.9modulePHP

I'm having some troubles with passing properties between related classes.

Let's say we have a parent class:

class Company_Interface_Model_Import_Product extends Mage_Core_Model_Abstract {

    public $_someVariableSetInProductClass = null;

    public function _construct()
    {
        $this->_someVariableSetInProductClass = 'test';
        parent::_construct();
    }   
}

Everything is obvious here. We're initializing public property $_someVariableSetInProductClass and in the _construct method we're updating it's value from null to string 'test'.

This property can be accessed wherever in this class by calling

$this->_someVariableSetInProductClass

Now we have a child class that extends it's parent, and we want to access that property _someVariableSetInProductClass which's set in parent class _construct() method.

class Company_Interface_Model_Import_Product_Categories extends Company_Interface_Model_Import_Product {

   public function _construct()
   {
       parent::_construct();
   }

   public function testAction()
   {
      var_dump($this->_someVariableSetInProductClass) //returns null
      var_dump(Mage::getModel('company_interface/import_product')->_someVariableSetInProductClass); //returns 'test';
   }
}

As far as I'm aware this would work in typical PHP setup, but Magento uses it's own constructor and somehow the only way to receive the property value from parent class is to call the class instance again.

This is strange for me cause everywhere we're prompted to avoid calling new instances and use the one existing.

UPDATE

If I do something like that:

class Company_Interface_Model_Import_Product extends Mage_Core_Model_Abstract {

    public $_someVariableSetInProductClass = 'test';

    public function _construct()
    {
        parent::_construct();
        $_someVariableSetInProductClass = 'not working in _Categories'; 
    }   
}

Then I receive the value 'test' in _Categories. It seems _Product _construct() is not setting the value when using methods from _Categories.

The questions:

  1. Is this not working because * _Product class _construct() method is not called when class * _Categories testAction() is called? I thought that parents are always initialized when children has parent::_construct() in its construct method.

  2. Is there any error in the code that could point this case in my thinking error?

  3. Is there other way to pass properties between related classes?

Thanks in advance.

Solution

It seem like _construct() method in _Categories class is overriding the function _construct() in _Product. Removing _construct() completely from _Categories solved the issue.

class Company_Interface_Model_Import_Product_Categories extends Company_Interface_Model_Import_Product {

   public function testAction()
   {
      var_dump($this->_someVariableSetInProductClass) //returns 'test'

   }
}

Update 2 – Reason

I've kept searching what was the small reason to have such big impact and I have to admit this was due poor coding and probably a tiredness.
This couldn't be seen in my example cause I've didn't put it there.

Generally the _Catalog class can have _construct() method but you have to be 100% sure that parent::_construct() is called BEFORE applying any values to _Catalog class properties – somehow they're not appended later and don't call the _Product class _construct() method unless it's called first.

So proper code would be:

class Company_Interface_Model_Import_Product_Categories extends Company_Interface_Model_Import_Product {
    public $_test = null;

    public function _construct()
    {

        parent::_construct(); 

     // This is the reason, the lines were inversed in this method. 

        $this->_test = 'testing works';

    }

    public function testAction()
    {
        var_dump($this->_someVariableSetInProductClass) //return 'test';
        var_dump(this->_test); //return 'testing works.'
    }
}

Best Answer

I'm not sure why it's not working, but I have some suggestions to clean up the code a little and maybe bring you closer to the solution

  1. The internal constructor comes from the Varien_Object and should be protected https://github.com/bragento/magento-core/blob/1.9/lib/Varien/Object.php#L151
  2. Your _construct in Company_Interface_Model_Import_Product should also call the parent function (even if it does not do anything in this case)
  3. You don't need to override the _construct in Company_Interface_Model_Import_Product_Categories if you only call the parent function
Related Topic