<?php
QUnit_Global::includeClass('Affiliate_Scripts_Bl_Registrator');

class Affiliate_Scripts_Bl_ClickRegistrator extends Affiliate_Scripts_Bl_Registrator
{
    var $multiTierCommissionsCounter = 0;
    var $subBannerID = '';
    var $browserHash;
    var $clickCount;
    var $transID;
    
    //--------------------------------------------------------------------------

    function Affiliate_Scripts_Bl_ClickRegistrator()
    {
        Affiliate_Scripts_Bl_Registrator::Affiliate_Scripts_Bl_Registrator();
        $this->registration_type = 'ClickRegistrator';
    }
    
    //--------------------------------------------------------------------------

    function process($params) {
        $this->setAccountID();
        
        $this->registratorLog(WLOG_DEBUG, "Click registration: Start registering click, params: ".getParams($_REQUEST), __FILE__, __LINE__);
        
        $params = $this->getParameters();
        
        if(!$this->checkCorrectParameters($params)) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: Checking parameters failed", __FILE__, __LINE__);
            return false;
        }
        
        if(!$this->processRotator($params)) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: Processing rotator failed", __FILE__, __LINE__);
            return false;
        }
        
        $result = $this->checkGeoTargetting($params);
        
        $this->processClick($result, $params);
    }
    
    //--------------------------------------------------------------------------
    
    function setAccountID() {
        if($GLOBALS['Auth']->getProgramType() == PROG_TYPE_PRO 
            || $GLOBALS['Auth']->getProgramType() == PROG_TYPE_ECOMMAGNET 
            || $GLOBALS['Auth']->getProgramType() == PROG_TYPE_LITE) 
        {
            $GLOBALS['Auth']->setAccountID(DEFAULT_ACCOUNT);
        } else {
            if($GLOBALS['Auth']->getAccountID() == '') {
                QCore_History::log(WLOG_ERROR, "Click registration: Cannot recognize account from domain '".getHostName()."'", __FILE__, __LINE__);
                return;
            }
        }
        
        $this->settings['Aff_debug_clicks'] = $GLOBALS['Auth']->getSettingForScripts('Aff_debug_clicks');
        $GLOBALS['Auth']->setUserType(USERTYPE_ADMIN);
    }
    
    //--------------------------------------------------------------------------
    
    function getParameters() {
        $params = array();
        
        if ($_REQUEST['AffiliateID'] != '') {
            $params['affiliateID'] = preg_replace('/[\'\"]/', '', $_REQUEST['AffiliateID']);
            $params['bannerID'] = preg_replace('/[\'\"]/', '', $_REQUEST['BannerID']);
        } else {
            $params['affiliateID'] = preg_replace('/[\'\"]/', '', $_REQUEST[PARAM_A_AID]);
            $params['bannerID'] = preg_replace('/[\'\"]/', '', $_REQUEST[PARAM_A_BID]);
        }
        
        $params['subBannerID'] = preg_replace('/[\'\"]/', '', $_REQUEST['a_sbid']);
        $params['data1'] = preg_replace('/[\'\"]/', '', $_REQUEST[PARAM_DATA1]);
        $params['data2'] = preg_replace('/[\'\"]/', '', $_REQUEST[PARAM_DATA2]);
        $params['data3'] = preg_replace('/[\'\"]/', '', $_REQUEST[PARAM_DATA3]);
        
        if ($_REQUEST['d1'] != '') $params['data1'] = preg_replace('/[\'\"]/', '', $_REQUEST['d1']);
        if ($_REQUEST['d2'] != '') $params['data2'] = preg_replace('/[\'\"]/', '', $_REQUEST['d2']);
        if ($_REQUEST['d3'] != '') $params['data3'] = preg_replace('/[\'\"]/', '', $_REQUEST['d3']);
        
        $params['destUrl'] = preg_replace('/[\'\"]/', '', $_REQUEST[PARAM_DESTURL]);
        $params['referrer'] = $_REQUEST['referrer'];
        $params['dontRedirect'] = preg_replace('/[\'\"]/', '', $_REQUEST['dr']);
        $params['1stPartyTracking'] = preg_replace('/[\'\"]/', '', $_REQUEST['js']);
        
        $this->browserHash = substr(md5($_SERVER['HTTP_USER_AGENT'].$_SERVER['HTTP_ACCEPT_LANGUAGE'].$_SERVER['HTTP_ACCEPT']), 0, 6);;
        
        $this->setExtraData($params['data1'], $params['data2'], $params['data3']);
        
        return $params;
    }
    
    //--------------------------------------------------------------------------

    function checkCorrectParameters($params) {
        $affiliateID = $params['affiliateID'];
        $bannerID = $params['bannerID'];
        
        if($affiliateID == '') {
            QCore_History::logWithCondition($GLOBALS['Auth']->getSettingForScripts('Aff_debug_clicks') == 1, WLOG_DEBUG, "Click registration: Missing Affiliate ID when calling click registration", __FILE__, __LINE__);
            return false;
        }
        
        // check if this affiliate exists
        if(!$this->checkUserExists($affiliateID)) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: Affiliate with ID '".$affiliateID."' doesn't exist", __FILE__, __LINE__);
            return false;
        }
        $this->registratorLog(WLOG_DEBUG, "Click registration: After check that affiliate exists, OK", __FILE__, __LINE__);
        
        // check if domain is approved
        if($GLOBALS['Auth']->getSetting('Aff_force_aff_domains_approval') == '1') {
            if(!$this->checkInDomain()) {
                $this->registratorLog(WLOG_DEBUG, "Click registration: Banner with ID '$bannerID' for affiliate '$affiliateID' is placed in unallowed domain", __FILE__, __LINE__);
                return false;
            }
            
            $this->registratorLog(WLOG_DEBUG, "Click registration: After check that banner is in approved defined domain, OK", __FILE__, __LINE__);
        }
        
        if(!$this->checkBannerExists($bannerID, true)) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: Banner '$bannerID' doesn't exist and cannot find any campaign for affiliate '$affiliateID'", __FILE__, __LINE__);
            return false;
        }
        $this->registratorLog(WLOG_DEBUG, "Click registration: After check that banner exists, OK", __FILE__, __LINE__);
        
        if(!$this->checkCampaignExists()) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: Campaign '".$this->campaignID."' doesn't exist", __FILE__, __LINE__);
            return false;
        }
        $this->registratorLog(WLOG_DEBUG, "Click registration: After check that campaign exists", __FILE__, __LINE__);
        
        if(!$this->checkUserInCampaign()) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: Affiliate '$affiliateID' doesn't belong to the campaign '".$this->campaignID."'", __FILE__, __LINE__);
            return false;
        }
        $this->registratorLog(WLOG_DEBUG, "Click registration: After check that affiliate is in this product category, OK", __FILE__, __LINE__);
        
        return true;
    }
    
    //--------------------------------------------------------------------------

    function checkGeoTargetting($params) {
        if($this->settings['Glob_acct_geo_allowed'] == '1') {
            QUnit_Global::includeClass('QCore_Bl_IpCountry');
            
            // geo-targetting check
            $this->setCountryData('__');
            $redirectUrl = $params['destUrl'];
            
            $ip = $_SERVER['REMOTE_ADDR'];
            $blIpCountry = QUnit_Global::newObj('QCore_Bl_IpCountry');
            $country = $blIpCountry->getCountryForIp($ip);
            $this->setCountryData($country['countrycode']);
            
            if(!$blIpCountry->isAllowedCountry($country, $this->settings) && $this->settings['Glob_acct_geo_dont_register_click'] == '1') {
                $this->registratorLog(WLOG_DEBUG, "Click registration: Country from IP '$ip' is not in list of allowed countries", __FILE__, __LINE__);
                return false;
            }
        }
        
        return true;
    }
    
    //--------------------------------------------------------------------------
    
    function isOverwriteCookieOn() {
        $userSettings = $this->blSettings->getUserSettings(SETTINGTYPE_USER, $this->AccountID, $this->UserID);
        switch ($userSettings['Aff_overwrite_cookie']) {
            case AFF_OVERWRITE_COOKIE_ON:
                return true;
            case AFF_OVERWRITE_COOKIE_OFF:
                return false;
            default:
                return $this->settings['Aff_overwrite_cookie'] == '1';
        }
    }
    
    //--------------------------------------------------------------------------
    
    function displayJavaScriptSave1stPartyCookieCode($params) {
        
        $this->setFirstPartySalesCookie($params);
        
        $this->setFirstPartyOriginalRefCookie($params);
        
        $this->setFirstPartyTimeCookie($params);
        
        $this->setFirstPartyClickCookie($params);
        
        ?>
            _tracker.trackNext();
        <?php
    }
    
    //--------------------------------------------------------------------------
    
    function setFirstPartySalesCookie($params) {
        $data = $this->decodeValue($_COOKIE[COOKIE_NAME]);
        
        $cookieUserID = $data[0];
        $cookieCampaignID = $data[1];

        if($this->UserID == '') {
            $this->registratorLog(WLOG_DEBUG, "Click registration: UserID is empty", __FILE__, __LINE__);
            return false;
        }

        if($this->CampaignID == '') {
            $this->registratorLog(WLOG_DEBUG, "Click registration: CampaignID is empty", __FILE__, __LINE__);
            return false;      
        }

        if($data != false && ($this->UserID != $cookieUserID || $this->CampaignID != $cookieCampaignID) && !$this->isOverwriteCookieOn()) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: cookie exists, not allowed to overwrite, cancelling saving to cookie", __FILE__, __LINE__);
            return true;
        }
        
        if($this->cookieLifetime == '')
            $this->cookieLifetime = 0;
        
        if($this->cookieLifetime != 0) {
            $lifetime =  time() + $this->cookieLifetime*86400;
            $expireDate = date('Y-m-d', $lifetime);
        } else {
            $expireDate = date("Y-m-d", mktime (0,0,0,date("m"),  date("d"),  date("Y")+10));
        }
        $value = $this->UserID.'_'.$this->CampaignID;
        $setIfNotExists = $this->isOverwriteCookieOn() ? '0' : '1';
