Needs work
Project:
Drupal core
Version:
main
Component:
theme system
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
24 Dec 2015 at 00:29 UTC
Updated:
5 Jul 2024 at 07:18 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
hass commentedTried adding
#typeintotemplate_preprocess_form_element()at line 472, but the added type makes Drupal running out of memory!?? No idea why adding
#typemakes Drupal running out of memory. It is just one more string.Comment #3
swentel commentedDon't get it either why that goes out of memory, but something like in the attached patch works.
Comment #4
hass commentedI'm fine with this naming, but we need some feedback from core maitainers if this is acceptable. I'm not sure if we need to add an
#parentswith the original element and leave this extra key out than.RTBC the patch for now.
Comment #5
alexpottWe should have some test coverage of this.
Comment #6
hass commentedHow should the render array look like? Do you know why we cannot pass
#type?Comment #20
quietone commentedThere has been no discussion here for 8 years and much has changed since then. However, since I don't know the theme system I am asking if this is still relevant.
Is this relevant to Drupal 10?
Since we need more information to move forward with this issue, I am setting the status to Postponed (maintainer needs more info). If we don't receive additional information to help with the issue, it may be closed after three months.
Thanks!
Comment #21
bnjmnmAlthough this issue was filed when Force Awakens was #1 at the box office. I confirmed this is still an issue in mid-2024. As the long lifespan of this issue suggests, it's probably not an urgent matter but it would me nice for label preprocess to know the type of element they belong to.
Comment #2 seems like the right place to get this attribute added. If there are still memory issues like the ones reported 8 years ago, perhaps some xdebugging can sniff out the culprit.
As mentioned above, this will of course need some tests. I'm guessing there is an existing test that can get a few lines added so it's not necessary to write a whole new dang test to see if
#typeis there.Comment #22
utkarsh_33 commentedThe change that we are making to include '#type' in the keys for array_intersect_key is causing an infinite loop. This is because $element contains a reference to $variables['label'], and modifying $variables['label'] inside the function is triggering the function to be called again, leading to an infinite recursion.
The way i was able to figure that out was because adding
code makes it work load the page which was not loading earlier.
Not sure if the solution in this patch is the best solution. If it is i can add the test for the same with the patch applied.
Comment #23
bnjmnmThis was spotted in #2 as well. The next step should be figuring out why adding
#typeis causing this recursion.What is it about this additional array property causing this recursive loop? Until we know that, we won't know if the solution in #2 is the right approach. Knowing this might reveal a way to get
#typein without the need to rename - it may also reveal an underlying bug or optimization opportunity.You don't need to fully know the render system to know how this works. The process of investigating these types of bugs is what leads to the fuller understanding. I recommend looking for logic that checks for
['#type']either being present or not empty. These regexes can help you find those uses:isset\(.*\['#type'\]\)!empty\(.*\['#type'\]\). There will still be several results, but you can rule out any uses found inside a module, theme or test since the recursion happens on a minimal install. Look at what the remaining uses do and put breakpoints in places you believe the recursion might be happening. There's a good chance you'll find the cause, but if you don't you can still document which regex-matching areas you checked and what your findings were - that information is still a helpful step forward.
Comment #24
utkarsh_33 commentedAfter some debugging and reading about the rendering system i came up with what could be the reason for infinite loop.
- In the Drupal theming system, variables like $variables['label'] are passed to template files for rendering. When you're preparing variables in the
template_preprocess_form_element function, you're essentially preparing data to be used in the template file associated with the form element.
- When you add #type directly to $variables['label'], you're essentially associating the type of the form element with the label of the form element.
- The rendering of form elements in Drupal is a recursive process. When rendering a form element, Drupal may need to render its children or
related elements, which in turn may need to render their children, and so on. If, during this process, Drupal encounters the #type property
associated with a label, it may interpret this as a signal to render another form element, leading to a recursive loop.
- Drupal's rendering system may keep trying to render the label as a form element due to the presence of #type, leading to excessive resource
usage and potentially crashing the system.
So according to what i understood with the above mentioned points i think the approach we are trying to use in #2 may not be the correct way to add type to label.We should keep that as a separate property.
I was not completely able to get what needs to be done in this so i tried with what i understood and documented my understanding on this.
Comment #25
bnjmnmIf we're running into an infinite recursion issue, I recommend first finding where the recursion is occurring.
We already know that there is an infinite recursion problem when
#typeis set in the render array.This is most likely due to a condition that executes code only when
#typeis present. The two most likely ways PHP would check for the presence of#typeareisset($foo['#type'])or!empty($foo['#type'])We can use a regular expression to find places where these conditions might be set
[^\!]isset\(.*\['#type'\]\)Will look for an "isset" call without a preceding exclamation point, followed by an array path that ends#type. The regex could be even more precise, but just this narrows things down to only 9 places this could be happening.Most of the results can be ruled out because they are in modules/themes that don't need to be running for this error to occur, they are in tests, or it belongs to a class for a feature that is unrelated to the issue.
Expand the results and you can rule out additional possibilities:

This leaves only 5 possible places, making it pretty easy to check each with an xdebug breakpoint, and see which condition is getting hit infinite times.
If I place the breakpoint in the Renderer.php condition, it appears to loop infinitely when it hits an element with a
form_element_label#theme.Without even having to know that much about the render system, just a little bit of PHP / regex / xdebug we can see the recursion is happening in this block in Renderer.php
Is this best accomplished by changing the condition, or by changing what
this->elementInfo->getInfo($elements['#type']);returns, or something entirely different?Comment #26
utkarsh_33 commentedComment #28
utkarsh_33 commentedComment #29
smustgrave commentedCan we update the issue summary to the standard issue template.
Have not reviewed yet.
Comment #30
bnjmnmMR has a question about why this particular solution works and evidence that it will not result in other problems. This may require a bit of research, which is a great way to get more familiar with how core works.
This will also need a test to confirm
#typeis getting passed to the label elements. Forms in general have many tests, to there may be an existing test that you can use this so it's only necessary to add a few lines instead of having to write an entirely new test.Comment #31
utkarsh_33 commented