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

[5.x]: Fix Typed property craft\base\FieldLayoutComponent::$elementType must not be accessed before initialization error with Kint and element queries #15074

Closed
engram-design opened this issue May 27, 2024 · 5 comments
Labels

Comments

@engram-design
Copy link
Contributor

What happened?

Refer to verbb/kint#8 but since Craft 5, the plugin cannot dump ElementQuery objects anymore. This is due to an error: Typed property craft\base\FieldLayoutComponent::$elementType must not be accessed before initialization.

To reproduce this, add an Entries field to an Entry, then use Kint to output the ElementQuery (not an element collection or single element): {{ d(craft.entries.id(123).one().entriesField) }}

Disregarding the Kint factor here, I feel like this might be a Craft issue.

Taking a deep-dive into things, this seems to be due to the craft\fieldlayoutelements\CustomField (our Entries field) doesn't have an elementType associated with it yet. It's also during this investigation that I've found when settings elements on a FieldLayoutTab that it's own elementType isn't set.

I'm not 110% sure, but shouldn't the elementType for the FieldLayoutTab and resulting CustomField objects be inherited from the FieldLayout::type property? The element type that the field layout is for?

public function setElements(array $elements): void
{
    $fieldsService = Craft::$app->getFields();
    $pluginsService = Craft::$app->getPlugins();
    $this->_elements = [];

+    // Set the element type based on the field layout's element type
+    $this->elementType = $this->layout->type;
+
    foreach ($elements as $layoutElement) {
        if (is_array($layoutElement)) {
            try {
+               // Ensure that layout elements know which element type this is for
+               $layoutElement['elementType'] = $this->elementType;
                $layoutElement = $fieldsService->createLayoutElement($layoutElement);

Which seems to fix my issue. I didn't do a PR, purely because I'm not really sure if this is right, expected behaviour or otherwise.

Craft CMS version

5.1.7

PHP version

8.2.0

Operating system and version

MacOS 14.1

Database type and version

MySQL 8

Image driver and version

No response

Installed plugins and versions

  • Kint 4
@brandonkelly
Copy link
Member

This is definitely a Kint bug. Replacing d() with dump() works fine, and shows the elementType property is set as expected for the relational query:

The output of a dump() function on a relational field’s element query

To be extra sure, I installed Kint and set a breakpoint in the d() handler, and elementType is definitely set at the time the query is passed to the function:

PhpStorm screenshot showing that the element query’s elementType property is set when the d() function is first called

The field layout/tab/element’s elementType property has nothing to do with the element query; that is identifying the element type the field layout was created for. The element query’s elementType property is the element type the relational field’s element query is meant to fetch (e.g. craft\elements\Asset if it’s an Assets field).

@engram-design
Copy link
Contributor Author

So the elementType not being set is actually on the custom field's layoutElement inside the element query, not on the element query itself - which you've shown is set correctly. It's hard to show in a single screenshot without it being massive, but you can check in the tree:

CleanShot 2024-05-28 at 09 32 19@2x

That's me just calling {% dd craft.entries.id(123).one().entries %} in a template.

It's the eagerLoadSourceElement, the entries field (my Entries custom field) and the field's layoutElement

I'm keenly aware that this is probably a "my problem" sort of issue, as dump() and event the similar s() (in Kint) function works correctly. It's clearly something to do with how Kint treats objects.

brandonkelly added a commit that referenced this issue May 28, 2024
@brandonkelly
Copy link
Member

Ah ok, sorry, got confused. I just set that property to null by default, which fixes that error. However now the page is timing out, so guessing there’s an infinite recursion bug or something. I’ll leave that to you :)

@engram-design
Copy link
Contributor Author

Thanks for that, yeah probably my issue to figure out now. It's likely all to do with the kint-twig package just being stupid, but that's my problem now 😄

@brandonkelly
Copy link
Member

Craft 5.1.8 is out with that fix.

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

No branches or pull requests

2 participants