How to get customer session data when a cache is enabled in Magento 2?

In this article, you will be learning how to get customer session data when a cache is enabled in Magento 2.

Before you read this article, please refer our blog about “Magento 2: How to check customer is logged in or not when a cache is enabled”.

We can’t get any data from customer session when a cache is enabled Because as soon as layout generation started, customer session will be cleared by \Magento\PageCache\Model\Layout\DepersonalizePlugin::afterGenerateXml on all cacheable pages. So we can’t get any customer session data from \Magento\Customer\Model\Session.

As per our previous blog, using httpContext we can get a customer is logged in or not. But what about if you want to get customer id, name, email and other customer attributes.

By default, In httpContext only customer_group and customer_not_logged_in are defined. So Customer id, Name, Email and other customer attributes are not defined in httpContext.

So we will create a plugin to set customer session data in httpContext.

Please follow the below steps
1.Define plugin a di.xml file
2. Create a plugin 
3. Use httpContext data in block

1.Define plugin in di.xml file

Create a di.xml file in app/code/Aureatelabs/ModuleName/etc/frontend directory.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
	<type name="Magento\Framework\App\Action\AbstractAction">
    	<plugin name="customer-session-data-to-context" type="Aureatelabs\ModuleName\Plugin\CustomerSessionContext" sortOrder="15"/>
	</type>
</config>

2. Create a plugin

Create CustomerSessionContext.php file in app/code/Aureatelabs/ModuleName/Plugin directory.

<?php
namespace Aureatelabs\ModuleName\Plugin;

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

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

	/**
 	* @param \Magento\Customer\Model\Session $customerSession
 	* @param \Magento\Framework\App\Http\Context $httpContext
 	*/
	public function __construct(
    	\Magento\Customer\Model\Session $customerSession,
    	\Magento\Framework\App\Http\Context $httpContext
	) {
    	$this->customerSession = $customerSession;
    	$this->httpContext = $httpContext;
	}

	/**
 	* @param \Magento\Framework\App\ActionInterface $subject
 	* @param callable $proceed
 	* @param \Magento\Framework\App\RequestInterface $request
 	* @return mixed
 	*/
	public function aroundDispatch(
    	\Magento\Framework\App\ActionInterface $subject,
    	\Closure $proceed,
    	\Magento\Framework\App\RequestInterface $request
	) {
    	$this->httpContext->setValue(
        	'customer_id',
        	$this->customerSession->getCustomerId(),
        	false
    	);

    	$this->httpContext->setValue(
        	'customer_name',
        	$this->customerSession->getCustomer()->getName(),
        	false
    	);

    	$this->httpContext->setValue(
        	'customer_email',
        	$this->customerSession->getCustomer()->getEmail(),
        	false
    	);

    	return $proceed($request);
	}
}

We have to get data like customer_id, customer_name and customer_email from customer session and set in in httpContext using the plugin.

You can also set other customer data same as above and can be used in our block.

3. Use httpContext data in Block

Initialize \Magento\Framework\App\Http\Context in your custom block file.

<?php

namespace Aureatelabs\ModuleName\Block;

class CustomBlock extends \Magento\Framework\View\Element\Template
{
	protected $httpContext;

	public function __construct(
    	\Magento\Framework\View\Element\Template\Context $context,
    	\Magento\Framework\App\Http\Context $httpContext,
    	array $data = []
	) {
    	$this->httpContext = $httpContext;
    	parent::__construct($context, $data);
	}

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

	public function getCustomerId()
	{
    	return $this->httpContext->getValue('customer_id');
	}

	public function getCustomerName()
	{
    	return $this->httpContext->getValue('customer_name');
	}

	public function getCustomerEmail()
	{
    	return $this->httpContext->getValue('customer_email');
	}

}

Now you can get customer id, name and email from the block and can be used in the frontend. It will be displayed even a page cache is enabled.

I hope this will help you in implementing your own logic.

  • Share :