Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Magento2: model cart do not load quote items on home page #7341

Closed
AlessandroStaffolani opened this issue Nov 7, 2016 · 2 comments
Closed

Comments

@AlessandroStaffolani
Copy link

AlessandroStaffolani commented Nov 7, 2016

I create my custom theme with some custom module, on home page I tried to get all cart items (from quote) to create my custom mini cart, this is my block:

<?php

namespace <Vendor>\<Module>\Block;

class Cart extends \Magento\Checkout\Block\Cart
{

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Customer\Model\Session $customerSession,
        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Catalog\Model\ResourceModel\Url $catalogUrlBuilder,
        \Magento\Checkout\Helper\Cart $cartHelper,
        \Magento\Framework\App\Http\Context $httpContext,
        array $data = []
    )
    {
        parent::__construct(
            $context,
            $customerSession,
            $checkoutSession,
            $catalogUrlBuilder,
            $cartHelper,
            $httpContext,
            $data
        );
    }
	
	public function getCartItems()
    {
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); // Instance of Object Manager
        $cartModel = $objectManager->create('Magento\Checkout\Model\Cart');
        $productsObject = $cartModel->getQuote()->getAllVisibleItems();
        
        $cartItems = array();
        foreach ($productsObject as $item) {
            $cartItems[] = $item;
        }
        
        return $cartItems;
    }
}

I add this block on my default.xml but when I'm on home page, category pages or on product page the object quote is always empty. While on checkout pages, on customer pages I can see the cart items if they have added.

The strangest think is that, if I disable the cache, the quote object works fine everywhere, while with cache enabled I get the quote empty.

Here there is my <Vendor>\<Theme>\Magento_Theme\layout\default.xml:

<?xml version="1.0"?><page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <update handle="default_head_blocks"/>
<body>

    <referenceBlock name="report.bugs" remove="true"/>
    <referenceContainer name="header.panel" remove="true"/>
    <referenceContainer name="header-wrapper" remove="true"/>
    <referenceContainer name="page.messages" remove="true"/>
    <referenceBlock name="head.additional">
        <block class="Magento\Framework\View\Element\Template" name="zopim-chat" template="Magento_Theme::head/zopim.phtml"/>
    </referenceBlock>
    <referenceContainer  name="header.container">
        <container name="top-header" label="Page Header" as="top-header" htmlTag="div" htmlClass="row no-margin">
            <block class="Magento\Framework\View\Element\Template" template="Magento_Theme::header/prodotti-header.phtml" name="prodotti-header" before="-"/>
            <block class="Magento\Theme\Block\Html\Header\Logo" template="Magento_Theme::header/logo.phtml" name="logo">
                <arguments>
                    <argument name="logo_file" xsi:type="string">images/logo.png</argument>
                    <argument name="logo_img_width" xsi:type="number">314</argument>
                    <argument name="logo_img_height" xsi:type="number">94</argument>
                </arguments>
            </block>
            <block class="Magento\Framework\View\Element\Template" template="Magento_Theme::header/header-links.phtml" name="header-links">
                <arguments>
                    <argument name="css_class" xsi:type="string">header links</argument>
                </arguments>
            </block>
        </container>
        <container name="panel-header-row" label="Panel header" as="panel-header-row" htmlTag="div" htmlClass="row no-margin">
            <block class="<Vendor>\CategoryList\Block\CategoryList" name="tree-category" template="<Vendor>_CategoryList::treeCategory.phtml">
                <block class="<Vendor>\CategoryList\Block\Category\Search" name="category-search" template="<Vendor>_CategoryList::category/search.phtml"/>
            </block> <block class="Magento\Framework\View\Element\Template" template="Magento_Theme::header/panel-header-hide.phtml" name="panel-header-hide"/>

            <container name="panel-header-right" label="Panel header right" as="panel-header-right" htmlTag="div" htmlClass="col s4 m4 l4 light2-grey panel-header right-panel">
			
				<!-- HERE I PUT THE CART BLOCK BY REFERING THIS CONTAINER -->
			
			</container>
        </container>
        <block class="Magento\Theme\Block\Html\Topmenu" name="catalog.topnav" template="Magento_Theme::navbar.phtml" ttl="3600" after="-"/>
    </referenceContainer>
    <referenceBlock name="copyright" remove="true"/>
    <referenceContainer name="footer-container" remove="true"/>
    <container name="page-footer" label="Page Footer" as="page-footer" htmlTag="footer" htmlClass="page-footer no-margin no-padding white black-text">
        <block class="<Vendor>\User\Block\FetchWishlistLogin" template="<Vendor>_User::fetchAddToWishlist.phtml" name="fetch-wishlist-login" before="-"/>
        <container name="newsletternewsletter" label="News Letter" as="newsletter" htmlTag="div" htmlClass="row no-margin dark-grey">
            <block class="Magento\Framework\View\Element\Template" template="Magento_Theme::footer/newsletter-footer.phtml" name="newsletter-footer" before="-"/>
            <block class="Magento\Newsletter\Block\Subscribe" template="Magento_Theme::footer/newsletter-email.phtml" name="newsletter-email" after="-"/>
        </container>
        <container name="pre-footer" label="Pre footer" as="pre-footer" htmlTag="div" htmlClass="row no-margin light2-grey">
            <block class="Magento\Framework\View\Element\Template" template="Magento_Theme::footer/pre-footer.phtml" name="rassicurazioni"/>
        </container>
        <container name="footer-info" label="Footer" as="footer" htmlTag="div" htmlClass="row no-margin footer-info">
            <block class="Magento\Framework\View\Element\Template" name="footer-col-1" template="Magento_Theme::footer/footer-col-1.phtml" before="-"/>
            <block class="Magento\Theme\Block\Html\Topmenu" name="footer-col-2" template="Magento_Theme::footer/footer-col-2.phtml" after="footer-col-1"/>
            <block class="Magento\Framework\View\Element\Template" name="footer-col-3" template="Magento_Theme::footer/footer-col-3.phtml" after="footer-col-2"/>
            <block class="Magento\Framework\View\Element\Template" name="footer-col-4" template="Magento_Theme::footer/footer-col-4.phtml" after="-"/>
        </container>
    </container>
</body></page>

Then in <Vendor>\<Module>\view\frontend\layout\default.xml:

<?xml version="1.0"?><page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
    <referenceContainer name="panel-header-right">
        <block class="<Vendor>\Cart\Block\Cart" before="-" template="<Vendor>_Cart::cart-panel.phtml" name="cart-panel"/>
    </referenceContainer>
</body></page>

Preconditions

  1. Magento 2.1.2
  2. Centos 7.2
  3. PHP 5.6
  4. MySQL 10.1.14-MariaDB
@juhanix
Copy link

juhanix commented Nov 8, 2016

I 'm having the same issue that getQuote()->getAllVisibleItems() is always empty, if I try to use it in my custom module.
Makes no difference if I implement Magento/Checkout/Model/Cart inside my Custom Module or if I try to use ObjectManagerInstance. If I go to /checkout/cart I see that I definitely have items in my cart.
BTW: Same empty results while using Magento/Checkout/Model/Session.

Using Magento 2.1.2

EDIT:

Okay I got the answer pretty quickly. Read this:
Issue: #6624

Make your block not cacheable inside the layout xml

....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.

@AlessandroStaffolani
Copy link
Author

AlessandroStaffolani commented Nov 10, 2016

@juhanix that's great, now It works, I close the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants