Search code examples
phpmagentocachingcookiesobservers

Cookies (Observer) not set when Cache enabled Magento 2.0.7


I have an observer that listens to <event name="controller_action_predispatch"> events.

The observer's execute method is correctly running on every request, but Cookies are not set correctly when caching is enabled, more specific Full Page Cache.(System -> Cache Management -> Page Cache).

Now when I disable cache, the cookies are set as expected, but the mini cart in the upper right corner stays empty when adding items to cart from the product list page. The only way to actually see the items in the mini cart and be able to checkout, is to first go to a random product overview page and then adding it to cart from there. Any ideas?

Setting Cookies inside the observer:

$cookieManager->setPublicCookie('Custom_Cookie', 'This is a Cookie');

The Observer class:

class MyObserver implements ObserverInterface {

protected $messageManager;
protected $cart;
protected $scopeConfig;
protected $logger;

public function __construct(
    \Magento\Framework\Message\ManagerInterface $messageManager,
    \Magento\Checkout\Model\Cart $cart,
    \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
    \Psr\Log\LoggerInterface $logger
) {

    $this->messageManager = $messageManager;
    $this->cart = $cart;
    $this->scopeConfig = $scopeConfig;
    $this->logger = $logger;
}

public function execute(\Magento\Framework\Event\Observer $observer)
{
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $cookieManager = $objectManager->get('Magento\Framework\Stdlib\CookieManagerInterface');
    $customer = $objectManager->create('Magento\Customer\Model\Customer');
    $product = $objectManager->create('Magento\Catalog\Model\Product');
    $cart = $objectManager->get('Magento\Checkout\Model\Cart');
    $customerSession = $objectManager->get('Magento\Customer\Model\Session');

    // COOKIE
    $cookieManager->setPublicCookie('Custom_Cookie', 'This is a Cookie');
    $this->logger->info('COOKIE IS ==> ' . $cookieManager->getCookie('Custom_Cookie'));

    ...

}

Solution

  • I just built an extension that is almost exactly like what you are doing. Please see the code I used below. This should work for you.

    Observer Class:

    <?php
    
    namespace Company\Module\Observer;
    
    class AffiliateTracking implements \Magento\Framework\Event\ObserverInterface
    {
        /**
         * @var \Magento\Framework\Registry
         */
        protected $_registry;
    
        /**
         * @var \Magento\Framework\App\Request\Http
         */
        protected $_request;
    
        /**
         * @var
         */
        protected $_cookieManager;
    
        /**
         * @var CookieMetadataFactory
         */
        protected $_cookieMetadataFactory;
    
        protected $_sessionManager;
    
        /**
         * The affiliate cookie name
         */
        const COOKIE_NAME = "nh_affiliate_id";
    
    
    
        public function __construct(
            \Magento\Framework\Registry $registry,
            \Magento\Framework\App\Request\Http $request,
            \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager,
            \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory,
            \Magento\Framework\Session\SessionManagerInterface $sessionManager)
        {
            $this->_registry = $registry;
            $this->_request = $request;
            $this->_cookieManger = $cookieManager;
            $this->_cookieMetadataFactory = $cookieMetadataFactory;
            $this->_sessionManager = $sessionManager;
        }
    
        /**
         * @param \Magento\Framework\Event\Observer $observer
         * @return $this
         */
        public function execute(\Magento\Framework\Event\Observer $observer)
        {
            $affiliateId = $this->_request->getParam("SSAID", false);
    
            if ($affiliateId)
            {
                $publicCookieMetadata = $this->_cookieMetadataFactory->createPublicCookieMetadata()
                    ->setDuration(2592000)
                    ->setPath($this->sessionManager->getCookiePath())
                    ->setDomain($this->sessionManager->getCookieDomain())
                    ->setHttpOnly(false);
    
                $this->_cookieManager->setPublicCookie(self::COOKIE_NAME,
                    $affiliateId,
                    $publicCookieMetadata
                );
            }
    
            return $this;
        }
    }