Jump to content

1.7.2.4 Order Summary shows same image for all items


ric355

Recommended Posts

I was testing a new store just prior to launch, using Prestashop 1.7.2.4, and came across a problem whereby if I added several items to my basket and checked out, the final order summary on the browser shows the same image for every item purchased. It always shows the image of the last item listed.

Having spent some time debugging it, I ended up in src/Adapter/Order/OrderPresenter.php in the function getProducts.

I'm a complete novice with Prestashop but not a novice developer, so I have a poor understanding of what this code is actually doing, other than it seems to be copying data from the cart to a structure to represent the order, but was able to come up with a change to work around the problem. There's a loop going through each product in the order, with a nested loop within it going through the cart:

 

    private function getProducts(Order $order)
      {
          $cart = new Cart($order->id_cart);
  
B>        $orderProducts = $order->getCartProducts();                                                                                                                         
          $cartProducts = $this->cartPresenter->present($cart);
          $orderPaid = $order->getCurrentOrderState() && $order->getCurrentOrderState()->paid;
  
          foreach ($orderProducts as &$orderProduct) {
              $orderProduct['name'] = $orderProduct['product_name'];
              $orderProduct['price'] = $this->priceFormatter->format($orderProduct['product_price'], Currency::getCurrencyInstance((int)$order->id_currency));
              $orderProduct['quantity'] = $orderProduct['product_quantity'];
              $orderProduct['total'] = $this->priceFormatter->format($orderProduct['total_price'], Currency::getCurrencyInstance((int)$order->id_currency));
  
              if ($orderPaid && $orderProduct['is_virtual']) {
                  $id_product_download = ProductDownload::getIdFromIdProduct($orderProduct['product_id']);
                  $product_download = new ProductDownload($id_product_download);
                  if ($product_download->display_filename != '') {
                      $orderProduct['download_link'] = $product_download->getTextLink(false, $orderProduct['download_hash'])
                          . '&id_order=' . (int)$order->id
                          . '&secure_key=' . $order->secure_key;
                  }
              }
  
              foreach ($cartProducts['products'] as $cartProduct) {
                  if ($cartProduct['id_product_attribute'] === $orderProduct['id_product_attribute']) {
                      if (isset($cartProduct['attributes'])) {
                          $orderProduct['attributes'] = $cartProduct['attributes'];
                      } else {
                          $orderProduct['attributes'] = array();
                      }
                      $orderProduct['cover'] = $cartProduct['cover'];
                      $orderProduct['unit_price_full'] = $cartProduct['unit_price_full'];
                  }
              }
  
              OrderReturn::addReturnedQuantity($orderProducts, $order->id);
          }
  
          $orderProducts = $this->cartPresenter->addCustomizedData($orderProducts, $cart);
  
          return $orderProducts;
      }

 

I've picked out the nested loop, as I think this is where the problem is:

          foreach ($cartProducts['products'] as $cartProduct) {
                  if ($cartProduct['id_product_attribute'] === $orderProduct['id_product_attribute']) {
                      if (isset($cartProduct['attributes'])) {
                          $orderProduct['attributes'] = $cartProduct['attributes'];
                      } else {
                          $orderProduct['attributes'] = array();
                      }
                      $orderProduct['cover'] = $cartProduct['cover'];
                      $orderProduct['unit_price_full'] = $cartProduct['unit_price_full'];
                  }
              }

Here it's going through every item in the cart, and checking id_product_attribute to find the matching item in the order. I don't know what specifically that value represents but in my case they all seemed to be zero (those I checked at least).   Every time it finds a match it reassigns the  cover image and the unit_price_full value with the item from the cart.

Since the individual items in the basket all have id_product_attribute of zero, they all match each other. This causes the cover image to be constantly overwritten, so the resulting image you get is of the last item that was processed, which is always the last one on the order.

To fix this on my own website I've added an additional check to make sure the product id is the same;

                   if ($cartProduct['id_product'] === $orderProduct['id_product'])
                          $orderProduct['cover'] = $cartProduct['cover'];
   

 

I'm pretty sure this fixes it but I suspect it is not the most ideal way to deal with it. Rather the cover images should probably be assigned in a different loop. One of the reasons I've raised this is because I was a bit concerned about the "unit_price_full" attribute also being continuously overwritten as it may well be a bug also. I did try a test but the prices seem to be preserved correctly unlike the images. I can only assume that the template uses a value from a different structure when it displays the summary.

I'm assuming there are loads of people who know how this stuff works in much more detail and can comment whether there is a better way of fixing it or whether I'm way off the mark.

Link to comment
Share on other sites

  • 1 month later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...