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

class Affiliate_Scripts_Bl_BannerViewerCache extends Affiliate_Scripts_Bl_BannerViewerOptimized
{
    var $blockimps, $blockimps_time, $blockimps_timeunit;
    var $ip, $referer, $time;
    var $cache;
    var $timeStarted, $maxTimeToRun;
    
    //--------------------------------------------------------------------------
    function setCache($cache) {
        $this->cache = $cache;
    }
    
    //--------------------------------------------------------------------------
    
    function process() {
        // log in to database
        $dbObj =& QUnit_Global::newObj('QUnit_Sql_DbConnectionMysql', DB_HOSTNAME,DB_USERNAME,DB_PASSWORD,DB_DATABASE);
        $GLOBALS['db'] = $dbObj->getConnection();
        $GLOBALS['db']->Execute("SET NAMES 'utf8'");
        $GLOBALS['dbrequests'] = 1;
        $this->setDb($dbObj);
        
        return parent::process();
    }
    
    //--------------------------------------------------------------------------
    
    function saveImpression($bannerID) {
        $data = $this->bannerType.';'.
                $this->sourceURL.';'.
                $this->logLevel.';'.
                $this->debugImps.';'.
                $this->getSetting('Aff_blockimps').';'.
                $this->getSetting('Aff_blockimps_time').';'.
                $this->getSetting('Aff_blockimps_timeunit').';'.
                $this->commissionType.';'.
                $this->CampaignID;

        $this->cache['input']->replace($bannerID.';'.$this->UserID, $data);  
        if (preg_replace('/[\'\"]/', '', $_GET[PARAM_A_AID]) != $this->UserID) {
            $this->cache['refid_userid']->replace(preg_replace('/[\'\"]/', '', $_GET[PARAM_A_AID]), $this->UserID);
        }
        
        if($this->blockimps == '1') {
            if(isset($_COOKIE[COOKIE_NAME.'blockimps'])) {
                return false;
            } else {
                if(($blockTime = $this->blockimps_time) && ($blockTimeUnit = $this->blockimps_timeunit)) {
                    switch($blockTimeUnit) {
                        case 1:
                            $expireTime = time() + $blockTime * 3600;
                            break;
                        case 2:
                            $expireTime = time() + $blockTime * 60;
                            break;
                        case 3:    
                        default:
                            $expireTime = time() + $blockTime;
                            break;                            
                    }
                    setcookie(COOKIE_NAME.'blockimps', time(), $expireTime, '/');  
                }          
            }
        }
        
        $rotator = ($this->bannerType == BANNERTYPE_ROTATOR);
        if ($rotator) {
            $this->processRotatorBanner();
        }

        // save impression to cache
        $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
        $data = $_SERVER['REMOTE_ADDR'].';'.
                time().';'.
                $this->BannerID.';'.
                $this->UserID.';'.
                $this->AccountID.';'.
                $this->extraData1.';'.
                $this->commissionType.';'.
                $this->CampaignID.';'.
                $referer.';'.
                (($_COOKIE[COOKIE_NAME.'imp'] == '') ? 1 : 0).';'.
                $this->rotatorID;

        $this->cache['output']->replace(uniqid('imp_'), $data);

        setcookie(COOKIE_NAME.'imp', time(), time() + 3650*86400, '/');
        
        return true;
    }
    
    //--------------------------------------------------------------------------
    
    function getUnprocessedFile() {
        $files = array();
        if ($dir = @opendir(CACHE_PATH)) {
            while (($file = readdir($dir)) !== false) {
                if((strstr($file, SB_OUTPUT_CACHE_FILENAME) !== false) && ($file !== SB_OUTPUT_CACHE_FILENAME)) {
                    $files[] = $file;
                }
            } 
            closedir($dir);
        }
        if (count($files) != 0) {
            sort($files);
            reset($files);
            if ($files[0] != '') {
               return $files[0];
            }
        }
        return false;
    }
    
    //--------------------------------------------------------------------------
    
