\Drupal\Core\Form\FormHelper::processStates checks whether the #type property is 'item'. However, the #type property is (afaik) optional and can be undefined for render items that aren't form elements. Compare with \Drupal\Core\Render::doRender, which checks:
if (isset($elements['#type']) && empty($elements['#defaults_loaded'])) {
$elements += $this->elementInfo->getInfo($elements['#type']);
}
So \Drupal\Core\Form\FormHelper::processStates might also need an isset() check there. Since type-less render elements aren't form elements, they also need the #wrapper_attributes set.
Steps to reproduce
Proposed resolution
TBD
Remaining tasks
Update IS
Add test
Review
Comment | File | Size | Author |
---|---|---|---|
#22 | 2846320-nr-bot.txt | 179 bytes | needs-review-queue-bot |
#2 | 0001-Issue-2846320-drupal_process_states-causes-notices-o.patch | 1.08 KB | cburschka |
Issue fork drupal-2846320
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
cburschkaComment #4
LoMo CreditAttribution: LoMo as a volunteer commented@cburschka The patch looks good to me and currently still applies on the 8.4.x-dev branch. I think this is basic enough (and logical enough) that it's reasonable to set status to RTBC, but it could be good on issues like this to provide "steps to replicate". Then I'd feel better about saying I'd "tested" the fix.
Anyway, I do think that your logic and fix both make sense.
Comment #5
tstoeckler#type
is actually not optional. You can omit it for'#type' => 'markup'
by simply using#markup
, but other than that it always needs to be specified. Can you elaborate on how you hit this problem?Comment #6
cburschkahttps://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21...
Specifying #theme is usually mutually exclusive with specifying #type...
I can't quite recall the exact code that triggered the E_NOTICE right now, but it was probably a form containing a generic render element. I'll see if I can get a simple reproducible example.
Comment #7
LoMo CreditAttribution: LoMo as a volunteer commented@tstoeckler You are probably right, but there are plenty of examples in core of such "defensive" coding that use
isset()
before attempting to access something like$element['#type']
, and core/lib/Drupal/Core/Render/RendererInterface.php includes the following comment:… so one might think that the
#type
could be optional. In any case, I do feel that it's always better practice to use code that tests whether an array element exists before attempting to access its value. ;-)@cburschka, assuming #type is non-optional, perhaps getting a notice is not really a bug. I still think your patch can't hurt.
Comment #8
tstoecklerI agree that we should be safe in either case, but I'm just not sure whether elements without a
#type
should have#attributes
set or#wrapper_attributes
.Edit: On the other hand, in this particular case, I'm not actually sure whether it's valid that this is called on something that is not a render element. I don't think we support hiding regular output of a
#theme
element with#states
.Comment #9
cburschkaHi, I finally recovered the sample code that triggered this. Basically, we had an ordinary #theme element that needed to be toggled with a #state:
In addition to triggering the notice, this code isn't currently working, as there is no element to set the required attributes on.
This can be fixed by adding '#type' => 'item' to the element, without affecting any other functionality. I'm not sure if there is any way to improve this - implicitly giving everything with #states the fallback type 'item' sounds a bit too complex.
Comment #15
chrisfromredfinI am seeing this with the token_tree_link theme element.
Also:
$elements["#states"]["visible"]["input[name$=\"[third_party_settings][linked_field][linked]\"]"]
... so it seems like there's a need to process states but for a token tree (not a field element). This happens when hitting the gear from Manage Display of a node.
Comment #22
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #23
mstrelan CreditAttribution: mstrelan at PreviousNext commentedThe function drupal_process_states() has moved to \Drupal\Core\Form\FormHelper::processStates, see Procedural function drupal_process_states() is deprecated.
Comment #26
arunkumarkThe
drupal_process_states()
has been deprecated on Drupal 9.x version. The change record is available Procedural function drupal_process_states() is deprecated.The patch has been rerolled and MR created to apply to the latest Drupal core version.
Comment #27
smustgrave CreditAttribution: smustgrave at Mobomo commentedThe proposed solution should be added to the issue summary.
A test case will also be needed.
Comment #29
FeyP CreditAttribution: FeyP as a volunteer and at werk21 commentedThanks for working on this issue. This looks very similar to #2700667: Notice: Undefined index: #type in Drupal\Core\Form\FormHelper::processStates() . The other issue doesn't have an MR already, but is older, has a patch with a kernel test, has way more followers and even more recent activity, so I'm going to close this one as a duplicate. It would be great, if you could continue working on this in the other issue. Feel free to reopen, if I missed something. Thanks again.