Magento – Magento 2 Observer not called due to caching

cachecookieevent-observerhttp-requestmagento2.1.0

Intention

I am trying to get an affiliate extension to work. The basic concept is that a customer calls the shop-page with a get parameter that is the id of the affiliate partner. The ID will be stored in the session and any actions of the customers are tracked and in case of an order a commission is added to the affiliate partners balance.

Running in developer mode for each call of the shop´s index page with the affiliate ID in the url e.g. myshop.com/?id=123455 the ID is added to the cookie. Great.

Problem 1: Observer not called

In production mode, when I call the same page (after clearing all local browser caches and cookies) the observer that should handle the request params is not even called. Thus the ID isn´t processed and is not written to the cookie.

Problem 2: Affiliate-ID not saved in cookie

Now, if I open a random sub page and append the ?id=123455part at least the observer is called. But then when I check the cookie nothing is stored in there.

observer.php (part)

class ControllerPredispatch extends AbtractObserver implements ObserverInterface {
public function execute(\Magento\Framework\Event\Observer $observer)
{
    if(!$this->_helper->isAffiliateModuleEnabled())
        return $this;

    $controller = $observer['controller_action'];
    $request = $observer['request'];
    \Magento\Framework\App\ObjectManager::getInstance()
        ->get('Psr\Log\LoggerInterface')->debug("Affiliateplus: GET Params detected: ".serialize($request->getParams()));
    $accountCode = $request->getParam('acc');

    $this->_eventManager->dispatch('affiliateplus_controller_action_predispatch',
        [
            'request' => $request
        ]
    );
    $this->_saveClickAction($controller, $request);
    $expiredTime = $this->_helperConfig->getGeneralConfig('expired_time');
    $accountData = $this->_getAffiliateAccountByAccountCode($accountCode, $request);
    $account = isset($accountData['account']) ? $accountData['account'] : null;

    if($account && $account->getId()){

        $accountCode = $account->getIdentifyCode();
        \Magento\Framework\App\ObjectManager::getInstance()
            ->get('Psr\Log\LoggerInterface')->debug("Affiliateplus: Affiliate Code detected: ".serialize($accountCode));
        $this->_helperCookie->saveCookie($accountCode, $expiredTime, false, $controller);
    }

}...}

cookie.php (part)

public function saveCookie($accountCode, $expiredTime, $toTop = false, $controller = null) {
    if ($expiredTime){
        $this->_publicCookieMetadata->setDuration(intval($expiredTime) * 86400);
    }

    $current_index = $this->_cookieManager->getCookie('aff_map_index');
    $addCookie = new \Magento\Framework\DataObject(
        [
            'existed' => false,
        ]
    );

    for ($i = intval($current_index); $i > 0; $i--) {
        if ($this->_cookieManager->getCookie("aff_account_code_$i") == $accountCode) {
            $addCookie->setExisted(true);
            $addCookie->setIndex($i);
            $this->_eventManager->dispatch('aff_controller_action_predispatch_add_cookie',
                [
                    'request' => $this->_request,
                    'add_cookie' => $addCookie,
                    'cookie' => $this->_cookieManager,
                ]
            );

            if ($addCookie->getExisted()) {
                /**
                 * change latest account
                 */
                $curI = intval($current_index);
                for ($j = $i; $j < $curI; $j++) {
                    $this->_cookieManager->setPublicCookie(
                        "aff_account_code_$j", $this->_cookieManager->getCookie("aff_account_code_" . intval($j + 1)), $this->getPublicCookieMetadata(null, "/")
                    );
                }
                $this->_cookieManager->setPublicCookie("aff_account_code_$curI", $accountCode, $this->getPublicCookieMetadata(null, "/"));
                return $this;
            }
        }
    }
    $current_index = $current_index ? intval($current_index) + 1 : 1;
    $this->_cookieManager->setPublicCookie('aff_map_index', $current_index, $this->getPublicCookieMetadata(null, "/"));
    $this->_cookieManager->setPublicCookie("aff_account_code_$current_index", $accountCode, $this->getPublicCookieMetadata(null, "/"));
    $cookieParams = new \Magento\Framework\DataObject([
        'params' => [],
    ]);
    $this->_eventManager->dispatch('aff_controller_action_predispatch_observer',
        [
            'controller_action' => $controller,
            'cookie_params' => $cookieParams,
            'cookie' => $this->_cookieManager,
        ]
    );

    if ($toTop) {
        $datenow = date('Y-m-d');
        $this->_cookieManager->setPublicCookie($accountCode, $datenow, $this->getPublicCookieMetadata(null, "/"));
    }
}

Question
Could this be a problem with the magento caching?
What could help to get this working?

Update
I investigated whats happening in the observer, it is called, but it does not get the GET-Params of the URL. I can see several params but the ID is not passed. Gives me even more headaches…

Update
I realized I have the cookie-check enabled. Is it possible that the GET-params get lost when the page is reloaded via javascript when the use of cookies is accepted?

Update
I am pretty sure that the first time the index page (and probably any page) is called, the GET-params are processed, but a second call using the same GET-param only hits the cache. This might optimize speed, but in case, that calls come from different users this doesn´t make sense as we need the GET-Params be processed for each individual visitor of the page. Disabling the cache every time the GET-Param for affiliates is detected could be a solution. But I can´t figure out how to disable the cache from within the observer only for the page called…

Best Answer

You can access get parameters in Magento 2 like this :

$this->getRequest()->getParam('id');
Related Topic