2

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.'
    }
}
  • Are you dealing with the core product and category classes? – benmarks Feb 6 '16 at 15:36
  • Yes and no. Particular usage for this, is to grab all products SKUs as keys and assign an Ids as values in array which's done in Product class. Then it should be available from _Categories children class so a check if product exists can be done very quickly without running any Magento internal code by doing an in_array($sku, $this->_sku_to_ids). I've checked a few other codes and I was using the _construct() method in children classes without overriding the parent. I'm still not sure what's the real reason here. So it depends what do you mean by dealing with them. – versedi Feb 6 '16 at 16:06
1

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
  • This is just a hand written code to show what I'm having troubles with, I've made sure that _construct() methods are protected. _Product did called a parent::_construct() just forgot to put it into example. I've removed parent::_construct() from _Categories. One thing occurs to me - if I set the properties like $_propertyInProduct = 'test' and not in the _construct() method of _Product then I can read it by $this->_propertyInProduct. It seems _Product _construct() is not called when _Categories are - it doesn't receives values set there. – versedi Feb 6 '16 at 14:10
  • ok, weird :) did you maybe override the public function __construct() somewhere so the _construct is not called anymore? github.com/bragento/magento-core/blob/1.9/lib/Varien/… – David Verholen Feb 6 '16 at 14:14
  • Nope, nothing found. – versedi Feb 6 '16 at 14:19
  • I went through the code a few more times and in the end it seems that point 3 was the solution. Could you explain a bit why _Categories can't have a _construct method itself? – versedi Feb 6 '16 at 14:21
  • 1
    thats even weirder. Categories can have a _construct function (at least it should be like that), but you don't need it if the only thing it does, is calling the parent function, since it's called anyways when it's not overridden – David Verholen Feb 6 '16 at 14:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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