Problem/Motivation

After upgrading to Commerce version 7.x-1.14, my dblog is just FULL of this error message over and over again:

Warning: array_key_exists() expects parameter 2 to be array, null given in commerce_cart_add_to_cart_form() (line 2072 of ..... /commerce/modules/cart/commerce_cart.module).

And every time it is coupled with this one too:

Notice: Undefined index: attributes in commerce_cart_add_to_cart_form() (line 2072 of ..... /commerce/modules/cart/commerce_cart.module).

I'm running Drupal 7.56 with PHP 7.1.

However these errors, while annoying, appear to be inconsequential. My site is running fine to the end-user, orders are still being processed as normal, etc. I've tried clearing caches and running cron etc. No difference. Anyone else having this problem?

Proposed resolution

A patch or instructions on how to make it stop?

Remaining tasks

Needs expert review.

User interface changes

Pending.

API changes

Pending.

Data model changes

Pending.

Comments

TynanFox created an issue. See original summary.

rszrama’s picture

Version: 7.x-1.14 » 7.x-1.x-dev

Well, bummer. This appears to be a regression introduced by #2919323: Fix dependent attribute option filtering when resolved relative to optional attributes. I suppose in your case $form['attributes'] is empty? Any way you can confirm that for me? If so, I can pair it with something like a !empty($form['attributes']) check and / or is_array().

TynanFox’s picture

Well, that makes perfect sense. I was wondering why it was happening so sporadically. The vast majority of my products/add-to-cart forms do have attributes, but there are a few products I sell with no options.

And indeed, after testing, viewing product displays which have an empty add-to-cart form are the ones creating this error.

dm66’s picture

I confirm this problem.

I change string 2072 in commerce_cart.module to

if (isset($form['attributes'][$used_field_name]) && array_key_exists('#default_value', $form['attributes'][$used_field_name])) {

This fixed the problem.

TynanFox’s picture

Thank you dm66. #4 worked for me too.

I would make a patch to test etc...but I don't have the skills. :( #NotaDeveloper

vagelis-prokopiou’s picture

Status: Active » Needs review
StatusFileSize
new761 bytes

Here is a patch guys. Please, test.

To apply:
1. cd in the commerce module.
2. Run: curl "https://www.drupal.org/files/issues/array_key_exists_error-2924792-6.patch" | git apply -v;

Neo13’s picture

This patch fixes the issue with notices but there is another issue with ajax on attribute change. The response is 200 parserror with empty resulttext.

rszrama’s picture

babin’s picture

Thanks this patch worked for me too.

TynanFox’s picture

Status: Needs review » Reviewed & tested by the community

Don't see any reason to stop it from committing

hunlaprovo’s picture

It's been a couple of years. I got the error, updated it now and came out. Repair is good. Thank you so much dm66
if (isset($form['attributes'][$used_field_name]) && array_key_exists('#default_value', $form['attributes'][$used_field_name])) {

rszrama’s picture

Status: Reviewed & tested by the community » Needs review

Took me a while to confirm the issue here: it's when you have optional attribute fields on a product type and the product display does not reference any products that use the first one by sort order but do use a higher weighted field. For folks who reported / confirmed, make sure in the future to provide some context about your form to make that a little easier - I thought I was just crazy when I couldn't reproduce it for the last hour. : P

That said, I'm reviewing the patch now, because I'm not sure it shouldn't be || instead of &&.

rszrama’s picture

StatusFileSize
new1.38 KB

Alrighty, I've reviewed this and the logic resulting in the warnings / notices, and it does appear the && was correct but that we could also detect the issue a little earlier. Basically, the reason the isset() would fail is because the attribute field element is not added to the form array when we only add NULL values to its $used_options array:

            // ...
            if ($product_wrapper->{$field_name}->raw() != NULL) {
              $field_has_options[$field_name] = TRUE;
            }
            $used_options[$field_name][] = $product_wrapper->{$field_name}->raw();
          }

          // If for some reason no options for this field are used, remove it
          // from the qualifying fields array.
          if (empty($field_has_options[$field_name]) || empty($used_options[$field_name])) {
            unset($qualifying_fields[$field_name]);
          }
          else {
            // ...

This code is all designed to only permit products on the form that match the sequence of selected attributes. So what we can do in the offending loop is check to see if the $used_options array for the field we're matching products against has already been removed from the $qualifying_fields array beneath a similar exception check that's already there:

              // Don't apply this check for the current field being evaluated.
              if ($used_field_name == $field_name) {
                continue;
              }

              // Don't apply this check if the previously used field we'd
              // compare against was unset from the qualifying fields array,
              // meaning that we only added NULL values to its used options
              // array because it was an unused optional attribute field.
              if (!isset($qualifying_fields[$used_field_name])) {
                continue;
              }

That said, there's no reason not to include the isset() check as well, so I'm adding both. : )

Patch attached for review / testbot.

  • rszrama committed d7c4743 on 7.x-1.x
    Issue #2924792 by rszrama, vagelis-prokopiou: resolve an...
rszrama’s picture

Status: Needs review » Fixed

Committing.

gundartb’s picture

I can confirm that the patch in #13 fixes the problem.

I have thousands of products with many attributes and some need to be set to NONE which was not only throwing hundreds of errors but slowing down the product selection process as well... everytime a customer changed a color or option etc.. it would take 10+ seconds to load and we were getting complaints of slow performance...

This patch not only gets rid of the errors, it speeds things up tremendously! THANKS

Status: Fixed » Closed (fixed)

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

ConradFlashback’s picture

#13 works
Please commit.

mglaman’s picture

See #14.

tonytheferg’s picture

Hi, I am noticing that each change I make in the selection box takes a little bit longer than the previous one, and eventually i get a 403 error. is that something that is rectified by this patch?