Nejsou správně validovaná podmíněně povinná pole
Je potřeba upravit kód v modulu Conditional fields podle
https://www.drupal.org/project/conditional_fields/issues/1561272
=====================
diff --git a/conditional_fields.module b/conditional_fields.module
index 5b50edd..33d2bc6 100644
--- a/conditional_fields.module
+++ b/conditional_fields.module
@@ -541,7 +541,7 @@ function conditional_fields_form_after_build($form, &$form_state) {
}
// Add validation callback to element if the dependency can be evaluated.
- if (in_array($options['condition'], array('value', 'empty', '!empty'))) {
+ if (in_array($options['condition'], array('value', 'empty', '!empty', 'checked', '!checked'))) {
_conditional_fields_element_add_property($dependent_form_field, '#element_validate', 'conditional_fields_dependent_validate', 'append');
}
@@ -672,10 +672,86 @@ function conditional_fields_form_after_build($form, &$form_state) {
* @see conditional_fields_form_validate()
*/
function conditional_fields_dependent_validate($element, &$form_state, $form) {
+
+ if (isset($element['#access']) && !$element['#access']) {
+ return;
+ }
+
$dependent = $element[$element['#language']];
// Check if this field's dependencies were triggered.
- if (conditional_fields_evaluate_dependencies($dependent, $form, $form_state)) {
+ $triggered = conditional_fields_evaluate_dependencies($dependent, $form, $form_state);
+
+ // If true - previous validation errors (like 'required') will be shown.
+ $show_previous_errors = TRUE;
+
+ if ($evaluated_dependencies = conditional_fields_evaluate_dependencies($dependent, $form, $form_state, FALSE)) {
+
+ foreach ($evaluated_dependencies[$dependent['#field_name']] as $operator) {
+ foreach ($operator as $state => $result) {
+ // Silently suppress errors if became invisible or optional
+ // (skip further processing).
+ if ($triggered && in_array($state, array('!required', '!visible'))) {
+ $show_previous_errors = FALSE;
+ }
+ // The same with hidden fields that did not become visible.
+ if (!$triggered && $state == 'visible') {
+ $show_previous_errors = FALSE;
+ }
+ if ($triggered && $state == 'required') {
+ $show_previous_errors = FALSE;
+ $key_exists = NULL;
+ $input_state = drupal_array_get_nested_value($form_state['values'], $dependent['#parents'], $key_exists);
+
+ if ($key_exists) {
+ // Remove the 'value' of the 'add more' button.
+ unset($input_state['add_more']);
+ }
+ $input_state = (is_null($input_state)) ? array() : $input_state;
+ if (isset($dependent['#field_name'])) {
+ $field = field_info_field($dependent['#field_name']);
+ $input_state = _field_filter_items($field, $input_state);
+ }
+
+ $info = field_info_field($dependent['#field_name']);
+ $function = $info['module'] . '_field_is_empty';
+
+ if (!empty($input_state)) {
+ $is_empty = TRUE;
+ foreach ($input_state as $value) {
+ if (function_exists($function)) {
+ $is_empty = $is_empty && $function($value, $info);
+ }
+ }
+
+ //TEMP see #2028085
+ if (isset($info['type']) && ($info['type'] == 'list_boolean')) {
+ $is_empty = TRUE;
+ foreach ($input_state as $value) {
+ if (function_exists($function)) {
+ $is_empty = $is_empty && ($value['value'] == 0);
+ }
+ }
+ }
+ }
+
+ // If conditionally required field is empty, show the error.
+ if (empty($input_state) || $is_empty) {
+ $title = '';
+ if (isset($dependent['#title'])) {
+ $title = $dependent['#title'];
+ }
+ elseif (isset($dependent[0]['#title'])) {
+ $title = $dependent[0]['#title'];
+ }
+ form_error($element, t('!name field is required.', array('!name' => $title)));
+ }
+ }
+ }
+ }
+ }
+
+ if ($show_previous_errors) {
return;
}
@@ -685,7 +761,7 @@ function conditional_fields_dependent_validate($element, &$form_state, $form) {
// Optional behavior: reset the field to its default values.
// Default values are always valid, so it's safe to skip validation.
- if (!empty($element['#conditional_fields_reset_if_untriggered'])) {
+ if (!empty($element['#conditional_fields_reset_if_untriggered']) && !$triggered) {
$form_state_addition['reset'] = TRUE;
}
@@ -756,10 +832,7 @@ function conditional_fields_form_validate($form, &$form_state) {
continue;
}
- if (empty($field['reset'])) {
- unset($field_values_location[$dependent['#field_name']]);
- }
- else {
+ if (!empty($field['reset'])) {
$dependent_info = field_form_get_state($dependent['#field_parents'], $dependent['#field_name'], $dependent['#language'], $form_state);
$field_values_location[$dependent['#field_name']][$dependent['#language']] = field_get_default_value($dependent_info['instance']['entity_type'], NULL, $dependent_info['field'], $dependent_info['instance'], $dependent['#language']);
}
@@ -999,22 +1072,31 @@ function conditional_fields_evaluate_grouping($groups) {
* @param $dependent
* The field form element in the current language.
*/
-function conditional_fields_evaluate_dependencies($dependent, $form, $form_state) {
+function conditional_fields_evaluate_dependencies($dependent, $form, $form_state, $grouping = TRUE) {
$dependencies = $form['#conditional_fields'][$dependent['#field_name']]['dependees'];
$evaluated_dependees = array();
foreach ($dependencies as $dependency_id => $dependency) {
// Skip dependencies that can't be evaluated.
- if (!in_array($dependency['options']['condition'], array('value', 'empty', '!empty'))) {
+ if (!in_array($dependency['options']['condition'], array('value', 'empty', '!empty', 'checked', '!checked'))) {
continue;
}
$values = conditional_fields_field_form_get_values($dependency['dependee'], $form, $form_state);
- $evaluated_dependees[$dependent['#field_name']][$dependency['options']['grouping']][] = conditional_fields_evaluate_dependency('edit', $values, $dependency['options']);
+ if ($grouping) {
+ $evaluated_dependees[$dependent['#field_name']][$dependency['options']['grouping']][] = conditional_fields_evaluate_dependency('edit', $values, $dependency['options']);
+ }
+ else {
+ $evaluated_dependees[$dependent['#field_name']][$dependency['options']['grouping']][$dependency['options']['state']] = conditional_fields_evaluate_dependency('edit', $values, $dependency['options']);
+ }
+ }
+
+ if ($grouping) {
+ return conditional_fields_evaluate_grouping($evaluated_dependees[$dependent['#field_name']]);
}
- return conditional_fields_evaluate_grouping($evaluated_dependees[$dependent['#field_name']]);
+ return $evaluated_dependees;
}
/**
@@ -1059,9 +1141,28 @@ function conditional_fields_evaluate_dependency($context, $values, $options) {
if ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_WIDGET) {
$dependency_values = $context == 'view' ? $options['value'] : $options['value_form'];
+ if ($options['condition'] === '!empty') {
+ $values = (isset($values[0]['value'])) ? $values[0]['value'] : $values;
+ $values = ($values === '_none') ? '' : $values;
+ return (!empty($values)) ? TRUE : FALSE;
+ }
+
+ if ($options['condition'] === 'empty') {
+ $values = (isset($values[0]['value'])) ? $values[0]['value'] : $values;
+ $values = ($values === '_none') ? '' : $values;
+ return (empty($values)) ? TRUE : FALSE;
+ }
+
+ // The BooleanList widget provides an empty array as $dependency_values, thus
+ // checking this field requires a different handling in case of 'checked or
+ // '!checked' conditions, where $value has 0 or 1.
+ if ($options['condition'] === 'checked' || $options['condition'] === '!checked') {
+ $dependency_values = (int)($options['condition'] === 'checked');
+ }
+
// Simple case: both values are strings or integers. Should never happen in
// view context, but does no harm to check anyway.
- if (!is_array($values)) {
+ if (!is_array($values) || (is_array($values) && (empty($values) || in_array($options['condition'], ['checked', '!checked'])))) {
// Options elements consider "_none" value same as empty.
$values = $values === '_none' ? '' : $values;
@@ -1087,14 +1188,30 @@ function conditional_fields_evaluate_dependency($context, $values, $options) {
// If $dependency_values is not an array, we can only assume that it
// should map to the first key of the first value of $values.
if (!is_array($dependency_values)) {
- $key = current(array_keys((array) current($values)));
- $dependency_values = array(array($key => $dependency_values));
+
+ if(is_null(current($values))) {
+ return FALSE;
+ }
+
+ if (count($options['value'])) {
+ $key = current(array_keys((array) current($values)));
+ $dependency_values = array(array($key => $options['value'][0][$key]));
+ $temp[][$key] = $values[0][$key];
+ $values = $temp;
+ }
}
// Compare arrays recursively ignoring keys, since multiple select widgets
// values have numeric keys in form format and string keys in storage
// format.
- return array_values($dependency_values) == array_values($values);
+ if (is_array($dependency_values)) {
+ return array_values($dependency_values) == array_values($values);
+ }
+ else {
+ // If dependency value is not array (checked/unchecked state), compare
+ // to the first value.
+ return $dependency_values == $values[0]['value'];
+ }
}
// $values, when viewing fields, may contain all sort of additional