1

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...

  • just a side note: could using the varnish cache solve the issue? – Jérôme Sep 3 '16 at 13:40
0

You can access get parameters in Magento 2 like this :

$this->getRequest()->getParam('id');
  • Yes, but when magneto serves a cached page it doesn't even call the observer. – Jérôme Sep 5 '16 at 13:14
  • Which event you have put in xml file to call observer? – user41152 Sep 7 '16 at 8:35
  • sales_order_load_after, sales_order_save_after – Jérôme Sep 7 '16 at 9:38
  • Have you tried to add shared="false" in your event.xml file? – user41152 Sep 8 '16 at 5:10
  • Yes. Is is pretty obvious that the reason for this problem is the magento caching. As the url does not change, the page is cached, even when it has a GET-request in it. After that caching cookies aren´t set (because only the cached page is served. Trying to figure out a work around. – Jérôme Sep 14 '16 at 14:02
0

Try controller_front_send_response_before event instead - it works fine on cached CMS pages. According to the nearest comment in the code - "This event gives possibility to launch something before sending output (allow cookie setting)".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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