To reproduce: Make a conditional based on the value of a select component with Other allowed (via select_or_other). On form submit, you will see:

Warning: strcasecmp() expects parameter 1 to be string, array given in webform_conditional_operator_string_equal() (line 951 of .../webform/includes/webform.conditionals.inc

Comments

liam morland’s picture

Status: Active » Needs review
StatusFileSize
new806 bytes

This happens because select components using select_or_other package their values into a array with keys "select" and "other". This patch flattens this.

liam morland’s picture

liam morland’s picture

webform_conditional_operator_string_not_equal() does not need a corresponding patch once #2307631: *_not_* functions should be wrappers is committed.

danchadwick’s picture

Status: Needs review » Needs work

I'm not sure what the possible array structures are for the input values (haven't researched it), but the test in this patch looks brittle. As yourself, could any valid set of select keys match what you are testing to see if there are "other" values?

liam morland’s picture

As I understand it, $input_values is a 1-dimensional array, unless it is a select_or_other component. In this case, $input_values['select']['select_or_other'] will exist. I don't think there is any other way for $input_values['select']['select_or_other'] to exist.

danchadwick’s picture

@Liam - In that case,

if (isset($input_values['select']) && is_array($input_values['select'])) // ... 

would be a better test, no?

liam morland’s picture

I think that test would work, but I don't see why it would be better. My test looks specifically for select_or_other. It could happen that something else could cause there to be an array at $input_values['select'], but it is very unlikely that anything else would use select_or_other as a key.

danchadwick’s picture

My logic is that some module -- perhaps other than select_or_other -- might add nesting. Since what you want is the items under 'select', test for what you want to use and use it if it exists, rather than test for something else and infer that what you want should exist.

liam morland’s picture

Do I understand correctly: You want it to use $input_values['select'] as the $input_values any time that it is an array.

I don't oppose this if you think it is better.

My thinking was that we should only intervene in the known case, that is, select_or_other, because a different situation might need a different fix.

liam morland’s picture

StatusFileSize
new794 bytes

Patch done your way attached.

liam morland’s picture

Status: Needs work » Needs review
danchadwick’s picture

Yuck. My apologies for leading you astray.

There are 4 permutations of "multiple" and "select_or_other" (SOO), and they all look different. Using colors as an example, $input_values is:

Case 00: Neither Multiple Nor SOO:
An array with 0 => 'blue' (because a scalar string was converted to an array). Note that this is indexed by 0, rather than by the value, as is the case with multiple.

Case 01: Multiple only:
An array, with an entry for every option, with 'blue' => 'blue' (or 0, if not selected)

Case 10: SOO only:
An array, with two entries,
'other' => 'pink' and 'select' => 'select_or_other'
OR
'other' => 'pink' (or whatever value was last used, if any) and 'select' => 'blue'

Case 11: Both Multiple and SOO:
An array with two entries,
'other' => 'pink' (or whatever value was last used)
'select' => an array with an entry for every option as above, plus 'select_or_other'

An issue that I see is that case 01 looks exactly like case 10, if your webform component used a 'select' and 'other' as keys.

I think that testing for this in the equal operator function is the wrong place. I suggest "fixing" the values in _webform_client_form_rule_check(). Something like (untested):

        $source_values = array();
        if (isset($input_values[$source_cid])) {
          $component_value = $input_values[$source_cid];
          if ($source_component['type'] == 'select' && !empty($source_component['extra']['other_option'])) {
            $component_value = $component_value['select'];
          }
          $source_values = is_array($component_value) ? $component_value : array($component_value);
        }
danchadwick’s picture

Status: Needs review » Needs work
liam morland’s picture

Status: Needs work » Needs review
StatusFileSize
new800 bytes
new786 bytes

Your approach in #12 is working for me. Here it is in two separate patch files. The first does the $component_value refactor (no functional change) and the second that adds the fix for select_or_other.

Status: Needs review » Needs work

The last submitted patch, 14: webform-strcasecmp_warning-2307619-14b.patch, failed testing.

danchadwick’s picture

Status: Needs work » Fixed

I combined your patches into one commit, which went into 7.x-4.x and 8.x. Thank you very much.

  • DanChadwick committed b8e5c6e on 7.x-4.x
    Issue #2307619 by DanChadwick: Fixed regression of conditional/...
  • DanChadwick committed 5b6b3fb on 8.x-4.x
    Issue #2307619 by DanChadwick: Fixed regression of conditional/...
danchadwick’s picture

Fixed a regression during preview.

liam morland’s picture

Thanks very much.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.