2

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

  1. 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.
  2. 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.
  3. 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:

  1. Are session factories actually the correct way to use this? It seems to mess up allot.
  2. How can I build this plugin as intended, without turning the FPC off conform best practice.

3 Answers 3

1

Can you try with this

<?php
namespace MyVendor\MyModule\Helper;

use Magento\Framework\App\Helper\AbstractHelper;


class Data extends AbstractHelper
{
    /**
     * @var \Magento\Framework\App\Http\Context
     */
    private $httpContext;

    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Framework\App\Http\Context $httpContext
    ) {
        parent::__construct($context);
        $this->httpContext = $httpContext;
    }

    public function isLoggedIn()
    {
        $isLoggedIn = $this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);
        return $isLoggedIn;
    }
}
1
  • Thanks for the reply. I will give it a test and get back to you.
    – JerGrun
    Feb 23, 2021 at 14:08
0

Please check
Customer Session Not working in magento 2

or

Why Customer Session is not working on full page cache?

Unfortunately Magento has some hmmm troubles with caching. For example if FPC is enabled and at least one element on block is not cachable, whole page wont be cached. So I guess, You want to keep FPC for category pages..

You can also try to load block using ajax - it should fix issue with cachable

0

On block Using Magento\Customer\Model\SessionFactory instead Magento\Customer\Model\Session since it was cached by FPC

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

public function __construct(
    ....
    \Magento\Customer\Model\SessionFactory $customerSessionFactory
    ....
) {
    ....
    $this->customerSessionFactory = $customerSessionFactory;
    ....
}

public function isCustomerLoggedIn(){
  return $this->customerSessionFactory->create()->isLoggedIn();
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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