A client uses the FME Restrict Customer Group module to give customers that are logged in a selection of products based on a customer group. He wants to give customers the option to toggle this selection. Simply put: we build a plugin that jumps in on the FME module and enables/disables it via frontend.
However the FullPageCache(FPC) prevents this plugin from working as intented.
So simply put there are 3 files relevant: SwitchRestrictCustomerGroup/Block/Block.php
public $session;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
array $data = [],
\Magento\Customer\Model\Session $customerSession
) {
parent::__construct($context, $data);
$this->session = $customerSession;
}
public function isLoggedIn(){
$loggedIn = $this->session->isLoggedIn();
return $loggedIn;
}
public function getSwitchValue(){
$switchValue = $this->session->getSwitchKey();
$modifiedSwitchValue = null;
if($switchValue == null || $switchValue == 'aan'){
$modifiedSwitchValue = true;
}
else {
$modifiedSwitchValue = false;
}
return $modifiedSwitchValue;
}
}
SwitchRestrictCustomerGroup/Controller/Session/Save.php
class Save extends Action
{
protected $session;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Customer\Model\Session $customerSession
)
{
$this->session = $customerSession;
return parent::__construct($context);
}
public function execute()
{
$sessionId = $this->session->getSessionId();
$request = $this->getRequest()->getParams();
if(array_key_exists('switch', $request)){
if($request['switch'] == 'on'){
$this->session->setSwitchKey('aan');
}
else {
$this->session->setSwitchKey('uit');
}
}
else {
$this->session->setSwitchKey('uit');
}
$this->_redirect($this->_redirect->getRefererUrl());
}
}
And last: SwitchRestrictCustomerGroup/Plugin/DataPlugin.php
class DataPlugin
{
public $session;
public function __construct(
\Magento\Customer\Model\Session $customerSession
) {
$this->session = $customerSession;
}
public function afterIsEnabledInFrontend(\FME\Restrictcustomergroup\Helper\Data $subject, $result)
{
$sessionId = $this->session->getSessionId();
// check for true/false first to keep original config purpose of enabled/disabling frontend in fme module
if($result == true){
$switchValue = $this->session->getSwitchKey();
if($switchValue == 'uit'){
$result = false;
return $result;
}
elseif($switchValue == 'aan') {
$result = true;
return $result;
}
else {
$result = true;
return $result;
}
}
// if frontend is disabled in fme module
else {
$result = false;
return $result;
}
}
}
Simply put: The block is set the category view. It loads a .phtml that only places the html if a customer is logged in. Thus the function isLoggedin(). It places a piece of html with a simple slider. If further checks if the switch value is set in the customer session and if that value is on or off.
The controller processes the value from the slider and sets the switch value to on or off in a customer session.
The plugin file reads the customer session and returns a value of true/false depending on what is set in the customer session switch value.
This all works as designed when the Full Page Cache is turned off.
The problems when the FPC is turned on
- The block always receives a false value on isUserLoggedin. So the template is never shown. I am aware that this is because of the session depersonalization. When I use a factory this does seem to work somehow.
- When I use a factories instead of DI, the site gets all weird with pages the user is logged in, not logged in, or both at the same time.
- So when I use a factory on only the block, and DI on the rest, it seems to be the closest to working properly with FPC on. However: When i flush the cache, visit category A it works as excepted. I turn the slider off, visit category B, the slider is also off. I turn it on in Category B, return to Category A, and there it is off again. It caches the switch value per category instead of having 1 global switch value in the customer session because of the cache.
My questions:
- Are session factories actually the correct way to use this? It seems to mess up allot.
- How can I build this plugin as intended, without turning the FPC off conform best practice.