When using the cart and updating multiple products at a time using 'update cart' the cart breaks.

The error it gives is the following

Recoverable fatal error: Argument 1 passed to Drupal\commerce_cart\CartManager::updateOrderItem() must implement interface Drupal\commerce_order\Entity\OrderInterface null given, called in modules/contrib/commerce/modules/cart/src/Plugin/views/field/EditQuantity.php on line 134 and defined in Drupal\commerce_cart\CartManager->updateOrderItem() (line 137 of modules/contrib/commerce/modules/cart/src/CartManager.php)

Just to be as thorough as possible;
- Updating one product at a time with different quantities works just fine.
- But updating 2 products at once (even when increasing or decreasing both with just 1) breaks the cart.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Maikel created an issue. See original summary.

vasike’s picture

Status: Active » Postponed (maintainer needs more info)

@Maikel: what version of the module do you use.
The lines indicated by the error message do not seem to be accurate for the latest version (dev).

could you, please, update your commerce package and try again.
Thanks

jsacksick’s picture

Status: Postponed (maintainer needs more info) » Active

I reproduce that issue all the time, all I have to do is update several quantities and click on "Update cart".
For some reasons, from the second item order item in the loop, the order_id field is empty.
So $order_item->getOrder() will return NULL.

Right now, the order is saved by the cart manager for each order item, we call:

$this->cartManager->updateOrderItem($order, $order_item);

We should fix this and save the order only once, but we need to figure out what's causing the order reference from the order item to be lost.

When passing FALSE as the third parameter, the order won't be saved by the cart manager, then we'll have to save it ourselves.

$this->cartManager->updateOrderItem($order, $order_item, FALSE);
SchwebDesign’s picture

We are seeing this issue as well.

Steps to recreate:
- add 2 different products to the cart
- in cart, change quantity of each and click 'update cart'

The error we get is:

The website encountered an unexpected error. Please try again later.
Recoverable fatal error: Argument 1 passed to Drupal\commerce_cart\CartManager::updateOrderItem() must implement interface Drupal\commerce_order\Entity\OrderInterface, null given, called in /home/sitename/public_html/stage/modules/contrib/commerce/modules/cart/src/Plugin/views/field/EditQuantity.php on line 158 and defined in Drupal\commerce_cart\CartManager->updateOrderItem() (line 137 of modules/contrib/commerce/modules/cart/src/CartManager.php).

If i can provide any information to help find a fix let me know.

kala4ek’s picture

Priority: Normal » Major

Subscribe, the same problem.

drugan’s picture

FileSize
968 bytes

Please, check if this patch helps you.

jsacksick’s picture

Status: Active » Needs work

The bug is still occurring with the patch from #6.
$row_index was already correct, so no need to increment it in the loop, I just think we should save the order after the loop, that seems to fix the issue.
I did some tests locally and it seems to fix the issue.

drugan’s picture

FileSize
829 bytes

@jsacksick

I can't reproduce your issue. So, there is a patch which prevents error but not actually fixes it. I think that the reason is related with cache. Have you some weird cache settings?

It would be helpful if you fresh install drupalcommerce site, create products and add them to cart to reproduce the error. Then just dump the site's database to dump.sql.gz file and upload it on this page.

drugan’s picture

Status: Needs work » Postponed (maintainer needs more info)
jsacksick’s picture

Status: Postponed (maintainer needs more info) » Needs review
FileSize
2.7 KB

Why do you set the status to "postponed"? Several people reported the issue, it's reproducible all the time on a fresh install, all you have to do is add more than one item to the cart, go to the cart page, update several quantities then click on "Update cart".

The attached patches fixes it (we save the order only once on submit, and also output the same message that was displayed in 1.x.

I tried to understand why after the first order item was saved (and the order), the order_id was nullified for other order items which was causing the issue described here.

mglaman’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

This needs a test. For all I know we do not have any test coverage of the quantity edit field and saving the cart form. We need a Functional test to cover this and also to try and reproduce the reported bug.

jsacksick’s picture

Status: Needs work » Needs review
FileSize
6.4 KB

There's already a test (CartTest), but it isn't testing updating multiple quantities in cart, I updated the test and also made sure the order was saved if quantities were updated (See attached patch).
I'm going to run the test without my patch to see if it's failing.

jsacksick’s picture

I just ran the updated CartTest with the current codebase (after removing asserting that the shopping cart update message is present), and surprisingly it's not failing... :p

drugan’s picture

FileSize
1.16 KB

I applied modules/cart/tests/src/Functional/CartTest.php (this file only) changes suggested on the #12 and the test is green for me.

Obviously that the reason is in different indices on $quantities and $this->view->result arrays. This happens because when the form is constructed in the EditQuantity->viewsForm() then we loop through $this->view->result array but when the form is submitted we loop through the $quantities array in the EditQuantity->viewsFormSubmit().

For the first look it seems the same but the current issue proves that it's not. A possible reason might be here:

http://cgit.drupalcode.org/drupal/tree/core/modules/views/src/Plugin/vie...

When the $this->view->result is populated it looks like this (on my installation):

$this->view->result = [
/** @var \Drupal\views\ResultRow */,
/** @var \Drupal\views\ResultRow */,
/** @var \Drupal\views\ResultRow */,
// ...
];

So. it is a non-associative array with auto indices (0, 1, 2, ...). But, let's imply that for some unknown reasons (like in @jsacksick case) the $result passed to iterator_to_array() has at least one associated key assigned before:

$result = [
  /** @var \Drupal\views\ResultRow */,
 '999' => /** @var \Drupal\views\ResultRow */,
  /** @var \Drupal\views\ResultRow */,
  // ...
];

As the iterator_to_array() is called with default $use_keys = true argument so the '999' will be assigned as the key for a Quantity field in the EditQuantity->viewsForm().

So, my suggestion is to loop through $this->view->result in the EditQuantity->viewsFormSubmit() too.

  • bojanz committed 91b0768 on 8.x-2.x authored by jsacksick
    Issue #2891190 by drugan, jsacksick, vasike, mglaman: Updating multiple...

bojanz credited bojanz.

bojanz’s picture

Status: Needs review » Fixed
Issue tags: -Needs tests

Let's go with this for now. Thank you, Jonathan.

Status: Fixed » Closed (fixed)

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

hisik’s picture

I am also seeing this issue when multiple products in the Drupal 7 Commerce cart, it is crashing during check out. Has anyone found a solution to this?