Magento2: M2.1.1 : Cannot get quote details

Created on 15 Sep 2016  路  9Comments  路  Source: magento/magento2

When I try to get quote details, my quote does not seem to get loaded from my session.

Preconditions

  1. Magento 2.1.1
  2. Sessions stored in database

    Steps to reproduce

  3. I add a product to the cart (as a guest)

  4. Everything works, cart, checkout, etc.
  5. However, my custom code says my cart is NULL. This code worked before.

Code sample (in a custom block):

public function __construct(
    \Magento\Checkout\Model\Session $checkoutSession,
)
{
    $this->checkoutSession = $checkoutSession;
}

/**
 * @return Quote
 */
public function getQuote()
{
    return $this->checkoutSession->getQuote();
}

Now if I cal $this->getQuote()->getId() it returns NULL, even though the quote is saved and all in the database.

Expected result

  1. I should get the quote that belongs to the session

    Actual result

  2. I get an empty quote.

Format is valid

Most helpful comment

Got it!

Once again it wasn't a bug, but a feature. Turns out that if your blocks are cacheable and cache is enabled, there is a little something called \Magento\Checkout\Model\Layout\DepersonalizePlugin. What this plugin does, is it checks if your page requires 'de-personalization'. If so, it clears the checkoutSessions' storage. And ... one of the 'requirements' that well 'de-personalize' your block is if it's cacheable (you can see all requirements in \Magento\PageCache\Model\DepersonalizeChecker::checkIfDepersonalize().

So, to make a long story short and to close my couple of hours of debugging: if you need stuff from your checkout session, make sure your block isn't cached. A simple cacheable="false" in your layout should do the trick:

<block class="Vendor\Module\Block\Something" cacheable="false"
       name="something" template="Vendor_Module::something.phtml">

I hope this saves somebody a couple of hours of frustration and debugging.

All 9 comments

The weird part is also, that when I put the following code in the constructor of my custom block:

var_dump($this->checkoutSession->getSessionId());
var_dump($this->checkoutSession->getData());die;

I get the following result:

string(26) "ma0c3isj7v0nocd9r6lsdjk9f7"
array(0) {
}

But ... when I past the same code in the constructor of Magento\Catalog\Block\Cart, I get the correct result:

string(26) "ma0c3isj7v0nocd9r6lsdjk9f7"
array(3) {
  ["last_added_product_id"]=>
  string(1) "2"
  ["quote_id_1"]=>
  string(1) "3"
  ["cart_was_updated"]=>
  bool(false)
}

Does anyone have a clue why this could be? I just invoke the checkout session using dependency injection in my constructor. How come that one class has the correct items filled and the other hasn't?

It is the same session!

More debugging: the method isSessionExists() returns false on my custom block, but true on the Magento Block. Diving deeper, it turns out that the session_status()-method returns '1' in my Block (PHP_SESSION_NONE), and '2' in Magento's Blocks (PHP_SESSION_ACTIVE).

Why don't I have a session in my custom block? When I manually invoke \Magento\Framework\Session\SessionManager::start(), the session_status() keeps returning '1'. :-/

Another interesting fact: in my constructor isSessionExists() returns true. But in my getQuote()-method it returns false. Could it be that some other code is destructing my session?

Got it!

Once again it wasn't a bug, but a feature. Turns out that if your blocks are cacheable and cache is enabled, there is a little something called \Magento\Checkout\Model\Layout\DepersonalizePlugin. What this plugin does, is it checks if your page requires 'de-personalization'. If so, it clears the checkoutSessions' storage. And ... one of the 'requirements' that well 'de-personalize' your block is if it's cacheable (you can see all requirements in \Magento\PageCache\Model\DepersonalizeChecker::checkIfDepersonalize().

So, to make a long story short and to close my couple of hours of debugging: if you need stuff from your checkout session, make sure your block isn't cached. A simple cacheable="false" in your layout should do the trick:

<block class="Vendor\Module\Block\Something" cacheable="false"
       name="something" template="Vendor_Module::something.phtml">

I hope this saves somebody a couple of hours of frustration and debugging.

Really helpful, thank you. This fixed it for me on all pages but not on the Product Description Page.

I am using magento 2.1.8. I my custom theme app\design\frontend\Sample\theme-frontend-shop\Magento_Catalog\templates\productviewform.phtml I have done

`
$quoteId = $objectManager->get('Magento\Checkout\Model\Session')->getQuoteId();
$currentItemCount=0;
if(!empty($quoteId)){
$cartItems = $objectManager->get('\Magento\Checkout\Model\Session')->getQuote()->getAllVisibleItems();
$itemsIds = array();
foreach ($cartItems as $cartItem) {
$itemsIds[] = $cartItem->getProduct()->getId();
}

$currentItemCount = count($itemsIds);

}

echo $currentItemCount;
`

and in my app\design\frontend\Sample\theme-frontend-shop\Magento_Catalog\layout\catalog_product_view.xml I have added
<referenceBlock name="product.info.addtocart" class="Magento\Checkout\Block\Cart" before="-" template="Blumeidealnew_shop::product/view/form.phtml" cacheable="false" />

But this is not working properly when full page cache is enabled.

Need help to fix this issue.

Got it!

Once again it wasn't a bug, but a feature. Turns out that if your blocks are cacheable and cache is enabled, there is a little something called \Magento\Checkout\Model\Layout\DepersonalizePlugin. What this plugin does, is it checks if your page requires 'de-personalization'. If so, it clears the checkoutSessions' storage. And ... one of the 'requirements' that well 'de-personalize' your block is if it's cacheable (you can see all requirements in \Magento\PageCache\Model\DepersonalizeChecker::checkIfDepersonalize().

So, to make a long story short and to close my couple of hours of debugging: if you need stuff from your checkout session, make sure your block isn't cached. A simple cacheable="false" in your layout should do the trick:

<block class="Vendor\Module\Block\Something" cacheable="false"
       name="something" template="Vendor_Module::something.phtml">

I hope this saves somebody a couple of hours of frustration and debugging.

thanks a lot :)

@kanduvisla Should be added to documentation!

Have a problem with the mincart in 2.3 when FPC i enable and it drop the items if I visit a page that has not been cached.

Is it possible for me to exclude the minicart from the cache nad how do I do it?
Hope someone know how so my project can be finished.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

denis-g picture denis-g  路  3Comments

phirunson picture phirunson  路  3Comments

punkstar picture punkstar  路  3Comments

andreaskoch picture andreaskoch  路  3Comments

xi-ao picture xi-ao  路  3Comments