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

[4.x]: BaseRelationField::afterElementSave $value can be type Collection instead of ElementQuery #11667

Closed
Anubarak opened this issue Jul 25, 2022 · 5 comments

Comments

@Anubarak
Copy link
Contributor

What happened?

Description

I recently updated a project to Craft 4 and due to heavy logic I need to eager load many fields - even after setting them.
So I frequently end up with logic like

$entry->setFieldValue('field', [$otherEntry->id[);
$entry->setEagerLoadedElements('field', [$otherEntry]);
$entry->setEagerLoadedElementCount('field', 1);

Because otherwise the amount of duplicated Queries would be insane.
Unfortunately you changed your Element.php and added a

        // Was this field’s value eager-loaded?
        if ($this->hasEagerLoadedElements($fieldHandle)) {
            return $this->getEagerLoadedElements($fieldHandle);
        }

condition in your getFieldValue. Due to that code your BaseRelationField::afterElementSave receives a Collection instead of a Query as it's value and the next conditions will fail.

Steps to reproduce

  1. load an element
  2. set a Relation field value
  3. eager load that field
  4. save the element

Expected behavior

Your BaseRelationField should either check the value or the Element should be able to return the Query instead

Actual behavior

There is an Exception Property [id] does not exist on this collection instance.

Craft CMS version

4.x

PHP version

8.1

Operating system and version

No response

Database type and version

No response

Image driver and version

No response

Installed plugins and versions

No response

@brandonkelly
Copy link
Member

I don’t see how that could have worked in Craft 3 if $value was an eager-loaded element array. This line should have thrown a PHP error:

if ($value->id !== null) {

@Anubarak
Copy link
Contributor Author

Anubarak commented Jul 26, 2022

In Craft 3 getFieldValue always returned the query and not the array of elements. It was all due to your change in this function

public function getFieldValue(string $fieldHandle)

Vs

https://github.com/craftcms/cms/blob/develop/src/base/Element.php#L3746

The same error occurs if you mark the element as dirty as described in my matrix example.
What would you suggest / recommend in case you don't want to fix it? The problem is: I have a project that calculates about 200 values for industrial fans. I have about 150 different formulas that require tons of relations again and again.
Rewriting everything and pass related elements as arguments instead of just the entry would take weeks as well as custom wrapper functions.

@brandonkelly
Copy link
Member

Ahhh, ok, thanks! Got this and #11670 fixed for the next release.

@Anubarak
Copy link
Contributor Author

What a relief - thank you very much.
I thought had to rewrite everything.

@brandonkelly
Copy link
Member

4.2.0 is out with those fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants