In this post we will see how we can get the customer specific data when cache is enabled. Before directly jumping to the code lets just try to learn why we don’t get the customer id from session when the Cache is enabled.
If you view the vendor/magento/module-customer/etc/frontend/di.xml file, you can find the following plugin declaration:
<type name="Magento\Framework\View\Layout"> <plugin name="customer-session-depersonalize" type="Magento\Customer\Model\Layout\DepersonalizePlugin" sortOrder="10"/> </type>
Check this plugin and you will find that in afterGenerateXml() function has been cleared.
public function afterGenerateXml(\Magento\Framework\View\LayoutInterface $subject, $result) { if ($this->depersonalizeChecker->checkIfDepersonalize($subject)) { $this->visitor->setSkipRequestLogging(true); $this->visitor->unsetData(); $this->session->clearStorage(); $this->customerSession->clearStorage(); $this->session->setData(\Magento\Framework\Data\Form\FormKey::FORM_KEY, $this->formKey); $this->customerSession->setCustomerGroupId($this->customerGroupId); $this->customerSession->setCustomer($this->customerFactory->create()->setGroupId($this->customerGroupId)); } return $result; }
Because of this you didn’t get the customerId from session when cache is enabled.
Now, we will see How to get the customerId when cache is enabled.
We will create context variable to save the customer Id.
For this, we will create plugin on the AbstractAction and will set the customerId.
<!-- File: Namespace/Yourmodule/etc/frontend/di.xml --> <?xml version="1.0"?> <!-- /** * Webkul Software. * * @category Webkul * @author Webkul * @copyright Copyright (c) 2010-2018 Webkul Software Private Limited (https://webkul.com) * @license https://store.webkul.com/license.html */ --> <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="wk-abstractaction-context-plugin" type="Namespace\Yourmodule\Plugin\App\Action\Context" sortOrder="15"/> </type> </config>
Now, create plugin file.
<?php namespace NameSpace\Yourmodule\Plugin\App\Action; class Context { /** * @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 ); return $proceed($request); } }
Now, you can get the customer Id in Helper like:
<?php namespace NameSpace\Yourmodule\Helper; class Data extends \Magento\Framework\App\Helper\AbstractHelper { protected $httpContext; /** * @param \Magento\Framework\App\Helper\Context $context * @param \Magento\Framework\App\Http\Context $httpContext */ public function __construct( \Magento\Framework\App\Helper\Context $context, \Magento\Framework\App\Http\Context $httpContext ) { $this->httpContext = $httpContext; parent::__construct($context); } /** * function to get customer id from context * * @return int customerId */ public function getCustomerId() { return $this->httpContext->getValue('customer_id'); } }
For further reading on the use of context variables check the Magento doc here. Hope this will help you in implementing your logics. For any query, do let me know in the comment below.
> Context variables should not be specific to individual users because variables are used in cache keys for public content. In other words, a context variable per user results in a separate copy of content cached on the server for each user.