0

I am using Magento 2.1, php 7.0.

I am trying to check in block if provided product is in cart. I call from list.phtml (Magento_Catalog template) custom function in overriden block \Magento\Catalog\Block\Product\ListProduct which should check in checkout session that thing:

namespace [vendor]\SkinHelper\Block\Catalog\Product;

use \[vendor]\SkinHelper\Block\Catalog\Product\DownloadableSampleUrlProviderInterface;
use \[vendor]\System\Helper\Debug;
use \Magento\Catalog\Api\CategoryRepositoryInterface;
use \Magento\Catalog\Block\Product\Context;
use \Magento\Catalog\Block\Product\ListProduct as MagentoListProduct;
use \Magento\Catalog\Model\Layer\Resolver;
use \Magento\Checkout\Model\Session;
use \Magento\Downloadable\Model\Product\Type;
use \Magento\Downloadable\Model\ResourceModel\Sample\CollectionFactory;
use \Magento\Framework\Data\Helper\PostHelper;
use \Magento\Framework\Url\Helper\Data;
use \Magento\Framework\UrlInterface;


/** Class 'extends by rewriting' class of block: \Magento\Catalog\Block\Product\ListProduct */
class ListProduct extends MagentoListProduct
                    implements DownloadableSampleUrlProviderInterface
{


    /**
     * @var \Magento\Checkout\Model\Session
     */
    private $checkoutSession;


    /**
     * @var \Magento\Downloadable\Model\ResourceModel\Sample\CollectionFactory
     */
    private $samplesCollectionFactory;


    /**
     * @var \Magento\Store\Model\StoreManagerInterface;
     */
    private $storeManager;



    /**
     * @param \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository
     * @param \Magento\Catalog\Block\Product\Context $context
     * @param \Magento\Framework\Data\Helper\PostHelper $postDataHelper
     * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver
     * @param \Magento\Checkout\Model\Session $checkoutSession
     * @param \Magento\Downloadable\Model\ResourceModel\Sample\CollectionFactory $samplesCollectionFactory
     * @param \Magento\Framework\Data\Helper\PostHelper $postDataHelper
     * @param \Magento\Framework\Url\Helper\Data $urlHelper
     * @param array $data
     */
    public function __construct(
        CategoryRepositoryInterface $categoryRepository,
        Context $context,
        Resolver $layerResolver,
        Session $checkoutSession,
        CollectionFactory $samplesCollectionFactory,
        PostHelper $postDataHelper,
        Data $urlHelper,
        array $data
    )
    {
        parent::__construct($context, $postDataHelper, $layerResolver,
                            $categoryRepository, $urlHelper, $data);
        $this->checkoutSession = $checkoutSession;
        $this->samplesCollectionFactory = $samplesCollectionFactory;
        $this->storeManager = $context->getStoreManager();
    }


    /**
     * Method check if provided product is in cart of current customer.
     * Doesn't work dynamically.
     * 
     * @param \Magento\Catalog\Model\Product $product
     * 
     * @return bool $inCart
     */
    public function isInCart($product)
    {

        $productId = $product->getId();
        $cartItems = $this->checkoutSession->getQuoteId();
        $itemsIds = array();
        foreach ($cartItems as $cartItem) {
            array_push($itemsIds, $cartItem->getProduct()->getId());
        }

        return in_array($productId, $itemsIds);
    }

Preference works, because I can dump some string like 'test' or something. Almost the same code works in controller if fired by entering its url:

$productId = $objectManager->get('Magento\Catalog\Model\Product')->load(6)->getId();
    $test = $objectManager->get('\Magento\Checkout\Model\Session')->getQuote();
    $result = $test->getAllVisibleItems();
    $itemsIds = array();
    foreach ($result as $cartItem) {
        array_push($itemsIds, $cartItem->getProduct()->getId());
    }

    print_r(in_array($productId, $itemsIds));

I was debbuging former steps before check - and I am able to grab quote object but it's almost empty and doesn't has my product added to cart. And that's my question - why I am unable to check it inside block?

2
  • You want to check in mini cart or checkout cart page? – Khoa TruongDinh Aug 29 '16 at 15:18
  • I want to use it on list page (displaying products in categories), so only mini cart is visible, so I guess mini cart is what I want. Is there any difference? If it is added to cart and it's present in quote it should be visible anywhere, am I right? – Bartosz Kubicki Aug 29 '16 at 17:27
0

It is all because of full page cache architecture. In order to improve performance page with public content is fully cached. Cart items info is an example of private content (it is bound to active user), so it is not persisted into fpc (data is depersonalized - https://www.atwix.com/magento-2/session-depersonalization-in-magento-2-why-and-how/).

In order to implement such a feature, you should use private content and render it using javascript.

More resources: https://docs.magento.com/m2/ce/user_guide/system/cache-full-page.html

https://devdocs.magento.com/guides/v2.3/extension-dev-guide/cache/page-caching/public-content.html

https://devdocs.magento.com/guides/v2.3/extension-dev-guide/cache/page-caching/private-content.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.