Last active
August 17, 2020 16:18
-
-
Save andybroomfield/ef5d7e92e19e8642c40ab170f51212a7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Determine if an element is visible by checking visiblity of parents. | |
* | |
* A helper around | |
* \Drupal::service('webform_submission.conditions_validator')->isElementVisible | |
* @param Array $element | |
* Webform element. | |
* @param \Drupal\Core\Form\FormStateInterface $form_state | |
* Form state object. | |
* @param Array $complete_form | |
* Form array. | |
* @return boolean | |
* True if all parent elements and the element itself if visible, | |
* else FALSE. | |
*/ | |
public static function isElementVisibleThroughParent($element, FormStateInterface $form_state, &$complete_form) { | |
// Build webform submission and get conditions validator service. | |
$form_object = $form_state->getFormObject(); | |
$webform_submission = $form_object->buildEntity($complete_form, $form_state); | |
$conditions_validator = \Drupal::service('webform_submission.conditions_validator'); | |
// Loop through each of parents elements to work out visibility. | |
$parents = $element['#webform_parents']; | |
$parent_container = $complete_form['elements']; | |
foreach ($parents as $parent) { | |
$parent_container = $parent_container[$parent]; | |
$is_visible = $conditions_validator->isElementVisible($parent_container, $webform_submission); | |
// Return FALSE as soon as an invisible element is found. | |
// The element itself will be invisible if its parent is. | |
if (!$is_visible) { | |
return FALSE; | |
} | |
} | |
// If all parents are visible, then return visibility of the element itself. | |
return $conditions_validator->isElementVisible($element, $webform_submission); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public static function validateWebformComposite(&$element, FormStateInterface $form_state, &$complete_form) { | |
// IMPORTANT: Must get values from the $form_states since sub-elements | |
// may call $form_state->setValueForElement() via their validation hook. | |
// @see \Drupal\webform\Element\WebformEmailConfirm::validateWebformEmailConfirm | |
// @see \Drupal\webform\Element\WebformOtherBase::validateWebformOther | |
$value = NestedArray::getValue($form_state->getValues(), $element['#parents']); | |
$element_key = end($element['#parents']); | |
// If the element or any of its parent containers are hidden by conditions, | |
// Bypass validation and clear any required element errors generated | |
// for this element. | |
if (!self::isElementVisibleThroughParent($element, $form_state, $complete_form)) { | |
$form_errors = $form_state->getErrors(); | |
$form_state->clearErrors(); | |
foreach($form_errors as $error_key => $error_value) { | |
if (strpos($error_key, $element_key . ']') !== 0) { | |
$form_state->setErrorByName($error_key, $error_value); | |
} | |
} | |
return; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment