protected function WebformSubmissionConditionsValidator::getBuildElementsRecursive in Webform 8.5
Same name and namespace in other branches
- 6.x src/WebformSubmissionConditionsValidator.php \Drupal\webform\WebformSubmissionConditionsValidator::getBuildElementsRecursive()
Recurse through a form, review #states/#required, and get visible elements.
Parameters
array $elements: Visible elements with #states property.
array $form: An associative array containing the structure of the form.
array $parent_states: An associative array containing 'required'/'optional' states from parent container to be set on the element.
1 call to WebformSubmissionConditionsValidator::getBuildElementsRecursive()
- WebformSubmissionConditionsValidator::getBuildElements in src/
WebformSubmissionConditionsValidator.php - Build and get visible elements from a form.
File
- src/
WebformSubmissionConditionsValidator.php, line 906
Class
- WebformSubmissionConditionsValidator
- Webform submission conditions (#states) validator.
Namespace
Drupal\webformCode
protected function getBuildElementsRecursive(array &$elements, array &$form, array $parent_states = []) {
foreach ($form as $key => &$element) {
if (!WebformElementHelper::isElement($element, $key)) {
continue;
}
// Pass parent states to sub-element states.
$subelement_states = $parent_states;
if (!empty($element['#states']) || !empty($parent_states)) {
if (!empty($element['#required'])) {
// If element has #states and is #required there may be a conflict where
// visibly hidden elements are required. The solution is to convert
// #required into corresponding 'required/optional' states based on
// 'visible/invisible' states.
if (!isset($element['#states']['required']) && !isset($element['#states']['optional'])) {
if (isset($element['#states']['visible'])) {
$element['#states']['required'] = $element['#states']['visible'];
}
elseif (isset($element['#states']['visible-slide'])) {
$element['#states']['required'] = $element['#states']['visible-slide'];
}
elseif (isset($element['#states']['invisible'])) {
$element['#states']['optional'] = $element['#states']['invisible'];
}
elseif (isset($element['#states']['invisible-slide'])) {
$element['#states']['optional'] = $element['#states']['invisible-slide'];
}
elseif ($parent_states) {
$element += [
'#states' => [],
];
$element['#states'] += $parent_states;
}
}
if (isset($element['#states']['optional']) || isset($element['#states']['required'])) {
unset($element['#required']);
}
// Store a reference to the original #required value so that
// form alter hooks know if the element's required/optional #states
// are based the 'visible/invisible' states or the parent states.
if (!isset($element['#required'])) {
$element['#_required'] = TRUE;
}
}
// If this container element has a visibility state, make its
// sub-elements required/optional based on this state.
if (isset($element['#states']['visible'])) {
$subelement_states = [
'required' => $element['#states']['visible'],
];
}
elseif (isset($element['#states']['visible-slide'])) {
$subelement_states = [
'required' => $element['#states']['visible-slide'],
];
}
elseif (isset($element['#states']['invisible'])) {
$subelement_states = [
'optional' => $element['#states']['invisible'],
];
}
elseif (isset($element['#states']['invisible-slide'])) {
$subelement_states = [
'optional' => $element['#states']['invisible-slide'],
];
}
}
// Store original #access in #_webform_access for all elements.
// @see \Drupal\webform\WebformSubmissionConditionsValidator::submitFormRecursive
if (isset($element['#access'])) {
$element['#_webform_access'] = $element['#access'];
}
// Skip if element is not accessible.
if (!WebformElementHelper::isAccessibleElement($element)) {
continue;
}
$elements[$key] =& $element;
$this
->getBuildElementsRecursive($elements, $element, $subelement_states);
$element_plugin = $this->elementManager
->getElementInstance($element);
if ($element_plugin instanceof WebformCompositeBase && !$element_plugin
->hasMultipleValues($element)) {
// Handle composite with single item.
if ($subelement_states) {
$composite_elements = $element_plugin
->getCompositeElements();
foreach ($composite_elements as $composite_key => $composite_element) {
// Skip if #access is set to FALSE.
if (isset($element['#' . $composite_key . '__access']) && $element['#' . $composite_key . '__access'] === FALSE) {
continue;
}
// Move #composite__required to #composite___required which triggers
// conditional #_required handling.
if (!empty($element['#' . $composite_key . '__required'])) {
unset($element['#' . $composite_key . '__required']);
$element['#' . $composite_key . '___required'] = TRUE;
$element['#' . $composite_key . '__states'] = $subelement_states;
}
}
}
}
elseif (isset($element['#element']) && isset($element['#webform_composite_elements'])) {
// Handle composite with multiple items and custom composite elements.
//
// For $element['#elements'] ...
// @see \Drupal\webform\Plugin\WebformElement\WebformCompositeBase::prepareMultipleWrapper
//
// For $element['#webform_composite_elements'] ...
// @see \Drupal\webform\Plugin\WebformElement\WebformCompositeBase::initializeCompositeElements
// @see \Drupal\webform_composite\Plugin\WebformElement\WebformComposite::initializeCompositeElements
//
// Recurse through a composite's sub elements.
$this
->getBuildElementsRecursive($elements, $element['#element'], $subelement_states);
}
}
}