<?php

/**
* @desc This class will update the country info for each record in the main profile table.
*/
if(!defined('APP_INCLUDE')){ die('invalid inclusion'); }

class UpdateCountries {
    
    var $showprogress = false;
    
    function __construct() {
        global $gi;
        set_time_limit(10000);
        #check to see if geoip is loaded
		if (!isset($gi)) {
            $geopath = logaholic_dir();
            //echo logaholic_dir()."/components/geoip/open_geoip.php";
			include_once(logaholic_dir()."/components/geoip/open_geoip.php");
		}
        if (!isset($gi)) {
                echo "GeoIP functions not loaded! We can't do anything without them.";    
                die();
        }
        //ob_start(); 
    }
    function UpdateCountries() {
        $this->__construct();    
    }
    
    # call this function if you want to update part of the database, based on a date range
    function UpdateRange($from,$to) {
        global $profile, $db, $gi;
        $q = "select group_concat(id) visitorid, ipnumber from $profile->tablename_visitorids where created between ".$db->Quote($from) ." and ".$db->Quote($to) ." group by ipnumber"; 

        $results = $db->Execute($q);
        $n = $results->NumRows();
        $this->Progress("Checking a total of $n IP addresses");


        $i=0; $updated=0; $last_progress=-1; $unknown=0;
        while ($data=$results->FetchRow()) {
            $data['visitorid'] = "'".str_replace(",","','",$data['visitorid'])."'";
            if (is_numeric(substr($data["ipnumber"],-1))) {
                # get the current country code from geoip and compare it to what we have in the database for this ip
                if (function_exists('encodeSPQR')) { $data["ipnumber"] = decodeSPQR($data["ipnumber"]); }
                try {
                    $area = $gi->city($data["ipnumber"]);
                    $cc = $area->country->isoCode;
                } catch (Exception $e) {
                    $area = [];
                    $cc = '';
                    $unknown++;
                }
                $dbc = $this->GetCountry($data['visitorid'],$from,$to);
                if ($dbc===false) {
                    # visitorid was not found in the main table, it has probably been removed (or put in the crawl table). In any case, skip it here
                } else if ($cc!=$dbc) {
                    # the country is different, lets update the database
                    $uq = "update $profile->tablename set country = ".$db->Quote($cc)." where visitorid IN ({$data["visitorid"]}) and timestamp between ".$db->Quote($from) ." and ".$db->Quote($to);
                    $db->Execute($uq);
                    $updated++;
                }
            }
            $i++;
            if ($this->showprogress == true) {
                $progress = number_format((($i / $n)*100),0);
                if ($progress!=$last_progress) {
                    $this->Progress("$progress");
                    $last_progress = $progress;
                }
            }
        }
        $this->Progress("Done! Updated $updated entries out of a total of $n.");
    }
    
    # call this function if you want to update the entire database
    function UpdateAll() {
        global $profile;
        $daterange = GetMaxDateRange($profile);
        $this->UpdateRange($daterange['from'],$daterange['to']);     
    }
    
    # call this function if you want to display a progress indicator
    function DisplayProgress() {
        global $profile;
        $this->showprogress = true;
        $this->Progress("Update Geographic Location information for '$profile->profilename'. This process can take a while.");
    }
    
    private function Progress($string) {
        echo "data: ". $string . PHP_EOL;
        echo PHP_EOL;
        //ob_flush();
        flush();
        //lgflush(); 
    }
    
    private function GetCountry($vid,$from,$to) {
        global $db, $profile;
        $q  = "select country from $profile->tablename where visitorid IN ($vid) and timestamp between ".$db->Quote($from) ." and ".$db->Quote($to) ." limit 1";
        $r = $db->Execute($q);
        if ($data=$r->FetchRow()) {
            return $data['country'];
        } else {
            return false;
        }
    }

   
}

?>

