2

If we need to get current customer sessions in a block, cacheable must be set to false in the layout XML. I am using \Magento\Customer\Model\SessionFactory $customerSession in my block but it is not working without cacheable false. Can someone tell me a recommended way to solve this problem?

Vivek Kumar
  • 5,115
  • 2
  • 24
  • 50
  • check this https://magento.stackexchange.com/questions/91897/how-to-check-if-customer-is-logged-in-or-not-in-magento-2 – Devidas Nov 15 '19 at 05:35

2 Answers2

2

\Magento\Customer\Model\SessionFactory will not work if the FPC is enabled. You can use the below code in your block class to check the user logged in the cache.

/**
 * Http Context
 *
 * @var \Magento\Framework\App\Http\Context
 */
protected $_httpContext;

/**
 * @var \Magento\Customer\Model\Session
 */
protected $customerSession;

/**
 * Init container
 */
public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Framework\App\Http\Context $httpContext,
    \Magento\Customer\Model\Session $customerSession,
    array $data = []
) {
    parent::__construct(
        $context,
        $data
    );
    $this->customerSession = $customerSession;
    $this->_httpContext = $httpContext;
    $this->_isScopePrivate = true;
}

public function isLoggedIn()
{
    return $this->_httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);
}

/**
 * get customer name
 *
 * @return string
 */
public function getCustomerName()
{
    if ($this->customerSession->isLoggedIn()) {
        return $this->customerSession->getCustomer()->getName();
    }
    return '';
}

Call $block->isLoggedIn() or $block->getCustomerName() in your phtml file to check the user is logged in or not.

I hope it helps!!!

Sumit
  • 4,875
  • 2
  • 19
  • 35
  • Thanks Sumit. Can you tell me how can I get customer data in above code. – Ashwani Rana Nov 15 '19 at 05:38
  • Updated my answer, please check. – Sumit Nov 15 '19 at 05:43
  • "Do not use the $_isScopePrivate property in your blocks. This property is obsolete and won’t work properly. " - Magento Devdocs.

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

    – Vivek Kumar Nov 15 '19 at 05:44
  • You should never use $_isScopePrivate, if you're looking for a quick fix just set cacheable false on the block specific to the page. It would be a better option. – Vivek Kumar Nov 15 '19 at 05:45
  • @VivekKumar cacheable false make a full page out of FPC. It's not a good practice. – Sumit Nov 15 '19 at 05:47
  • Still better than using an unstable obsolete feature, also I did mention use cacheable false for a block specific to the page so it won't block cache for all pages. – Vivek Kumar Nov 15 '19 at 05:48
  • A standard implementation would be using cache hole punching, I would be adding that in the answer – Vivek Kumar Nov 15 '19 at 05:49
  • @VivekKumar I've tried to add cacheable false to the block and it will make the page out of FPC. Hole punching is a good to approach. – Sumit Nov 15 '19 at 05:54
1

If you have to show customer-specific data (private content) you would have to serve the specific content from the server instead of cache. So, best practice would be using cache hole punching to get the specific data using ajax.

Magento has a standard implementation for us to use called customer sections which maintains versioning of the private content in local storage and invalidates them to get correct data through ajax call.

You can study it here on devdocs - https://devdocs.magento.com/guides/v2.3/extension-dev-guide/cache/page-caching/private-content.html

Here is some more read for understanding the internal working of customer sections - Magento 2: how do customer sections / sections.xml work?

Vivek Kumar
  • 5,115
  • 2
  • 24
  • 50