Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ActiveRelationTrait.php for compatibility 7.4 #17769

Closed
wants to merge 1 commit into from

Conversation

indrig
Copy link

@indrig indrig commented Dec 27, 2019

Fix for PHP 7.4

Trying to access array offset on value of type null
When $model is null on Php 7.4:
if (($value = $model[$attribute]) !== null)

/var/www/builds/cms/3.6.0/vendor/yiisoft/yii2/db/ActiveRelationTrait.php line 526

#0 /var/www/builds/cms/3.6.0/vendor/yiisoft/yii2/db/ActiveRelationTrait.php(526): yii\base\ErrorHandler->handleError()
#1 /var/www/builds/cms/3.6.0/vendor/yiisoft/yii2/db/ActiveRelationTrait.php(246): yii\db\ActiveQuery->filterByModels()
#2 /var/www/builds/cms/3.6.0/vendor/yiisoft/yii2/db/ActiveQueryTrait.php(151): yii\db\ActiveQuery->populateRelation()
#3 /var/www/builds/cms/3.6.0/vendor/yiisoft/yii2/db/ActiveQuery.php(224): yii\db\ActiveQuery->findWith()

Q A
Is bugfix? ✔️
New feature?
Breaks BC?
Tests pass?
Fixed issues comma-separated list of tickets # fixed by the PR, if any

Fix for PHP 7.4

Trying to access array offset on value of type null
When $model is null on Php 7.4:
if (($value = $model[$attribute]) !== null)

/var/www/builds/cms/3.6.0/vendor/yiisoft/yii2/db/ActiveRelationTrait.php line 526

#0 /var/www/builds/cms/3.6.0/vendor/yiisoft/yii2/db/ActiveRelationTrait.php(526): yii\base\ErrorHandler->handleError()
yiisoft#1 /var/www/builds/cms/3.6.0/vendor/yiisoft/yii2/db/ActiveRelationTrait.php(246): yii\db\ActiveQuery->filterByModels()
yiisoft#2 /var/www/builds/cms/3.6.0/vendor/yiisoft/yii2/db/ActiveQueryTrait.php(151): yii\db\ActiveQuery->populateRelation()
yiisoft#3 /var/www/builds/cms/3.6.0/vendor/yiisoft/yii2/db/ActiveQuery.php(224): yii\db\ActiveQuery->findWith()
@samdark samdark added the php7 label Dec 27, 2019
@samdark samdark added this to the 2.0.32 milestone Dec 27, 2019
@samdark samdark added the pr:request for unit tests Unit tests are needed. label Dec 27, 2019
@yii-bot
Copy link

yii-bot commented Dec 27, 2019

Thank you for putting effort in the improvement of the Yii framework.
We have reviewed your pull request.

In order for the framework and your solution to remain stable in the future, we have a unit test requirement in place. Therefore we can only accept your pull request if it is covered by unit tests.

Could you add these please?

Thanks!

P.S. If you have any questions about the creation of unit tests? Don't hesitate to ask for support. More information about unit tests

This is an automated comment, triggered by adding the label pr:request for unit tests.

@@ -523,7 +523,7 @@ private function filterByModels($models)
// single key
$attribute = reset($this->link);
foreach ($models as $model) {
if (($value = $model[$attribute]) !== null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the code I don't see anything that would fail on PHP 7 but won't fail on PHP 5. Are you sure it's PHP 7 specific?

Copy link
Contributor

@Ximich Ximich Apr 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samdark, yes, I can confirm it's php 7.4 incompatible change: https://www.php.net/manual/en/migration74.incompatible.php

Array-style access of non-arrays
Trying to use values of type null, bool, int, float or resource as an array (such as $null["key"]) will now generate a notice.

Please, merge this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I need create another PR or you can merge this one?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ximich How can you get null in $models?

Copy link
Contributor

@Ximich Ximich Apr 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rob006, in relation with via, where relation attribute has null value.

    public function getSomething()
    {
        return $this->hasOne(Something::class, ['id' => 'something_id'])->via('viaAnotherModel');
    }

Example:

class Thing extends ActiveRecord
{
    public function getSomething()
    {
        return $this->hasOne(Something::class, ['id' => 'something_id'])->via('viaAnotherModel');
    }
}

$thing = new Thing;
$thing->id = 1;
$thing->something_id = null;
$thing->save();

Thing::find()->where(['id' => 1])->one(); // throw this exception

This code works fine in php 7.3.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

populateRelation() method in ActiveRelationTrait return $viaModels with null value in this case here: https://github.com/yiisoft/yii2/blob/master/framework/db/ActiveRelationTrait.php#L245

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we remove these nulls from $models before calling filterByModels()? IMO it looks weird that this method needs to handle nulls, while it obviously expecting models.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know where's right place to filter null models. @samdark, what do you think: should we filter null $models in populateRelation() method or check it in filterByModels()?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filtering sounds like a right thing to do.

@yiisoft yiisoft deleted a comment from yii-bot Jan 9, 2020
@samdark samdark removed this from the 2.0.32 milestone Jan 9, 2020
@samdark samdark added the expired Information requested was not provided in two weeks. label Jan 20, 2020
@yii-bot
Copy link

yii-bot commented Jan 20, 2020

It has been 2 or more weeks with no response on our request for more information.
In order for our issue tracker to be effective, we are closing this issue.

If you want it to be reopened again, feel free to supply us with the requested information.

Thanks!

This is an automated comment, triggered by adding the label expired.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
expired Information requested was not provided in two weeks. php7 pr:request for unit tests Unit tests are needed. status:need more info
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants