When customer uses the option to copy profile fields from shipping to billing receives the following error
Cannot use a scalar value
Warning: Cannot use a scalar value as an array in commerce_customer_profile_copy_fields() (line 1394 of /sites/all/modules/commerce/modules/customer/commerce_customer.module).

PS. Hopefully the fields are successfully transferred to review page.

Comments

rszrama’s picture

Category: bug » support
Status: Active » Postponed (maintainer needs more info)

I'm gonna need more information, like what fields are you trying to copy from one to the other. The default behavior itself produces no warnings for me.

adpo’s picture

I was able to reproduce this error on new commerce kickstart installation, by adding field_position List (text) field on shipping profile, and then using the same field on billing.

warbo’s picture

The line mentioned in the error is this:

$form_state['order']->data['profile_copy'][$pane_id]['elements'][$field_name][$langcode][$delta] = TRUE;

I've put some printf debugging around it and found:

$langcode => "und"
$pane_id => "customer_profile_billing__c" // A custom commerce customer profile type
$delta => 0
$field_name => "field_license_holder" // A custom boolean field with a 'single on/off checkbox' widget
$field => array(1) {
    ["und"]=>
    array(1) {
      [0]=>
      array(1) {
        ["value"]=>
        int(1)
      }
    }
  }
$form_state['order']->data['profile_copy'][$pane_id]['elements'][$field_name][$langcode] => bool(true)

Since $form_state['order']->data['profile_copy'][$pane_id]['elements'][$field_name][$langcode] is a boolean, we can't put "[$delta]" after it, hence the error.

I've been scouring over our code but can't see anything wrong with the input. I've worked around it so far using an if(is_array()) check. Would be good to know where the real problem lies though.

warbo’s picture

Not sure if it's related, but some of my SimpleTests which try to checkout are failing in commerce_customer_profile_copy_fields. Drush outputs loads of this:

Test commerce_customer_profile_copy_fields() failed: Undefined index: [error]
profile_copy
Test commerce_customer_profile_copy_fields() failed: Undefined index: [error]
field_email
Test commerce_customer_profile_copy_fields() failed: Undefined index: [error]
field_phone
Test commerce_customer_profile_copy_fields() failed: Undefined index: [error]
customer_profile_billing__c
Test commerce_customer_profile_copy_fields() failed: Undefined index: [error]
field_email
Test commerce_customer_profile_copy_fields() failed: Undefined index: [error]
field_phone
Test commerce_customer_profile_copy_fields() failed: Undefined index: [error]
profile_copy
Test commerce_customer_profile_copy_fields() failed: Undefined index: [error]
field_email
Test commerce_customer_profile_copy_fields() failed: Undefined index: [error]
field_phone

rszrama’s picture

Not sure. I have issues testing locally as well, but the test bot on d.o never complains.

rszrama’s picture

Based on #2016045: No array available within address field in the auto copy function, it looks like we should be able to reproduce the warning with the Countries module as well.

mvdve’s picture

Version: 7.x-1.5 » 7.x-1.7

This is indeed the same issue. Sorry for the duplicate (different line number).

The PHP error is caused by a field in the $form_state array where $langcode is not an array, for example the countries field:

Countries field

'field_country' => array(
    'und' => TRUE,
  ),

Normal text field

'field_city' => array(
    'und' => array(
      TRUE,
    ),
  ),

The following line can not be executed, because $delta does not exists:

$form_state['order']->data['profile_copy'][$pane_id]['elements'][$field_name][$langcode][$delta] = TRUE;

I added an extra array check on the $langcode variable, but is looks like this should be fixed within the Countries module.

checker’s picture

Version: 7.x-1.7 » 7.x-1.8

Changing version

checker’s picture

Just want to add, this also happens if you are using list (integer) not only list (text) fields.

checker’s picture

Version: 7.x-1.8 » 7.x-1.x-dev
Status: Postponed (maintainer needs more info) » Needs review
StatusFileSize
new1.04 KB

This patch does not correct the root of the problem but it controls this situation from drupal core with list fields. Just adding an if clause for the missing $delta dimension.

if(is_array($form_state['order']->data['profile_copy'][$pane_id]['elements'][$field_name][$langcode])) {
  $form_state['order']->data['profile_copy'][$pane_id]['elements'][$field_name][$langcode][$delta] = TRUE;
}
else {
  $form_state['order']->data['profile_copy'][$pane_id]['elements'][$field_name][$langcode] = TRUE;
}
rszrama’s picture

Category: Support request » Bug report
Issue summary: View changes
StatusFileSize
new719 bytes

Alrighty, what was happening in here is that our validate handler was being invoked before another that does data transformation to the field arrays, such as the List (text) field, resulting in the second pass hitting a conflict with data stored in the form state from the first pass.

My proposed solution is attached: clear the copied elements array at the start of the function for the current $pane_id. There's no reason I can see to persist this from invocation to invocation, and resetting this at the start avoids any notices with scalars (the boolean TRUE being set for the field sans delta values) being used as arrays.

checker’s picture

Patch #11 looks good. I get no warnings and I can complete the order.

rszrama’s picture

Status: Needs review » Fixed

Thanks for the test. Committed.

Status: Fixed » Closed (fixed)

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

The last submitted patch, 10: commerce_customer_copy_notice.patch, failed testing.

Status: Closed (fixed) » Needs work

The last submitted patch, 11: 1954204.customer_profile_copy_data.patch, failed testing.

rszrama’s picture

Status: Needs work » Closed (fixed)