Explanation of Magento 1.9.3 __call Change
-
03-10-2020 - |
Question
The changelog for Magento 1.9.3 mentions the following backwards-incompatible change:
Mage_Uploader_Model_Config_Abstract: Overrides the magic method __call and its behavior can be inconsistent.
Can somebody explain what this means? The example cited in the changelog is not clear either. Is it saying the behavior was changed to be inconsistent or it was changed to no longer be inconsistent?
Solution
Most of the Magento classes extend Varien_Object
which implements the magic getter/setter/unsetter/has with the following __call
method:
public function __call($method, $args)
{
switch (substr($method, 0, 3)) {
case 'get' :
//Varien_Profiler::start('GETTER: '.get_class($this).'::'.$method);
$key = $this->_underscore(substr($method,3));
$data = $this->getData($key, isset($args[0]) ? $args[0] : null);
//Varien_Profiler::stop('GETTER: '.get_class($this).'::'.$method);
return $data;
case 'set' :
//Varien_Profiler::start('SETTER: '.get_class($this).'::'.$method);
$key = $this->_underscore(substr($method,3));
$result = $this->setData($key, isset($args[0]) ? $args[0] : null);
//Varien_Profiler::stop('SETTER: '.get_class($this).'::'.$method);
return $result;
case 'uns' :
//Varien_Profiler::start('UNS: '.get_class($this).'::'.$method);
$key = $this->_underscore(substr($method,3));
$result = $this->unsetData($key);
//Varien_Profiler::stop('UNS: '.get_class($this).'::'.$method);
return $result;
case 'has' :
//Varien_Profiler::start('HAS: '.get_class($this).'::'.$method);
$key = $this->_underscore(substr($method,3));
//Varien_Profiler::stop('HAS: '.get_class($this).'::'.$method);
return isset($this->_data[$key]);
}
throw new Varien_Exception("Invalid method ".get_class($this)."::".$method."(".print_r($args,1).")");
}
Thus, we you call getSomething
, setSomething
, hasSomething
or unsSomething
, this method uses the data to return something (via getData
, setData
and unsetData
.
In 1.9.3, Mage_Uploader_Model_Config_Abstract
overrides this method :
public function __call($method, $args)
{
$key = lcfirst($this->_camelize(substr($method,3)));
switch (substr($method, 0, 3)) {
case 'get' :
$data = $this->getData($key, isset($args[0]) ? $args[0] : null);
return $data;
case 'set' :
$result = $this->setData($key, isset($args[0]) ? $args[0] : null);
return $result;
case 'uns' :
$result = $this->unsetData($key);
return $result;
case 'has' :
return isset($this->_data[$key]);
}
throw new Varien_Exception("Invalid method ".get_class($this)."::".$method."(".print_r($args,1).")");
}
The difference is that the key is not generated the same way.
Thus if you call getMyDescription()
you will get the following:
- With
Varien_Object
: it will try to get the data with key =my_description
- With
Mage_Uploader_Model_Config_Abstract
: it will try to get the data with key =myDescription
To summarize, the result of the __call
method is not consistent with every other Magento classes, the only other exception I'm aware of is Mage_Paypal_Model_Payflow_Request