ZF-5819: Zend_Db_Table_Row_Abstract::setFromArray removes data key/value pair if key is not a DB column
Description
Data provided to row by 'setFromArray' method are deleted if the key is not a DB column (key is not present in self::_data array) without call '_transformColumn'.
\
public function setFromArray(array $data)
{
$data = array_intersect_key($data, $this->_data);
foreach ($data as $columnName => $value) {
$this->__set($columnName, $value);
}
return $this;
}
public function setFromArray(array $data)
{
foreach ($data as $columnName => $value) {
$this->__set($columnName, $value);
}
return $this;
}
The magic method '__set' (invoked in setFromArray for each key/value pair):
- call the self::_transformColumn method (used for inflection, for example);
- check the existence of 'column' in self::_data array (raising an exception if not found).
public function __set($columnName, $value)
{
$columnName = $this->_transformColumn($columnName);
if (!array_key_exists($columnName, $this->_data)) {
require_once 'Zend/Db/Table/Row/Exception.php';
throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row");
}
$this->_data[$columnName] = $value;
$this->_modifiedFields[$columnName] = true;
}
So ``` may be safely removed.
Comments
Posted by Helgi Hrafn Halldórsson (harabanar) on 2009-04-24T04:30:21.000+0000
When using Oracle the database column names are usually in uppercase, while the names of the input fields are in lower. For that we use the _transformColumn function. When using the setFromArray, when posting data from a form, the array_intersect_key function will return an empty array, and no data will be set.
So, I vote for this issue to be resolved.
If the array_intersect_key function must be, I suggest that the _transformColumn function is used before, so the array keys have been transformed before removal.
Hope this will be fixed. For now I have overwritten the setFromArray function and removed the following line
```
ps. I am using 1.7.8
Posted by Richard Jones (talentedmrjones) on 2009-12-19T12:21:50.000+0000
I wholeheartedly concur. In my applications I prefer to hide the column names from the user in forms and rely on _transformColumn for column name mapping. So in some cases where setFromArray is used I have to override that function in my concrete row class rather than modifying core.
I dont see an issue with removing the array_intersect_key function, as the current implementation of __set() will catch column names that do not exist in the row.
Posted by starflash (starflash) on 2010-12-17T01:29:10.000+0000
I agree.
For example:
The db table has tow columns: test_1, test_2 .
my _transformColumn function is:
'test_one' => 'test_1', 'test_two' => 'test_2',
when I invoke setFromArray(array('test_one' => 'abc', 'test_two' => 'abc)), and no data will be set.