yii2
yii2 copied to clipboard
Version 2.0.46 brakes saving in DB
I have updated Yii2 up to 2.0.46
My code was working well, but I started to get the following:
PHP Notice 'yii\base\ErrorException' with message 'Undefined index: Id'
in .../vendor/yiisoft/yii2/db/BaseActiveRecord.php:1765
Stack trace:
#0 ...vendor/yiisoft/yii2/db/BaseActiveRecord.php(1765): yii\base\ErrorHandler->handleError(8, 'Undefined index...', '...', 1765, Array)
#1 .../vendor/yiisoft/yii2/db/BaseActiveRecord.php(642): yii\db\BaseActiveRecord->isAttributeDirty('Id', 22813)
...
I have analyzed changes done between 2.0.45 and 2.0.46 and found the following: https://github.com/yiisoft/yii2/commit/0f004db99b93e731b0e4cdbd35dcf78d86701f87 Here,
- if (isset($names[$name]) && (!array_key_exists($name, $this->_oldAttributes) || $value !== $this->_oldAttributes[$name])) {
+ if (isset($names[$name]) && (!array_key_exists($name, $this->_oldAttributes) || $this->isAttributeDirty($name, $value))) {
Where isAttributeDirty is a new function that looks like:
private function isAttributeDirty($attribute, $value)
{
$old_attribute = $this->oldAttributes[$attribute];
if (is_array($value) && is_array($this->oldAttributes[$attribute])) {
$value = ArrayHelper::recursiveSort($value);
$old_attribute = ArrayHelper::recursiveSort($old_attribute);
}
return $value !== $old_attribute;
}
For me, interesting is, why we used $this->_oldAttributes in the older versions, but $this->oldAttributes in the newest?
So I changed the code locally to:
private function isAttributeDirty($attribute, $value)
{
$old_attribute = $this->_oldAttributes[$attribute];
if (is_array($value) && is_array($this->_oldAttributes[$attribute])) {
$value = ArrayHelper::recursiveSort($value);
$old_attribute = ArrayHelper::recursiveSort($old_attribute);
}
return $value !== $old_attribute;
}
and that works back as it used to be before.
Is this a bug, or feature?
looks like typo for me
Damn, indeed. I wonder why the tests didn't show anything. Could you prepare PR fixing this? With proper tests if possible?
@bizley, This isn`t a typo, see this
Hmm, right... Missed that getter. So what is going on here? This should not affect anything. @rsemenyshyn could you provide us with a minimal data to reproduce the problem?
For me, interesting is, why we used $this->_oldAttributes in the older versions, but $this->oldAttributes in the newest?
because $this->oldAttributes calling $this->getOldAttributes(), by default, $this->_oldAttributes is null i.e. not array
https://github.com/yiisoft/yii2/blob/27344557ea415011afda1d26be0df1496a1cc51a/framework/db/BaseActiveRecord.php#L93
private function isAttributeDirty($attribute, $value)
{
$oldAttributes = $this->getOldAttributes();
if (!array_key_exists($attribute, $oldAttributes)) {
return false;
}
if ($value === $oldAttributes[$attribute]) {
return true;
}
return \yii\helpers\Comparator::compare($value, $oldAttributes[$attribute]);
}
Since this change broke app and we have many reports about it I would say that we need to rollback it. @samdark ?
Hi @samdark, was there some discussion/progress on @bizley request to revert?
Hi @samdark, was there some discussion/progress on @bizley request to revert?
@markch123 see https://github.com/yiisoft/yii2/issues/19546
Closing since it was reverted in master.