    function processFile($file) {
        $cache = new Cache(CACHE_PATH.$file);
        if($cache->open() === false) {
            $this->writeHistory(WLOG_ERROR, 'Error opening sb output cache file '.CACHE_PATH.$file, __FILE__, __LINE__);
            return false;
        }
        
        $cache->reset();
        while ($data = $cache->getNextValueAndDelete()) {
            $data = explode(';', $data);
            $this->ip = $ip       = $data[0];
            $this->time = $time   = $data[1];
            $this->BannerID = $bannerID = $data[2];
            $this->UserID         = $data[3];
            $this->AccountID      = $data[4];
            $this->extraData1     = $data[5];
            $this->commissionType = $data[6];
            $this->CampaignID     = $data[7];
            $this->referer        = $data[8];
            $uniqueImp            = $data[9];
            $this->rotatorID      = $data[10];
            
            // geo-targetting check
            $country['__'] = array("countrycode" => '__', "countryname" => 'Unknown');
    
            if($this->getSetting('Glob_acct_geo_allowed') == '1') {
                $country = $this->getCountryForIp($ip);
                if(!$this->isAllowedCountry($country) && ($this->getSetting('Glob_acct_geo_dont_register_imp') == '1')) {
                    $this->writeHistory(WLOG_DEBUG, "Impression registration: Country from IP '$ip' is not in list of allowed countries", __FILE__, __LINE__);
                    continue;
                }
            }
        
            $hourDate = date('Y-m-d H:00:00', $time);

            // get impression record for this hour
            $sql = "select impressionid, all_imps_count, unique_imps_count from wd_pa_impressions ".
                "where bannerid='".addslashes($bannerID)."' and affiliateid='".addslashes($this->UserID)."'".
                "  and dateimpression='".addslashes($hourDate)."'".
                "  and country='".addslashes($country['countrycode'])."'".
                "  and accountid='".addslashes($this->AccountID)."'".
                "  and commissiongiven=0".
                "  and data1='".addslashes($this->extraData1)."'";
            if ($this->rotatorID != '') {
               $sql .= "  and rotatorid="._q($this->rotatorID);
            }

            $rs = $this->db->query($sql);
            if(!$rs)
            {    
                $this->writeHistory(WLOG_ERROR,"Show banner: Error getting last impression", __FILE__, __LINE__);
                continue;
            }
            if(!($row = $rs->FetchRow()))
            {
                // insert record
                $impressionID = $this->db->createUniqueId();
                //$impressionID = QCore_Sql_DBUnit::createUniqueID('wd_pa_impressions', 'impressionid');
                $sql = "insert into wd_pa_impressions(impressionid,dateimpression,".
                        "accountid,bannerid,rotatorid,affiliateid,all_imps_count,unique_imps_count, commissiongiven, data1, country)".
                        "values('".addslashes($impressionID)."','".addslashes($hourDate).
                        "','".addslashes($this->AccountID)."','".addslashes($this->BannerID)."','".addslashes($this->rotatorID).
                        "','".addslashes($this->UserID)."',1,1,0,'".addslashes($this->extraData1).
                        "','".addslashes($country['countrycode'])."')";
    
                $ret =& $this->db->query($sql);
                if (!$ret)
                {
                    $this->writeHistory(WLOG_ERROR,"Show banner: Error saving impression", __FILE__, __LINE__);
                    continue;
                }
            }
            else
            {
                $allImps = $row['all_imps_count'] + 1;
                $uniqueImps = $row['unique_imps_count'];
                $ipmId = $row['impressionid'];
                
                if($uniqueImp) {
                    $uniqueImps++;
                }
                
                // update record
                $sql = "update wd_pa_impressions ".
                    " set all_imps_count='".addslashes($allImps)."'".
                    ", unique_imps_count='".addslashes($uniqueImps)."'".
                    " where impressionid='".addslashes($ipmId)."'";

                $ret =& $this->db->query($sql);                
                if (!$ret)
                {
                    $this->writeHistory(WLOG_ERROR, "Show banner: Error saving impression", __FILE__, __LINE__);
                    continue;
                }
            }

            if($this->commissionType & TRANSTYPE_CPM) {
                $this->updateCPMCommission();
            }
          
            // check if we have enough time  
            if (microtime_diff($this->timeStarted, microtime()) > $this->maxTimeToRun) {
                $cache->close();
                return false;
            }

        }
        
        $cache->clearAndClose();
        return true;
    }
    
    //--------------------------------------------------------------------------
    
    function createCopy() {
        if(!file_exists(CACHE_PATH.SB_OUTPUT_CACHE_FILENAME)) {
            return false;
        }
        $filename = 'unpr_'.time().'_'.rand(1, 100).'_'.SB_OUTPUT_CACHE_FILENAME;
        @rename(CACHE_PATH.SB_OUTPUT_CACHE_FILENAME, CACHE_PATH.$filename);
        return true;
        
    }
    
    //--------------------------------------------------------------------------
    
