ZF-4759: Default row values are not saved to the database

Description

When saving new table row to the database default values are filtered and not saved to the database. IMHO, we should not check for modified fields when inserting a new row Replacing two lines


$data = array_intersect_key($this->_data, $this->_modifiedFields);
$primaryKey = $this->_getTable()->insert($data);

with


$primaryKey = $this->_getTable()->insert($this->_data);

should fix the problem

Comments

fix bug for #bughuntday

As I see the issue is not resolved yet. To avoid the problem I followed this way. I put this lines in pre-insert logic


protected function _insert()
{
    foreach ($this->_table->getDefaultValues() as $k=>$v) {
        $this->_modifiedFields[$k] = true;
    }
}

I think that the issue comes when defaultSource is set to self::DEFAULT_CLASS. Then, the default value must be passed to the insert statement and thus, must be touched to become a modifiedFields.

In the Zend_Db_Table_Abstract::createRow, i would merge the $data from argument with the defaults value before the call to SetFromArray

Change:

} elseif ($defaultSource == self::DEFAULT_CLASS && $this->_defaultValues) {

        foreach ($this->_defaultValues as $defaultName => $defaultValue) {
            if (array_key_exists($defaultName, $defaults)) {
                $defaults[$defaultName] = $defaultValue;
            }
        }

}

with something like

} elseif ($defaultSource == self::DEFAULT_CLASS && $this->_defaultValues) {

        foreach ($this->_defaultValues as $defaultName => $defaultValue) {
            if (array_key_exists($defaultName, $defaults)) {
                $defaults[$defaultName] = $defaultValue;
            }
        }
       // add the defaults value to the data, values specified in $data override defaults one 
       $data = array_merge($defaults, $data);
    }

Be aware that with this fix, you can no longer mix default value from the database and from the class. But I think it's not really recommended and was not the purpose of this functionnality.

The problem occurs due to default values aren't flagged in $_modifiedFields array. They are just assigned to $_data. Other fields that you change go through __set method and 'true' is set for each changed field in $_modifiedFields.

I would create a method to set initial data:

protected function _setData(array $data) { $this->_data = $data; $this->_modifiedFields = array_combine(array_keys($data), array_fill(0, count($data), true)); }

thanks.