From 9c96dcdb146b41afb20db52f748d5948511e1840 Mon Sep 17 00:00:00 2001 From: kenny Date: Wed, 31 Aug 2016 15:59:26 -0500 Subject: [PATCH] * Support for multiple "Field Collection" fields * Conditional fields has no effect on additional field collections --- conditional_fields.module | 564 ++++++++++++++++++++++------------------------ 1 file changed, 268 insertions(+), 296 deletions(-) diff --git a/conditional_fields.module b/conditional_fields.module index 5b50edd..3b8145e 100644 --- a/conditional_fields.module +++ b/conditional_fields.module @@ -1,5 +1,4 @@ $dependency) { - if (!isset($form['#conditional_fields'][$field['#field_name']]['dependees'][$id])) { - conditional_fields_attach_dependency($form, array('#field_name' => $dependency['dependee']), $field, $dependency['options'], $id); + if (!isset($form['#conditional_fields'][$field_parents_key][$field['#field_name']]['dependees'][$id])) { + conditional_fields_attach_dependency($form, array('#field_name' => $dependency['dependee']), $field, $dependency['options'], $field_parents_key, $id); } } } @@ -276,8 +277,8 @@ function conditional_fields_element_after_build($element, &$form_state) { // define per-element sets of dependency values. if (isset($dependencies['dependees'][$field['#field_name']])) { foreach ($dependencies['dependees'][$field['#field_name']] as $id => $dependency) { - if (!isset($form['#conditional_fields'][$field['#field_name']]['dependents'][$id])) { - conditional_fields_attach_dependency($form, $field, array('#field_name' => $dependency['dependent']), $dependency['options'], $id); + if (!isset($form['#conditional_fields'][$field_parents_key][$field['#field_name']]['dependents'][$id])) { + conditional_fields_attach_dependency($form, $field, array('#field_name' => $dependency['dependent']), $dependency['options'], $field_parents_key, $id); } } } @@ -355,7 +356,7 @@ function conditional_fields_element_after_build($element, &$form_state) { * Note that you don't need to manually set all these options, since default * settings are always provided. */ -function conditional_fields_attach_dependency(&$form, $dependee, $dependent, $options, $id = 0) { +function conditional_fields_attach_dependency(&$form, $dependee, $dependent, $options, $field_parents_key, $id = 0) { $options += conditional_fields_dependency_default_options(); // The absence of the $id parameter identifies a custom dependency. @@ -383,11 +384,11 @@ function conditional_fields_attach_dependency(&$form, $dependee, $dependent, $op } // Attach dependee. - // Use the #array_parents property of the dependee instead of #field_parents - // since we will need access to the full structure of the widget. + // Use the #parents property of the dependee instead of #field_parents since + // we will need access to the full structure of the widget. if (isset($dependee['#parents'])) { - $form['#conditional_fields'][$dependee['#field_name']]['parents'] = $dependee['#array_parents']; - $form['#conditional_fields'][$dependee['#field_name']]['dependents'][$id] = array( + $form['#conditional_fields'][$field_parents_key][$dependee['#field_name']]['parents'] = $dependee['#parents']; + $form['#conditional_fields'][$field_parents_key][$dependee['#field_name']]['dependents'][$id] = array( 'dependent' => $dependent['#field_name'], 'options' => $options, ); @@ -401,8 +402,8 @@ function conditional_fields_attach_dependency(&$form, $dependee, $dependent, $op $dependent_parents = $dependent['#parents']; } if (isset($dependent_parents)) { - $form['#conditional_fields'][$dependent['#field_name']]['field_parents'] = $dependent_parents; - $form['#conditional_fields'][$dependent['#field_name']]['dependees'][$id] = array( + $form['#conditional_fields'][$field_parents_key][$dependent['#field_name']]['field_parents'] = $dependent_parents; + $form['#conditional_fields'][$field_parents_key][$dependent['#field_name']]['dependees'][$id] = array( 'dependee' => $dependee['#field_name'], 'options' => $options, ); @@ -430,212 +431,212 @@ function conditional_fields_form_after_build($form, &$form_state) { $state_handlers = conditional_fields_states_handlers(); // Cycle all dependents. - foreach ($form['#conditional_fields'] as $dependent => $dependent_info) { - $states = array(); - - if (empty($dependent_info['dependees'])) { - continue; - } - - $dependent_location = array_merge($dependent_info['field_parents'], array($dependent)); - $dependent_form_field = drupal_array_get_nested_value($form, $dependent_location); - - // Cycle the dependant's dependees. - foreach ($dependent_info['dependees'] as $dependency) { - $dependee = $dependency['dependee']; - - if (empty($form['#conditional_fields'][$dependee])) { - continue; - } - - $dependee_info = $form['#conditional_fields'][$dependee]; - $dependee_form_field = drupal_array_get_nested_value($form, $dependee_info['parents']); - $options = $dependency['options']; - - // Load field edit behaviors. - // If this dependent has multiple dependees, only the logic of the first - // dependency will be taken into account. - if (!isset($behaviors)) { - $behaviors = conditional_fields_field_behaviors('edit', $options); - } - - // Determine if the dependee is in the form. - if (empty($dependee_form_field) || (isset($dependee_form_field['#access']) && $dependee_form_field['#access'] == FALSE)) { - // Apply orphan dependent behaviors. - /* - if (in_array(CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN, $behaviors)) { - // TODO - $is_triggered = TRUE; - - if ($is_orphan && !$is_triggered) { - $form[$dependent]['#access'] = FALSE; - } - } - */ - if (in_array(CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN, $behaviors)) { - $dependent_form_field['#access'] = FALSE; - } - unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN]); - unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN]); - unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED]); - continue; - } - - unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN]); - unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN]); - - // Build a jQuery selector if it was not overridden by a custom value. - // Note that this may be overridden later by a state handler. - if (!$options['selector']) { - $options['selector'] = conditional_fields_field_selector($dependee_form_field); - } - else { - // Replace the language placeholder in the selector with current language. - $options['selector'] = str_replace('%lang', $dependee_form_field['#language'], $options['selector']); - } - - if ($options['condition'] != 'value') { - // Conditions different than "value" are always evaluated against TRUE. - $state = array($options['state'] => array($options['selector'] => array($options['condition'] => TRUE))); - } - else { - // Build the values that trigger the dependency. - $values = array(); - - if ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_WIDGET) { - $values[$options['condition']] = $options['value_form']; - } - elseif ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_REGEX) { - $values[$options['condition']] = $options['value']; - } - elseif ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_AND) { - $values[$options['condition']] = count($options['values']) == 1 ? $options['values'][0] : $options['values']; - } - else { - if ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_XOR) { - // XOR behaves like OR with added 'xor' element. - $values[] = 'xor'; - } - elseif ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_NOT) { - // NOT behaves like OR with switched state. - $options['state'] = strpos($options['state'], '!') === 0 ? drupal_substr($options['state'], 1) : '!' . $options['state']; - } - - // OR, NOT and XOR conditions are obtained with a nested array. - foreach ($options['values'] as $value) { - $values[] = array($options['condition'] => $value); - } - } - - $state = array($options['state'] => array($options['selector'] => $values)); - $dependee_form_state = isset($dependee_form_field['#field_parents'], $dependee_form_field['#field_name'], $dependee_form_field['#language']) ? field_form_get_state($dependee_form_field['#field_parents'], $dependee_form_field['#field_name'], $dependee_form_field['#language'], $form_state) : NULL; - - // Execute special handler for fields that need further processing. - // The handler has no return value. Modify the $state parameter by - // reference if needed. - foreach ($state_handlers as $handler => $handler_conditions) { - if (array_intersect_assoc($handler_conditions, $dependee_form_field) == $handler_conditions) { - $handler($dependee_form_field, $dependee_form_state, $options, $state); - } - } - } - - // Add validation callback to element if the dependency can be evaluated. - if (in_array($options['condition'], array('value', 'empty', '!empty'))) { - _conditional_fields_element_add_property($dependent_form_field, '#element_validate', 'conditional_fields_dependent_validate', 'append'); - } - - // Add the $state into the correct logic group in $states. - foreach ($state as $key => $constraints) { - foreach ($constraints as $selector => $constraint) { - // Add the constraint in an array to avoid overwriting other - // dependencies' states with the same selector. - $states[$key][$options['grouping']][$selector][] = $constraint; - } - } - - // Build effect settings for effects with options. - // TODO: add dependee key to allow different effects on the same selector. - if ($options['effect'] && $options['effect'] != 'show') { - $selector = conditional_fields_field_selector(drupal_array_get_nested_value($form, array($dependent_location[0]))); - // Convert numeric strings to numbers. - foreach ($options['effect_options'] as &$effect_option) { - if (is_numeric($effect_option)) { - $effect_option += 0; - } - } - $effects[$selector] = array( - 'effect' => $options['effect'], - 'options' => $options['effect_options'], - ); - } - - // Apply reset dependent to default if untriggered behavior. - if (in_array(CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED, $behaviors)) { - // Add property to element so conditional_fields_dependent_validate() can - // pick it up. - $dependent_form_field['#conditional_fields_reset_if_untriggered'] = TRUE; - unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED]); - } - } - - // Execute custom behaviors callbacks. - if (!empty($behaviors)) { - foreach ($behaviors as $behavior) { - $behavior($form, $form_state, $dependent, $dependent_info); - } - } - - unset($behaviors); - - if (empty($states)) { - continue; - } - - // Save the modified field back into the form. - drupal_array_set_nested_value($form, $dependent_location, $dependent_form_field); - - // Map the states based on the conjunctions. - $states_new = array(); - foreach ($states as $state_key => $value) { - // As the main object is ANDed together we can add the AND items directly. - if (!empty($states[$state_key]['AND'])) { - $states_new[$state_key] = $states[$state_key]['AND']; - } - // The OR and XOR groups are moved into a sub-array that has numeric keys - // so that we get a JSON array and not an object, as required by the States - // API for OR and XOR groupings. - if (!empty($states[$state_key]['OR'])) { - $or = array(); - foreach ($states[$state_key]['OR'] as $constraint_key => $constraint_value) { - $or[] = array($constraint_key => $constraint_value); - } - // '1' as a string so that we get an object (which means logic groups - // are ANDed together). - $states_new[$state_key]['1'] = $or; - } - if (!empty($states[$state_key]['XOR'])) { - $xor = array('xor'); - foreach ($states[$state_key]['XOR'] as $constraint_key => $constraint_value) { - $xor[] = array($constraint_key => $constraint_value); - } - // '2' as a string so that we get an object. - $states_new[$state_key]['2'] = $xor; - } - } - $states = $states_new; - - // Add the #states property to the dependent field. - drupal_array_set_nested_value($form, array_merge($dependent_location, array('#states')), $states); - - $has_states = TRUE; + foreach ($form['#conditional_fields'] as $parent_dependent_key => $parent_dependent_info) { + foreach ($parent_dependent_info as $dependent => $dependent_info) { + $states = array(); + + if (empty($dependent_info['dependees'])) { + continue; + } + + $dependent_location = array_merge($dependent_info['field_parents'], array($dependent)); + $dependent_form_field = drupal_array_get_nested_value($form, $dependent_location); + + // Cycle the dependant's dependees. + foreach ($dependent_info['dependees'] as $dependency) { + $dependee = $dependency['dependee']; + + if (empty($form['#conditional_fields'][$parent_dependent_key][$dependee])) { + continue; + } + + $dependee_info = $form['#conditional_fields'][$parent_dependent_key][$dependee]; + $dependee_form_field = drupal_array_get_nested_value($form, $dependee_info['parents']); + $options = $dependency['options']; + + // Load field edit behaviors. + // If this dependent has multiple dependees, only the logic of the first + // dependency will be taken into account. + if (!isset($behaviors)) { + $behaviors = conditional_fields_field_behaviors('edit', $options); + } + + // Determine if the dependee is in the form. + if (empty($dependee_form_field) || (isset($dependee_form_field['#access']) && $dependee_form_field['#access'] == FALSE)) { + // Apply orphan dependent behaviors. + /* + if (in_array(CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN, $behaviors)) { + // TODO + $is_triggered = TRUE; + + if ($is_orphan && !$is_triggered) { + $form[$dependent]['#access'] = FALSE; + } + } + */ + if (in_array(CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN, $behaviors)) { + $dependent_form_field['#access'] = FALSE; + } + unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN]); + unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN]); + unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED]); + continue; + } + unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN]); + unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN]); + + + + // Build a jQuery selector if it was not overridden by a custom value. + // Note that this may be overridden later by a state handler. + if (!$options['selector']) { + $options['selector'] = conditional_fields_field_selector($dependee_form_field); + } + else { + // Replace the language placeholder in the selector with current language. + $options['selector'] = str_replace('%lang', $dependee_form_field['#language'], $options['selector']); + } + if ($options['condition'] != 'value') { + // Conditions different than "value" are always evaluated against TRUE. + $state = array($options['state'] => array($options['selector'] => array($options['condition'] => TRUE))); + } + else { + + // Build the values that trigger the dependency. + $values = array(); + + if ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_WIDGET) { + $values[$options['condition']] = $options['value_form']; + } + elseif ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_REGEX) { + $values[$options['condition']] = $options['value']; + } + + elseif ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_AND) { + $values[$options['condition']] = count($options['values']) == 1 ? $options['values'][0] : $options['values']; + } + else { + if ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_XOR) { + // XOR behaves like OR with added 'xor' element. + $values[] = 'xor'; + } + elseif ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_NOT) { + // NOT behaves like OR with switched state. + $options['state'] = strpos($options['state'], '!') === 0 ? drupal_substr($options['state'], 1) : '!' . $options['state']; + } + + // OR, NOT and XOR conditions are obtained with a nested array. + foreach ($options['values'] as $value) { + $values[] = array($options['condition'] => $value); + } + } + + $state = array($options['state'] => array($options['selector'] => $values)); + $dependee_form_state = isset($dependee_form_field['#field_parents'], $dependee_form_field['#field_name'], $dependee_form_field['#language']) ? field_form_get_state($dependee_form_field['#field_parents'], $dependee_form_field['#field_name'], $dependee_form_field['#language'], $form_state) : NULL; + + // Execute special handler for fields that need further processing. + // The handler has no return value. Modify the $state parameter by + // reference if needed. + foreach ($state_handlers as $handler => $handler_conditions) { + if (array_intersect_assoc($handler_conditions, $dependee_form_field) == $handler_conditions) { + $handler($dependee_form_field, $dependee_form_state, $options, $state); + } + } + } + + + // Add the $state into the correct logic group in $states. + foreach ($state as $key => $constraints) { + if (empty($states[$key][$options['grouping']])) { + $states[$key][$options['grouping']] = $constraints; + } + else { + $states[$key][$options['grouping']] = array_merge($states[$key][$options['grouping']], $constraints); + } + } + + // Build effect settings for effects with options. + // TODO: add dependee key to allow different effects on the same selector. + if ($options['effect'] && $options['effect'] != 'show') { + $selector = conditional_fields_field_selector(drupal_array_get_nested_value($form, array($dependent_location[0]))); + // Convert numeric strings to numbers. + foreach ($options['effect_options'] as &$effect_option) { + if (is_numeric($effect_option)) { + $effect_option += 0; + } + } + $effects[$selector] = array( + 'effect' => $options['effect'], + 'options' => $options['effect_options'], + ); + } + + + + // Apply reset dependent to default if untriggered behavior. + if (in_array(CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED, $behaviors)) { + // Add property to element so conditional_fields_dependent_validate() can + // pick it up. + $dependent_form_field['#conditional_fields_reset_if_untriggered'] = TRUE; + unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED]); + } + } + + + + unset($behaviors); + + if (empty($states)) { + continue; + } + + // Save the modified field back into the form. + drupal_array_set_nested_value($form, $dependent_location, $dependent_form_field); + + // Map the states based on the conjunctions. + $states_new = array(); + foreach ($states as $state_key => $value) { + // As the main object is ANDed together we can add the AND items directly. + if (!empty($states[$state_key]['AND'])) { + $states_new[$state_key] = $states[$state_key]['AND']; + } + + // The OR and XOR groups are moved into a sub-array that has numeric keys + // so that we get a JSON array and not an object, as required by the States + // API for OR and XOR groupings. + if (!empty($states[$state_key]['OR'])) { + $or = array(); + foreach ($states[$state_key]['OR'] as $constraint_key => $constraint_value) { + $or[] = array($constraint_key => $constraint_value); + } + // '1' as a string so that we get an object (which means logic groups + // are ANDed together). + $states_new[$state_key]['1'] = $or; + } + if (!empty($states[$state_key]['XOR'])) { + $xor = array('xor'); + foreach ($states[$state_key]['XOR'] as $constraint_key => $constraint_value) { + $xor[] = array($constraint_key => $constraint_value); + } + // '2' as a string so that we get an object. + $states_new[$state_key]['2'] = $xor; + } + + } + $states = $states_new; + + // Add the #states property to the dependent field. + drupal_array_set_nested_value($form, array_merge($dependent_location, array('#states')), $states); + + $has_states = TRUE; + } } if (empty($has_states)) { return $form; } - $form['#attached']['library'][] = array('conditional_fields', 'conditional_fields'); + $form['#attached']['js'][] = drupal_get_path('module', 'conditional_fields') . '/js/conditional_fields.js'; // Add effect settings to the form. if ($effects) { @@ -683,6 +684,7 @@ function conditional_fields_dependent_validate($element, &$form_state, $form) { // have been validated to avoid collision between dependencies. $form_state_addition['parents'] = $dependent['#array_parents']; + // 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'])) { @@ -714,15 +716,15 @@ function conditional_fields_dependent_validate($element, &$form_state, $form) { } /** - * Extracts field values from a field element of a submitted form. + * Extracts submitted field values during form validation. * * @return * The requested field values parent. Actual field vales are stored under the * key $element['#field_name']. */ -function conditional_fields_field_get_values($element, $form_state) { +function conditional_fields_form_field_get_values($element, $form_state) { // Fall back to #parents to support custom dependencies. - $parents = !empty($element['#field_parents']) ? $element['#field_parents'] : $element['#parents']; + $parents = isset($element['#field_parents']) ? $element['#field_parents'] : $element['#parents']; return drupal_array_get_nested_value($form_state['values'], $parents); } @@ -745,14 +747,11 @@ function conditional_fields_form_validate($form, &$form_state) { foreach ($form_state['conditional_fields_untriggered_dependents'] as $field) { $dependent = drupal_array_get_nested_value($form, $field['parents']); - $field_values_location = conditional_fields_field_get_values($dependent, $form_state); + $field_values_location = conditional_fields_form_field_get_values($dependent, $form_state); // If we couldn't find a location for the field's submitted values, let the // validation errors pass through to avoid security holes. if (!isset($field_values_location[$dependent['#field_name']])) { - if (!empty($field['errors'])) { - $untriggered_dependents_errors = array_merge($untriggered_dependents_errors, $field['errors']); - } continue; } @@ -769,7 +768,7 @@ function conditional_fields_form_validate($form, &$form_state) { // $form_state['values'][ ... $element['#parents'] ... ], while the // documentation of hook_field_widget_form() states that field values are // $form_state['values'][ ... $element['#field_parents'] ... ]. - drupal_array_set_nested_value($form_state['values'], $dependent['#field_parents'], $field_values_location); + //drupal_array_set_nested_value($form_state['values'], $dependent['#field_parents'], $field_values_location); if (!empty($field['errors'])) { $untriggered_dependents_errors = array_merge($untriggered_dependents_errors, $field['errors']); @@ -961,7 +960,7 @@ function conditional_fields_entity_view_alter(&$build, $type) { default: // Custom behaviors are callbacks. - $behavior($dependee, $dependent, $is_triggered, $dependencies, $build, $type); + $$behavior('view', $dependee, $dependent, $is_triggered, $dependencies, $build, $type); break; } @@ -1000,17 +999,28 @@ function conditional_fields_evaluate_grouping($groups) { * The field form element in the current language. */ function conditional_fields_evaluate_dependencies($dependent, $form, $form_state) { - $dependencies = $form['#conditional_fields'][$dependent['#field_name']]['dependees']; + $dependent_field_key = conditional_fields_flatten_array($dependent['#field_parents']); + $dependencies = $form['#conditional_fields'][$dependent_field_key][$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'))) { - continue; + // Extract field values from submitted values. + $dependee = $dependency['dependee']; + $dependee_parents = $form['#conditional_fields'][$dependee]['parents']; + + // We have the parents of the field, but depending on the entity type and + // the widget type, they may include additional elements that are actually + // part of the value. So we find the depth of the field inside the form + // structure and use the parents only up to that depth. + $dependee_parents_keys = array_flip($dependee_parents); + $dependee_parent = drupal_array_get_nested_value($form, array_slice($dependee_parents, 0, $dependee_parents_keys[$dependee])); + $values = conditional_fields_form_field_get_values($dependee_parent[$dependee], $form_state); + + // Remove the language key. + if (isset($dependee_parent[$dependee]['#language'], $values[$dependee_parent[$dependee]['#language']])) { + $values = $values[$dependee_parent[$dependee]['#language']]; } - $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']); } @@ -1018,28 +1028,6 @@ function conditional_fields_evaluate_dependencies($dependent, $form, $form_state } /** - * Extracts field values from a submitted form. - */ -function conditional_fields_field_form_get_values($field_name, $form, $form_state) { - $field_parents = $form['#conditional_fields'][$field_name]['parents']; - - // We have the parents of the field, but depending on the entity type and - // the widget type, they may include additional elements that are actually - // part of the value. So we find the depth of the field inside the form - // structure and use the parents only up to that depth. - $field_parents_keys = array_flip($field_parents); - $field_parent = drupal_array_get_nested_value($form, array_slice($field_parents, 0, $field_parents_keys[$field_name])); - $values = conditional_fields_field_get_values($field_parent[$field_name], $form_state); - - // Remove the language key. - if (isset($field_parent[$field_name]['#language'], $values[$field_parent[$field_name]['#language']])) { - $values = $values[$field_parent[$field_name]['#language']]; - } - - return $values; -} - -/** * Evaluate if a dependency meets the requirements to be triggered. * * @param $context @@ -1047,15 +1035,6 @@ function conditional_fields_field_form_get_values($field_name, $form, $form_stat * $values are extracted from an entity. */ function conditional_fields_evaluate_dependency($context, $values, $options) { - if ($options['condition'] == 'empty') { - $options['values_set'] = CONDITIONAL_FIELDS_DEPENDENCY_VALUES_AND; - $options['values'] = array(''); - } - elseif ($options['condition'] == '!empty') { - $options['values_set'] = CONDITIONAL_FIELDS_DEPENDENCY_VALUES_NOT; - $options['values'] = array(''); - } - if ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_WIDGET) { $dependency_values = $context == 'view' ? $options['value'] : $options['value_form']; @@ -1201,15 +1180,8 @@ function conditional_fields_field_behaviors($op, $options) { } /** - * Builds a jQuery selector from the name or id attribute of a field. - * - * @todo support custom selectors with %lang and %key placeholders. - * - * @param $field - * The field form element. - * - * @return - * A jQuery selector string. + * Builds a jQuery selector from the name attribute of a field. + * TODO: support custom selectors with %lang and %key placeholders. */ function conditional_fields_field_selector($field) { if (isset($field['#attributes']['name'])) { @@ -1451,24 +1423,6 @@ function conditional_fields_element_info() { } /** - * Implements hook_library(). - */ -function conditional_fields_library() { - return array( - 'conditional_fields' => array( - 'tile' => 'Conditional Fields', - 'version' => '1.0.0', - 'js' => array( - drupal_get_path('module', 'conditional_fields') . '/js/conditional_fields.js' => array('group' => JS_DEFAULT), - ), - 'dependencies' => array( - array('system', 'drupal.states'), - ), - ), - ); -} - -/** * Builds a list of supported states that may be applied to a dependent field. */ function conditional_fields_states() { @@ -1642,7 +1596,7 @@ function conditional_fields_behaviors($op = NULL) { $behaviors = array( 'edit' => array( CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN => t('Hide the dependent if the dependee is not in the form'), - CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED => t('Reset the dependent to its default values when the form is submitted if the dependency is not triggered.') . '
' . t('Note: This setting only applies if the condition is "Value", "Empty", or "Filled" and may not work with some field types. Also, ensure that the default values are valid, since they will not be validated.') . '', + CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED => t('Reset the dependent to its default values when the form is submitted if the dependency is not triggered.') . '
' . t('Note: This setting only applies if the condition is "Value" and may not work with some field types. Also, ensure that the default values are valid, since they will not be validated.') . '', // TODO: Implement. Settings are imported from D6 though, they just do nothing for now. /* CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN => t('Hide the dependent if the dependee is not in the form and the dependency is not triggered.') . '
' . t('Note: This setting is not currently not implemented and has no effect.') . '', @@ -1658,7 +1612,7 @@ function conditional_fields_behaviors($op = NULL) { ); // Allow other modules to modify the options. - drupal_alter('conditional_fields_behaviors', $behaviors); + drupal_alter('conditional_fields_behaviors', $op, $behaviors); if (isset($behaviors[$op])) { return $behaviors[$op]; @@ -1676,10 +1630,11 @@ function conditional_fields_behaviors($op = NULL) { * $options and $state. * * @see conditional_fields_field_attach_form() + * @see conditional_fields_states_handler_select() */ function conditional_fields_states_handlers() { $handlers = array( - 'conditional_fields_states_handler_select_multiple' => array( + 'conditional_fields_states_handler_select' => array( '#type' => 'select', '#multiple' => TRUE, ), @@ -1720,7 +1675,7 @@ function conditional_fields_states_handlers() { * reference values of type Array are selected, a different selector must be * added for each value of a set for OR, XOR and NOT evaluations. */ -function conditional_fields_states_handler_select_multiple($field, $field_info, $options, &$state) { +function conditional_fields_states_handler_select($field, $field_info, $options, &$state) { switch ($options['values_set']) { case CONDITIONAL_FIELDS_DEPENDENCY_VALUES_WIDGET: case CONDITIONAL_FIELDS_DEPENDENCY_VALUES_AND: @@ -2027,3 +1982,20 @@ function conditional_fields_features_api() { ), ); } + + +/** + * Flatten a one-dimensional array. + */ +function conditional_fields_flatten_array($array, $delta = 0, $separator = ':') { + $array_string = 'root'.$separator; + $array_count = count($array); + foreach ($array as $array_value) { + $array_string .= $array_value; + if ($delta != $array_count) { + $array_string .= $separator; + } + $delta++; + } + return $array_string; +} \ No newline at end of file -- 2.7.1.windows.2