    function saveImpressionFromCache() {
        $this->timeStarted = microtime();
        $this->maxTimeToRun = (ini_get('max_execution_time') == '') ? 20 : ini_get('max_execution_time') - 10; 
        
        while (microtime_diff($this->timeStarted, microtime()) < $this->maxTimeToRun) {
            if(($file = $this->getUnprocessedFile()) !== false) {
                if($this->processFile($file) == false) {
                    return;
                }
            } else {
                $this->createCopy();
            }
        }
    }
    
    function saveRotatorDescFromCache() {
        $timeStarted = microtime();
        $maxTimeToRun = (ini_get('max_execution_time') == '') ? 20 : ini_get('max_execution_time') - 10; 
        
        $this->cache['rotator_desc']->reset();
        while ($data = $this->cache['rotator_desc']->getNextKeyValueAndDelete()) {
            $bannerID = $data['key'];
            $description = $data['value'];
            $bannerData = $this->getBannerData($bannerID);
            if ($bannerData['destinationurl'] == '') {
                $this->updateDescriptionArg($bannerID, $description);
                continue;
            }
            
            $cacheBanners = $this->parseRotatorBannerDescription($description);
            $dbBanners = $this->parseRotatorBannerDescription($bannerData['description']);
            
            if ((($bannerData['destinationurl']+0) & ROTATOR_CONTENT_CHANGE) !== 0) {
                foreach ($cacheBanners as $id => $value) {
                    if (key_exists($id, $dbBanners) === false) {
                        unset($cacheBanners[$id]);
                    }
                }
                foreach ($dbBanners as $id => $value) {
                    if (key_exists($id, $cacheBanners) === false) {
                        $cacheBanners[$id] = $value;
                    }
                }
            }
            if ((($bannerData['destinationurl']+0) & ROTATOR_RESET_STATS) !== 0) {
                foreach ($cacheBanners as $id => $value) {
                    $cacheBanners[$id]['all_imps'] = 0;
                    $cacheBanners[$id]['uniq_imps'] = 0;
                    $cacheBanners[$id]['clicks'] = 0;
                }
            }
            if ((($bannerData['destinationurl']+0) & ROTATOR_RESET_RANK) !== 0) {
                foreach ($cacheBanners as $id => $value) {
                    $cacheBanners[$id]['rank'] = $dbBanners[$id]['rank'];
                }
            }
            
            $this->updateDescriptionArg($bannerID, $this->encodeRotatorBannerDescription($cacheBanners), true);
            
            // check if we have enough time  
            if (microtime_diff($timeStarted, microtime()) > $maxTimeToRun) {
                return false;
            }

        }
        $this->clearDestinationUrls();
        $this->cache['rotator_desc']->clear();
    }
    
    //--------------------------------------------------------------------------
    
    function saveLogFromCache() {
        $timeStarted = microtime();
        $maxTimeToRun = (ini_get('max_execution_time') == '') ? 20 : ini_get('max_execution_time') - 10;
        
        $this->cache['log']->reset();
        while ($data = $this->cache['log']->getNextValueAndDelete()) {
            $data = explode(';', $data);
            $ip                 = $data[0];
            $time               = $data[1];
            $type               = $data[2];
            $text               = $data[3];
            $file               = $data[4];
            $line               = $data[5];
            $accountId          = $data[6];
            
            $historyid = $this->db->createUniqueId();
            $sql = "insert into wd_g_history set ".
                    "historyid = '".addslashes($historyid)."',".
                    "rtype = '".addslashes($type)."',".
                    "accountid = '".$accountId."',".
                    "value = '".addslashes($text)."',".
                    "dateinserted = '".$this->db->getDateString($time)."',".
                    "hfile = '".addslashes($file)."',".
                    "line = '".addslashes($line)."',".
                    "ip = '".addslashes($ip)."'";                          
            $ret =& $this->db->query($sql);
            
            // check if we have enough time  
            if (microtime_diff($timeStarted, microtime()) > $maxTimeToRun) {
                return false;
            }
        }
        $this->cache['log']->clear();
    }
    
    //--------------------------------------------------------------------------