?>
        _tracker.setCookie('<?php echo COOKIE_NAME?>', '<?php echo $value?>', '<?php echo $expireDate?>', '<?php echo $setIfNotExists?>');
<?php
    }
    
    //--------------------------------------------------------------------------
    
    function setFirstPartyOriginalRefCookie($params) {
        if($params['referrer'] != '') {
            $cookie = time()."_".$params['referrer'];
        $expireDate = date("Y-m-d", mktime (0,0,0,date("m"),  date("d"),  date("Y")+10));
?>
        _tracker.setCookie('<?php echo REF_COOKIE_NAME?>', '<?php echo $cookie?>', '<?php echo $expireDate?>', '1');
<?php      
        }
    }
    
    //--------------------------------------------------------------------------
    
    function setFirstPartyTimeCookie($params) {
        $data = $_COOKIE[TIME_COOKIE_NAME];
        
        $dateFirstClick = time();
        $clickCount = 1;
        if ($data != "") {
            $cookie = explode("_", $data);
            if ($cookie[0] != "")
                $dateFirstClick = $cookie[0];
            if (($cookie[2] != "") && is_numeric($cookie[2]))
                $clickCount = $cookie[2];
        }
        
        $data = $dateFirstClick.'_'.time().'_'.$clickCount;
        
        $expireDate = date("Y-m-d", mktime (0,0,0,date("m"),  date("d"),  date("Y")+10));
?>
        _tracker.setTimeCookie('<?php echo TIME_COOKIE_NAME?>', '<?php echo $data?>', '<?php echo $expireDate?>', <?php echo $this->clickCount+1?>);
<?php
    }
    
	//--------------------------------------------------------------------------
    
    function setFirstPartyClickCookie($params) {
        $data = $this->transID;
        $expireDate = date("Y-m-d", mktime (0,0,0,date("m"),  date("d"),  date("Y")+10));
?>
        _tracker.setCookie('<?php echo CLICK_COOKIE_NAME?>', '<?php echo $data?>', '<?php echo $expireDate?>', '0');
<?php      
    }
    
    //--------------------------------------------------------------------------
    
    function processRotator($params) {
        if($this->BannerType == BANNERTYPE_ROTATOR) {
            if(($subBannerData = $this->getBannerData($params['subBannerID'])) === false) {
                $this->registratorLog(WLOG_DEBUG, "Click registration: Rotator banner -> banner ".$params['subBannerID']." does not exist", __FILE__, __LINE__);
                return false;;
            }
            $this->destinationURL = $subBannerData['destinationurl'];
            $this->updateRotatorStatistics($params['subBannerID']);
            $this->subBannerID = $params['subBannerID'];
        }
        
        return true;
    }
    
    //--------------------------------------------------------------------------
    
    function processClick($result, $params) {
        if($result) {
            if ($this->updateTransactionLimit(TRANSTYPE_CLICK)) {
                $redirectUrl = LIMIT_DEFAULT_REDIRECT;
            } else {
                $this->setCookie($params);
                $this->registratorLog(WLOG_DEBUG, "Click registration: After setting cookie, OK", __FILE__, __LINE__);
                
                $this->saveClick($params['referrer']);
                $this->setClickCookie();
                $this->registratorLog(WLOG_DEBUG, "Click registration: End registering click", __FILE__, __LINE__);
                $redirectUrl = $_REQUEST[PARAM_DESTURL];
            }
        } else {
            switch($this->settings['Glob_acct_geo_after_click_action']) {
                case AC_DEFAULT_DEST:
                    $redirectUrl = $destUrl;
                    break;
                case AC_SIGNUP_FORM: 
                    $redirectUrl = '../signup_aff.php';
                    $this->registratorLog(WLOG_DEBUG, "Click registration: Redirecting to signup form", __FILE__, __LINE__);
                    break;
                case AC_CUSTOM_DEST:
                    $redirectUrl = $this->settings['Glob_acct_geo_custom_dest'];
                    $this->registratorLog(WLOG_DEBUG, "Click registration: Redirecting to custom URL", __FILE__, __LINE__);
                    break;
            }
        }
        
        if($params['dontRedirect'] == '' || $params['dontRedirect'] != 'n') {
            $this->redirect($redirectUrl, false);
        } elseif ($params['1stPartyTracking'] == 'y') {
            $this->displayJavaScriptSave1stPartyCookieCode($params); 
        }
    }
    
    //--------------------------------------------------------------------------
    
    function setClickTimeCookie() {
        $data = $_COOKIE[TIME_COOKIE_NAME];
        
        $dateFirstClick = time();
        $clickCount = 1;
        if ($data != "") {
            $cookie = explode("_", $data);
            if ($cookie[0] != "")
                $dateFirstClick = $cookie[0];
            if (($cookie[2] != "") && is_numeric($cookie[2])) {
                $this->clickCount = $cookie[2];
                $clickCount = $cookie[2] + 1;
            }
        }
        
        $data = $dateFirstClick.'_'.time().'_'.$clickCount;
        
        if (!setcookie(TIME_COOKIE_NAME, $data, time() + 3650*86400, '/')) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: time cookie setcookie returned false", __FILE__, __LINE__);
        }
    }
    
	//--------------------------------------------------------------------------
    
    function setClickCookie() {
        $data = $this->transID;
        
        if (!setcookie(CLICK_COOKIE_NAME, $data, time() + 3650*86400, '/')) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: extra data cookie setcookie returned false", __FILE__, __LINE__);
        }
    }
    
    //--------------------------------------------------------------------------
    
    function setOriginalRefererCookie($params) {
        $data = $_COOKIE[REF_COOKIE_NAME];
        if($data == '') {
            // overwrite only if original referer cookie is empty
            if($params['referrer'] != '') {
                $cookie = time()."_".$params['referrer'];
                
                if (!setcookie(REF_COOKIE_NAME, $cookie, time() + 3650*86400, '/')) {
                    $this->registratorLog(WLOG_DEBUG, "Click registration: original referrer cookie setcookie returned false", __FILE__, __LINE__);
                } else {
                    $this->registratorLog(WLOG_DEBUG, "Click registration: original referrer cookie saved '".$params['referrer']."'", __FILE__, __LINE__);
                }
            } else {
                $this->registratorLog(WLOG_DEBUG, "Click registration: original referrer is empty, will not save it to cookie", __FILE__, __LINE__);
            }
        } else {
            $this->registratorLog(WLOG_DEBUG, "Click registration: original referrer cookie already exisit", __FILE__, __LINE__);
        }
    }
    
    //--------------------------------------------------------------------------
    
    function setCookie($params)
    {
        $this->setP3PPolicy('0');
        
        $this->setOriginalRefererCookie($params);
        
        $this->setClickTimeCookie();
        
        $data = $this->decodeValue($_COOKIE[COOKIE_NAME]);
        
        $cookieUserID = $data[0];
        $cookieCampaignID = $data[1];

        if($this->UserID == '') {
            $this->registratorLog(WLOG_DEBUG, "Click registration: UserID is empty", __FILE__, __LINE__);
            return false;
        }

        if($this->CampaignID == '') {
            $this->registratorLog(WLOG_DEBUG, "Click registration: CampaignID is empty", __FILE__, __LINE__);
            return false;      
        }

        if($data != false && ($this->UserID != $cookieUserID || $this->CampaignID != $cookieCampaignID) && $this->settings['Aff_overwrite_cookie'] != '1') {
            $this->registratorLog(WLOG_DEBUG, "Click registration: cookie exists, not allowed to overwrite, cancelling saving to cookie", __FILE__, __LINE__);
            return true;
        }

        if($this->cookieLifetime == '')
            $this->cookieLifetime = 0;
        
        if($this->cookieLifetime != 0)
            $lifetime =  time() + $this->cookieLifetime*86400;
        else
            $lifetime =  time() + 3650*86400;
        
        $value = $this->UserID.'_'.$this->CampaignID;
        $this->cookieSetReturn = setcookie(COOKIE_NAME, $value, $lifetime, '/');

        if($this->settings['Aff_track_by_session'] == 1)
        {
            if(!headers_sent())
                session_start();
            
            $_SESSION[COOKIE_NAME] = $value;
        }
    
        if(!$this->cookieSetReturn) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: setcookie returned false", __FILE__, __LINE__);
            return false;
        }
    }
    
    //--------------------------------------------------------------------------
    
    function saveClick($referrer = '')
    {
        if($this->settings['Aff_support_click_commissions'] != 1 && $this->settings['Aff_dont_save_click_transaction'] == 1) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: click not saved - disabled in Settings", __FILE__, __LINE__);
            return true;
        }

        $params = $this->checkBeforeSaveClick($referrer);
        if($params == false) return false;
        
        $status = $params['status'];
        $ip = $params['ip'];
        $remoteAddr = $params['remoteAddr'];

        //------------------------------------------
        // register normal commission
        if( ($commission = $this->getCommission()) === false) return false;

        if($this->BannerType == BANNERTYPE_ROTATOR) {
            $bannerID = $this->subBannerID;
            $rotatorID = $this->BannerID;
        } else {
            $bannerID = $this->BannerID;
            $rotatorID = '';
        }
        
        $TransID = QCore_Sql_DBUnit::createUniqueID('wd_pa_transactions', 'transid');
        $this->transID = $TransID;
        $sql = "insert into wd_pa_transactions ".
            "(transid, accountid, affiliateid, campcategoryid, bannerid, rotatorid,".
            " cookiestatus, dateinserted, transtype, transkind, refererurl,".
            " ip, countrycode, rstatus, commission, data1, data2, data3, browser)".
            "values("._q($TransID).","._q($this->AccountID).
            ","._q($this->UserID).","._q($this->CampaignCategoryID).
            ","._q($bannerID).","._q($rotatorID).","._q($this->cookieSetReturn).",".sqlNow().
            ",".TRANSTYPE_CLICK.",".TRANSKIND_NORMAL.","._q($remoteAddr).
            ","._q($ip).","._q($this->countryCode).","._q($status).","._q($commission).
            ","._q($this->extraData1).","._q($this->extraData2).","._q($this->extraData3).
            ","._q($this->browserHash).")";

        $ret = QCore_Sql_DBUnit::execute($sql, __FILE__, __LINE__);
        if (!$ret) {
            $this->registratorLog(WLOG_ERROR, "Click registration: Error saving click", __FILE__, __LINE__);
            return false;
        }

        $this->registratorLog(WLOG_DEBUG, "Click registration: After saving click, Start registering multi tier commissions", __FILE__, __LINE__);

        //------------------------------------------
        // register multi tier commissions
        $this->registerMultiTierClickCommission($TransID, $remoteAddr, $ip, $status, $this->UserID, 2);

        $this->registratorLog(WLOG_DEBUG, "Click registration: After registering multi tier commissions", __FILE__, __LINE__);
        
        return true;
    }
    
    //--------------------------------------------------------------------------
    
    function registerMultiTierClickCommission($parentTransID, $remoteAddr, $ip, $status, $parentUserID, $tier, $maxRecursion = 50)
    {
        if($maxRecursion <= 0) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: Maximum recursion reached", __FILE__, __LINE__);
            return true;
        }

        if($tier > $this->maxCommissionLevels) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: Maximum tier levels reached", __FILE__, __LINE__);
            return true;
        }
        
        //----------------------------------------
        // get parent user for this child
        $params = array('parentUserID' => $parentUserID, 'status' => $status);

        if(($params = $this->getParentUser($params)) === false) return false;

        $userID = $params['userID'];
        $status = $params['status'];
        $deleted = $this->isUserDeleted($userID);
        
        if ($deleted == false) {

            $params = array('userID' => $userID, 'tier' => $tier);

            if($this->checkSpecialCommission($params) === false) return false;

            $commission = $this->getCommissionMultiTier(array('tier' => $tier));

            if($commission === false) return false;

            if($commission != 0)
            {
                if($this->BannerType == BANNERTYPE_ROTATOR) {
                    $bannerID = $this->subBannerID;
                    $rotatorID = $this->BannerID;
                } else {
                    $bannerID = $this->BannerID;
                    $rotatorID = '';
                }
            
                if ($this->updateTransactionLimit(TRANSTYPE_CLICK))
                    return false;

                //----------------------------------------
                // register commission
                $TransID = QCore_Sql_DBUnit::createUniqueID('wd_pa_transactions', 'transid');
                $sql = "insert into wd_pa_transactions ".
                    "(transid,parenttransid,affiliateid,campcategoryid,bannerid,rotatorid,".
                    "cookiestatus,dateinserted,transtype,transkind,refererurl,ip,".
                    "rstatus,commission,accountid, data1, data2, data3)".
                    "values("._q($TransID).","._qOrNull($parentTransID).
                    ","._q($userID).","._q($this->CampaignCategoryID).
                    ","._q($bannerID).","._q($rotatorID).","._q($this->cookieSetReturn).
                    ",".sqlNow().",".TRANSTYPE_CLICK.",".(TRANSKIND_SECONDTIER+$tier).
                    ","._q($remoteAddr).","._q($ip).", "._q($status).
                    ","._q($commission).","._q($this->AccountID).","._q($this->extraData1).
                    ","._q($this->extraData2).","._q($this->extraData3).")";
                
                $ret = QCore_Sql_DBUnit::execute($sql, __FILE__, __LINE__);
                if (!$ret) {
                    $this->registratorLog(WLOG_ERROR, "Click registration: Error saving $tier - tier click commission", __FILE__, __LINE__);
                    return false;
                }
            
                $this->multiTierCommissionsCounter++;
                
                $this->registratorLog(WLOG_DEBUG, "Click registration: Saved multi tied commission to transaction ID '$TransID'", __FILE__, __LINE__);
            }
            
        }
        
        //----------------------------------------
        // go recursively to the next tier
        if($tier < $this->maxCommissionLevels)
        {
            $this->registerMultiTierClickCommission($TransID, $remoteAddr, $ip, $status, $userID, $tier + 1, $maxRecursion -1);          
        }
        
        return true;
    }
    
    //--------------------------------------------------------------------------
    
    function checkBeforeSaveClick($referrer = '')
    {
        if($this->CampaignCategoryID == '') {
            $this->registratorLog(WLOG_DEBUG, "Click registration: CampaignCategoryID is empty", __FILE__, __LINE__);
            return false;      
        }

        if($this->BannerID == '') {
            $this->registratorLog(WLOG_DEBUG, "Click registration: BannerID is empty", __FILE__, __LINE__);
            return false;      
        }

        if($this->cookieSetReturn == '')
            $this->cookieSetReturn = 99;
        
        if($referrer != '')
            $remoteAddr = $referrer;
        else
            $remoteAddr = $_SERVER['HTTP_REFERER'];
        
        $ip = $_SERVER['REMOTE_ADDR'];
        
        if($this->ClickTransactionApproval == APPROVE_MANUAL)
            $status = AFFSTATUS_NOTAPPROVED;
        else
            $status = AFFSTATUS_APPROVED;
        
        // check fraud protection
        if($this->DeclineFrequentClicks == 1) {
            if(!$this->applyFraudProtection($ip, $status))
                return false;
        }
        
        $this->registratorLog(WLOG_DEBUG, "Click registration: After fraud protection, OK", __FILE__, __LINE__);

        return array('status' => $status, 'ip' => $ip, 'remoteAddr' => $remoteAddr);
    }
    
    //--------------------------------------------------------------------------
    
    function getCommission()
    {
        $commission = 0;

        if(!($this->CampaignCommType & TRANSTYPE_CLICK))
        {
            $commission = 0;
        }
        else
        {
            // compute commission
            $commission = $this->ClickCommission;
            if($commission == '')
                $commission = 0;
            
            if($commission == 0) {
                $this->registratorLog(WLOG_DEBUG, "Click registration: Commission is zero. Transaction not saved.", __FILE__, __LINE__);
            }
        }
        
        return $commission;
    }
    
    //--------------------------------------------------------------------------
    
    function getCommissionMultiTier($params)
    {
        //----------------------------------------
        // compute commission in this tier
        $commission = 0;
        if(!($this->CampaignCommType & TRANSTYPE_CLICK)) {
            $this->registratorLog(WLOG_DEBUG, "Click registration: Campaign type is not per click", __FILE__, __LINE__);
            return false;
        }

        // compute commission
        $commission = $this->STClickCommission[$params['tier']];

        if($commission == '')
            $commission = 0;
        
        if($commission == '0') {
            $this->registratorLog(WLOG_DEBUG, "Click registration: Click commission is zero. Transaction not saved.", __FILE__, __LINE__);
        }
        
        return $commission;
    }
    
    //--------------------------------------------------------------------------
    
    function checkSpecialCommission($params)
    {
        //---------------------------------------
        // check if this user is not assigned in some special user commission category for this product category
        $sql = 'select cc.* from wd_pa_affiliatescampaigns ac, wd_pa_campaigncategories cc '.
            'where cc.campaignid='._q($this->CampaignID).
            '  and cc.campcategoryid=ac.campcategoryid'.
            '  and ac.rstatus='._q(AFFSTATUS_APPROVED).
            '  and ac.affiliateid='._q($params['userID']);
        $rs = QCore_Sql_DBUnit::execute($sql, __FILE__, __LINE__);

        if(!$rs)
            return false;
        
        if(!$rs->EOF)
        {
            if($this->CampaignCategoryID != $rs->fields['campcategoryid'])
            {
                // user is in different commission category, get the commission level
                $this->STClickCommission[$params['tier']] = $rs->fields['st'.$params['tier'].'clickcommission'];
                $this->registratorLog(WLOG_DEBUG, "Click registration: User ".$params['userID']." has special commission category with ID:".$rs->fields['campcategoryid'], __FILE__, __LINE__);
            }
        }
        else
        {
            // get commission from default commission category
            $sql = 'select * from wd_pa_campaigncategories '.
                   'where deleted=0 and campaignid='._q($this->CampaignID).
                   '  and name='._q(UNASSIGNED_USERS);
            $rs = QCore_Sql_DBUnit::execute($sql, __FILE__, __LINE__);
            if (!$rs || $rs->EOF)
                return false;  

            $this->STClickCommission[$params['tier']] = $rs->fields['st'.$params['tier'].'clickcommission'];
        }
        
        return true;
    }
    
    //--------------------------------------------------------------------------

    function getAllowedDomainsForDynamicLink()
    {
        $domains = trim($GLOBALS['Auth']->getSetting('Aff_dynamic_link_domains'));

        if ($domains == '') return false;
            
        $domains = explode("\n", $domains);
        
        if (count($domains) < 1) return false;
        
        foreach ($domains as $i => $d) {
            if (trim($d) == '') unset($domains[$i]);
        }
        
        return $domains;
    }
    
    //--------------------------------------------------------------------------

    function checkDynamicLinkUrl($destUrl)
    {
        if (($domains = $this->getAllowedDomainsForDynamicLink()) == false) return true;
       
        if(($pos = strpos($destUrl, "://")) !== false) $destUrl = substr($destUrl, $pos + 3);
        
        foreach ($domains as $domain) {
            if(($pos = strpos($domain, "://")) !== false) $domain = substr($domain, $pos + 3);
            $domain = trim($domain);
            
            if (strncmp($domain, $destUrl, min(strlen($domain), strlen($destUrl))) == 0) return true;
        }
        
        reset($domains);
        
        return current($domains);
    }
    
    //--------------------------------------------------------------------------
    
    function redirect($destUrl = '')
    {
        // if no POST variables are set, then only redirect
        if(count($_POST) == 0 || !extension_loaded('curl')) {
            if($this->settings['Aff_permanent_redirect'] == 1) {
                header("HTTP/1.1 301 Moved Permanently");
            }
/*
            if($this->BannerType == BANNERTYPE_POPUP || $this->BannerType == BANNERTYPE_POPUNDER)
            {
            ?>
                <script>
                  var TheNewDestWindow = window.open('<?php echo ($destUrl == '' ? $this->destinationURL : $destUrl)?>','TheDestPop','top=0,left=0,toolbar=1,location=1,directories=1,status=1,menubar=1,scrollbars=1,resizable=1');
                  TheNewDestWindow.focus();
                  window.close();
                </script>
            <?php                
            }
*/
            if($destUrl == '') {
                header('Location: '.$this->destinationURL);
                //echo "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0;URL=".$this->destinationURL."\">";
            }
            else {
                // check if the destination url is enabled
                if (($alllowedUrl = $this->checkDynamicLinkUrl($destUrl)) === true) {
                    Header('Location: '.$destUrl);
                } else {
                    Header('Location: '.$alllowedUrl);
                }
                //echo "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0;URL=".$destUrl."\">";
            }
        }
        else
        {
            // post whole content again using cURL and display returned value
            
            // prepare post fields
            $postfields = '';
            foreach($_POST as $key => $value)
            {
                if($key == PARAM_A_AID || $key == PARAM_A_BID)
                    continue;
                
                if($postfields != '')
                    $postfields .= '&';
                
                $postfields .= $key.'='.urlencode($value);
            }
            
            // make post call and display the result
            $ch = curl_init();
            if($destUrl == '')
                curl_setopt($ch, CURLOPT_URL, $this->destinationURL);
            else
                curl_setopt($ch, CURLOPT_URL, $destUrl);
            
            curl_setopt($ch, CURLOPT_VERBOSE, 0);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
            curl_exec($ch);
        }
    }
    
    //--------------------------------------------------------------------------
    
    function applyFraudProtection($ip, &$status)
    {
        if ($this->disableFraudProtection) return true;
        
        // find initial click (first non-declined within this day)
        $sql = "select dateinserted as aa from wd_pa_transactions ".
            "where transtype=".TRANSTYPE_CLICK.
            "  and transkind=".TRANSKIND_NORMAL." and ip="._q($ip).
            "  and rstatus<>".AFFSTATUS_SUPPRESSED.
            "  and accountid="._q($this->AccountID).
            "  and (".sqlTimeToSec(sqlNow())." - ".sqlTimeToSec('dateinserted')."<".$this->ClickFrequency.")";
        $ret = QCore_Sql_DBUnit::execute($sql, __FILE__, __LINE__);
        if(!$ret) {
            $this->registratorLog(WLOG_ERROR, "Click registration: (fraud protection) Error saving click", __FILE__, __LINE__);
            return false;
        }

        if(!$ret->EOF)
        {
            if($this->FrequentClicks == 2)
            {
                return false;
            }

            // decline the transaction 
            $status = AFFSTATUS_SUPPRESSED;
        }

        return true;
    }
    
    //------------------------------------------------------------------------
    
    function parseRotatorBannerDescription($desc)
    {
        if($desc == '') {
            return array();
        }
        
        $descArray = explode(',', $desc);
        $parsed = array();
        
        foreach($descArray as $descItem) {
            $banner = explode(';', $descItem);
            $parsed[$banner[0]] = array('all_imps'  => $banner[1],
                                        'uniq_imps' => $banner[2],
                                        'clicks'    => $banner[3],
                                        'rank'      => $banner[4]);
        }
        return $parsed;
    }
    
    //------------------------------------------------------------------------
    
    function encodeRotatorBannerDescription($banners)
    {
        if (count($banners) == 0) {
            return '';
        }
        
        $desc = '';
        foreach ($banners as $bannerID => $bannerData) {
            $desc .= ($desc == '' ? '' : ',').$bannerID.';'.implode(';', $bannerData);
        }
        
        return $desc;
    }
    
    //--------------------------------------------------------------------------
    
    function updateRotatorStatistics($id) {
        $banners = $this->parseRotatorBannerDescription($this->description);
        $banners[$id]['clicks']++;
        $this->description = $this->encodeRotatorBannerDescription($banners);
        
        $sql = 'update wd_pa_banners set description='._q($this->description).' where bannerid='._q($this->BannerID);
        $rs = QCore_Sql_DBUnit::execute($sql, __FILE__, __LINE__);
        if (!$rs) {
            $this->registratorLog(WLOG_DEBUG, "Registrator: Error updating rotator banner '$this->BannerID' statistics", __FILE__, __LINE__);
            return false;
        }
        return true;
    }
}
?>
