Problem/Motivation

The widgets passed in a field's widget after-build does not include minimum-components. This makes it so that developers need to push their own widget property to pass on the minimum components, even though an empty minimum-components property exists on the widget.

Steps to reproduce

function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  foreach ($form_object->getEntity()->getFields() as $field) {
    $field_config = $field->getFieldDefinition();
    if (!($field_config instanceof FieldConfigInterface)) {
      continue;
    }
    $field_name = $field_config->getName();
    if (!isset($form[$field_name]) || !is_array($form[$field_name])) {
      continue;
    }

    if ($field_config->getType() === 'name') {
      if (empty($form[$field_name]['widget']) || !is_array($form[$field_name]['widget'])) {
        return;
      }

      // $field_config->getSettings()['minimum_components'] is typically available here.

      $form[$field_name]['widget']['#after_build'][] = '_mymodule_field_element_after_build';
    }
  }
}

function _mymodule_field_element_after_build(array $widget, FormStateInterface $form_state): array {
  // @todo Determine if minimum components is passed.
  if (empty($required_keys) || !is_array($required_keys)) {
    return $widget;
  }

  foreach (Element::children($widget) as $delta) {
    if (empty($widget[$delta]) || !is_array($widget[$delta])) {
      continue;
    }

    // $widget[$delta]['minimum_components'] is empty.
  }

  return $widget;
}

Proposed resolution

Supply a populated minimum-components to the field's widget.

Data model changes

The $widget[$delta]['minimum_components'] is populated in a field's widget after-build callback.

Comments

jcandan created an issue. See original summary.

bluegeek9’s picture

Is this related to the other active issue about components and being marked require?

bluegeek9’s picture

Status: Active » Postponed (maintainer needs more info)

I do not know why the #after_build needs minimum_components.

jcandan’s picture

The example code above isn’t for name. It demonstrates where to find a minimum_components property, but it’s empty.

If a module needed to know which component fields are required to do something at that point, it couldn’t.

The request here is to populate the provided minimum components property.

Use case: https://git.drupalcode.org/project/require_on_publish/-/blob/2.1.x/requi...

bluegeek9’s picture

Status: Postponed (maintainer needs more info) » Active

The components should each have a #required property.

The link you provided does have the required components passed on property, #require_on_publish_name_required_keys. But, in the #after_build callback nothing is done with them, it only checks if it exists.

jcandan’s picture

Each component does indeed have the #required property, however it is false, even on minimum components.

That's not entirely accurate that nothing is done with the required keys. On L499, I loop through this special #require_on_publish_name_required_keys workaround, and supply a #required_on_publish property on each component.

The following step-debugging screenshot shows the above are true:

screenshot showing the name field widgets do not list any minimum component in after_build

I think it would suffice if Name were to either:

  • Ensure each minimum component's #required property was correctly true.
  • Ensure the widget delta's #minium_components property was correctly populated.

But, perhaps both are warranted. Hope this helps clear things up.

jcandan’s picture