    function saveCPMCommission()
    {
        // first save commission
        if(($commission = $this->getCommission()) === false) return false;


        $remoteAddr = $this->referer;
        $ip = $this->ip;
        $status = AFFSTATUS_APPROVED;
        
        $TransID = $this->db->createUniqueId();
        $sql = "insert into wd_pa_transactions ".
            "(transid, accountid, affiliateid, campcategoryid, bannerid,".
            " dateinserted, transtype, transkind, refererurl,".
            " ip, rstatus, commission)".
            "values('".addslashes($TransID)."','".addslashes($this->AccountID).
            "','".addslashes($this->UserID)."','".addslashes($this->CampaignCategoryID).
            "','".addslashes($this->BannerID)."','".$this->db->getDateString($this->time).
            "',".TRANSTYPE_CPM.",".TRANSKIND_NORMAL.",'".addslashes($remoteAddr).
            "','".addslashes($ip)."','".addslashes($status)."','".addslashes($commission)."')";

        $ret =& $this->db->query($sql);
        if (!$ret)
        {
            $this->writeHistory(WLOG_ERROR, "Show banner: Error saving CPM commission", __FILE__, __LINE__);
            return false;
        }

        $this->writeHistory(WLOG_DEBUG, "Banner Viewer: Created CPM commission with ID '$TransID'", __FILE__, __LINE__);
                
        //------------------------------------------------
        // now change impression status to commissiongiven=1
        $sql = "select bannerid from wd_pa_banners where campaignid='".addslashes($this->CampaignID)."'";
        $rs =& $this->db->query($sql);
        if(!$rs)
        {    
            $this->writeHistory(WLOG_ERROR, "Show banner: Error getting banner ID by campaign", __FILE__, __LINE__);
            return false;
        }
        
        $bannerIDs = array();
        while($row = $rs->FetchRow())
        {
            $bannerIDs[] = $row['bannerid'];            
        }

        $chunkedBannerIDs = sb_array_chunk($bannerIDs, WD_MAX_PROCESSED_IDS);
        
        foreach($chunkedBannerIDs as $bannerIDsArray)
        {
            $bannerIDSql = "('".implode("','", $bannerIDsArray)."')";
            
            $sql = 'update wd_pa_impressions set commissiongiven=1'.
                   ' where bannerid in '.$bannerIDSql.
                   "   and accountid='".addslashes($this->AccountID)."'".
                   "   and affiliateid='".addslashes($this->UserID)."'";

            $rs =& $this->db->query($sql);
            if (!$rs)
            {
                $this->writeHistory(WLOG_ERROR, "Show banner: Error changing impression status to commissiongiven=1", __FILE__, __LINE__);
                return false;
            }
        }
        
        return true;
    }
       
    //--------------------------------------------------------------------------
	
	function processRotatorBanner() {
	    if(($subBannerDesc = $this->cache['rotator_desc']->getData($this->BannerID)) !== false) {
            $this->description = $subBannerDesc;
        }
	    
	    $banners = $this->parseRotatorBannerDescription($this->description);
	    if(count($banners) == 0) {
	        return;
	    }
	    $id = $this->getBannerToShow($banners);
        
        if(($bannerData = $this->getBannerData($id)) === false) {
            return false;
        }
       
        $specialDestUrl = $_REQUEST[PARAM_DESTURL];
        $params = array();
        $params['Affiliate_id'] = urlencode($this->UserID);
        $params['Affiliate_refid'] = urlencode($this->User_refid);
        $params['Affiliate_name'] = urlencode($this->User_name.' '.$this->User_surname);
        $params['Affiliate_username'] = urlencode($this->User_username);
        
        $clickUrlOnly = $this->getClickUrl($bannerData['destinationurl'], $params);
        
        $code = $this->getBannerCode($clickUrlOnly, $bannerData['bannertype'], $bannerData['bannerid'], $bannerData['sourceurl'], $bannerData['description'], $params, $specialDestUrl);
        if ($bannerData['bannertype'] == BANNERTYPE_POPUNDER || $bannerData['bannertype'] == BANNERTYPE_POPUP) {
            $this->rotatorOutput = $code;
        } else {
	        $this->rotatorOutput = "document.write('".str_replace("'", '"', $code)."');";
        }
	    
	    $banners = $this->updateStatistics($banners, $id);
	    if ($this->sourceURL != SELFOPTIMIZATION_NONE) {
	       $banners = $this->optimizeRotatorBanner($banners);
        }
        
        $this->description = $this->encodeRotatorBannerDescription($banners);
        
        $this->cache['rotator_output']->replace($this->UserID.'_'.$this->BannerID.'_'.$id, $this->rotatorOutput); 
        $this->cache['rotator_desc']->replace($this->BannerID, $this->description);
        
        $this->rotatorID = $this->BannerID;
        $this->checkBannerExists($id);
	}
   
}
?>
