What is the difference between $model->getData() and $model->getOrigData(); methods in Magento?

$model->getOrigData() returns the data that was originally loaded from the database when you initialized the model object and called $model->load() method. After loading the model you may have performed certain updates to the $model object calling methods like $model->setData(). $model->getData() return the $model object data in the present state.

Magento models extend the class ‘Mage_Core_Model_Abstract’ which in turn extends the class ‘Varien_Object’. The methods getData() and getOrigData() have been defined in the class ‘Varien_Object’ as follows:


/**
* Retrieves data from the object
*
* If $key is empty will return all the data as an array
* Otherwise it will return value of the attribute specified by $key
*
* If $index is specified it will assume that attribute data is an array
* and retrieve corresponding member.
*
* @param string $key
* @param string|int $index
* @return mixed
*/
public function getData($key='', $index=null)
{
if (''===$key) {
return $this->_data;
}

$default = null;

// accept a/b/c as ['a']['b']['c']
if (strpos($key,'/')) {
$keyArr = explode('/', $key);
$data = $this->_data;
foreach ($keyArr as $i=>$k) {
if ($k==='') {
return $default;
}
if (is_array($data)) {
if (!isset($data[$k])) {
return $default;
}
$data = $data[$k];
} elseif ($data instanceof Varien_Object) {
$data = $data->getData($k);
} else {
return $default;
}
}
return $data;
}

// legacy functionality for $index
if (isset($this->_data[$key])) {
if (is_null($index)) {
return $this->_data[$key];
}

$value = $this->_data[$key];
if (is_array($value)) {
//if (isset($value[$index]) && (!empty($value[$index]) || strlen($value[$index]) > 0)) {
/**
* If we have any data, even if it empty - we should use it, anyway
*/
if (isset($value[$index])) {
return $value[$index];
}
return null;
} elseif (is_string($value)) {
$arr = explode("\n", $value);
return (isset($arr[$index]) && (!empty($arr[$index]) || strlen($arr[$index]) > 0))
? $arr[$index] : null;
} elseif ($value instanceof Varien_Object) {
return $value->getData($index);
}
return $default;
}
return $default;
}

 

/**
* Get object loaded data (original data)
*
* @param string $key
* @return mixed
*/
public function getOrigData($key=null)
{
if (is_null($key)) {
return $this->_origData;
}
return isset($this->_origData[$key]) ? $this->_origData[$key] : null;
}

 

The above code shows that the method getData() returns data stored in the Varien_Object class protected property $_data while getOrigData() method returns the data stored in the Varien_Object class protected property $_origData.

But now the question is how are these properties setup?

Here is the load function from the class Mage_Core_Model_Abstract:


/**
* Load object data
*
* @param   integer $id
* @return  Mage_Core_Model_Abstract
*/
public function load($id, $field=null)
{
$this->_beforeLoad($id, $field);
$this->_getResource()->load($this, $id, $field);
$this->_afterLoad();
$this->setOrigData();
$this->_hasDataChanges = false;
return $this;
}

This function calls the load() method from the resource model. The resource model calls the $model object addData()/setData() method to set the Varien_Object class protected property $_data.

Normal resource models extend the class Mage_Core_Model_Resource_Db_Abstract while the entity resource models extend the class Mage_Eav_Model_Entity_Abstract, check the load() method in these classes.

After the model loads data from the database, it calls $this->setOrigData() and set the property $_hasDataChanges as false. Here’s the code from Varien_Object class:


/**
* Initialize object original data
*
* @param string $key
* @param mixed $data
* @return Varien_Object
*/
public function setOrigData($key=null, $data=null)
{
if (is_null($key)) {
$this->_origData = $this->_data;
} else {
$this->_origData[$key] = $data;
}
return $this;
}

This copies the data from the $_data property to $_origData; in other words it makes a copy of the original object.

What’s the purpose of maintaining this copy of data?

Whenever you call $model->addData() or $model->setData(), $_hasDataChanges variable gets set true indicating that the values in the loaded model have changed.

Lets have a look at Mage_Core_Model_Abstract method:


/**
* Check whether model has changed data.
* Can be overloaded in child classes to perform advanced check whether model needs to be saved
* e.g. usign resouceModel->hasDataChanged() or any other technique
*
* @return boolean
*/
protected function _hasModelChanged()
{
return $this->hasDataChanges();
}

/**
* Save object data
*
* @return Mage_Core_Model_Abstract
*/
public function save()
{
/**
* Direct deleted items to delete method
*/
if ($this->isDeleted()) {
return $this->delete();
}
if (!$this->_hasModelChanged()) {
return $this;
}
$this->_getResource()->beginTransaction();
$dataCommited = false;

.
.                .

}

}

The save() method checks whether $_hasDataChanges is true or not before proceeding to save the data.

Code comments for the method _hasModelChanged() in above code that say that the purpose of this function is to check whether model has changed data or not. If the model has not changed any data then there is nothing to update and hence perform a database operation.

Classes like Mage_Sales_Model_Quote_Item_Option, Mage_Sales_Model_Quote_Item, Mage_Wishlist_Model_Item_Option, Mage_Wishlist_Model_Item which have Mage_Core_Model_Abstract class in their parent classes hierarchy go a step further and override _hasModelChanged() method to perform additional check in resource model as below:


protected function _hasModelChanged()
{
if (!$this->hasDataChanges()) {
return false;
}

return $this->_getResource()->hasDataChanged($this);
}

Here is the code from the class Mage_Core_Model_Resource_Db_Abstract:


/**
* Check that model data fields that can be saved
* has really changed comparing with origData
*
* @param Mage_Core_Model_Abstract $object
* @return boolean
*/
public function hasDataChanged($object)
{
if (!$object->getOrigData()) {
return true;
}

$fields = $this->_getWriteAdapter()->describeTable($this->getMainTable());
foreach (array_keys($fields) as $field) {
if ($object->getOrigData($field) != $object->getData($field)) {
return true;
}
}

return false;
}

This function makes use of the getOrigData() and the getData() methods. It compares the current object data with the original object data and returns true if any data change is found.

The functions getOrigData() and the getData() can be used for logging data changes in you website.

Leave a Comment

Back to top