<?php

function HandleInputArguments(){
	global $conf, $running_from_command_line, $argv, $argc, $force, $movedone, $debug, $delfile, $manage_keys, $check_file_history;
	
	# For realtime refresh mode, we may need to take a nap once in a while
	if (isset($_GET['sleep'])) {
		$rand = rand(0,6);
		sleep($rand);
	}
	
	$conf = @$_GET["conf"]; 
	
	if (!isset($running_from_command_line)) {
		$running_from_command_line = false;
	}
	
	# In case we do a simple command line options of profilename 
	if (!$conf) {
		if (isset($argv[1])) {
			if ($argv[1] == "running_from_command_line") {
				$conf = $argv[2];
			} else {
				if (strpos($argv[1],"=") !== FALSE) {
					# If we've passed in a command line, push it into the $_GET section this mean we can support name=value pairs as command line options
					if (@$argc > 0) {
						for ($i = 1; $i < $argc; $i++) {
							$a = filter_var($argv[$i], FILTER_SANITIZE_URL);
							parse_str($a, $tmp);
							$_REQUEST = array_merge($_REQUEST, $tmp);
						}
						$conf = @$_REQUEST["conf"];
					}
				} else {
					$conf = $argv[1];
				}
			}
			if (isset($_REQUEST['dbid'])) { $_GET['dbid'] = $_REQUEST['dbid']; }
			
			$running_from_command_line = true;
		} else {
			# attempt to read piped input
			$stdin_stream = fopen('php://stdin', 'r');
			if (is_resource($stdin_stream)) {
				stream_set_blocking($stdin_stream, 0); # should be necessary, but just in case
				if ($line = fgets($stdin_stream, 1024)) {
					parse_str(trim($line), $tmp);
					$_REQUEST = array_merge($_REQUEST, $tmp);
					$conf = @$_REQUEST["conf"];
					$running_from_command_line = true;
				}
				fclose($stdin_stream); # shouldn't be necessary, but we'll do it anyway
			}
		}
	} 

	if (isset($_REQUEST["manage_keys"])) {
		//echo " manage keys ...";
		if(((int)$_REQUEST["manage_keys"]) === 1){
			//echo "True manage keys";
			$manage_keys = true;
		} else {
			$manage_keys = false;
		}
	} else {
		$manage_keys = true;
	}

	if (isset($_REQUEST["force"])) {
		$force = true;
	} else {
		$force = false;
	}

	if (isset($_REQUEST["check_file_history"])) {
		$check_file_history = true;
	}

	if (isset($_REQUEST["movedone"])) {
		$movedone = true;		
	} else {
		$movedone = false;
	}
	
	# if delfile is true, the original log file will be deleted after it's been processed
	if (isset($_REQUEST["delfile"]) && $_REQUEST["delfile"] === 'true') {
		$delfile = true;
	} else {
		$delfile = false;
	}
	
	$debug = "";
	if (@$_REQUEST["debug"]) {
		$debug = $_REQUEST["debug"];
	}
	
	if (PHP_SAPI === 'cli') {
		$running_from_command_line = true;
	} else if (PHP_SAPI === 'cgi-fcgi' && empty($_SERVER['REMOTE_ADDR'])) {
		$running_from_command_line = true;
	}
	
}


function OverrideOptions() {
	global $profile;

	if (isset($_REQUEST['logfilefullpath'])) {
		$profile->original["logfilefullpath"] = $profile->logfilefullpath;
		$profile->logfilefullpath = $_REQUEST['logfilefullpath'];
	}
	if (isset($_REQUEST['splitlogs'])) {
		$profile->original["splitlogs"] = $profile->splitlogs;
		$profile->splitlogs = $_REQUEST['splitlogs'];
	}
	if (isset($_REQUEST['recursive'])) {
		$profile->original["recursive"] = $profile->recursive;
		$profile->recursive = $_REQUEST['recursive'];
	}
	if (isset($_REQUEST['splitfilter'])) {
		$profile->original["splitfilter"] = $profile->splitfilter;
		$profile->splitfilter = $_REQUEST['splitfilter'];
	}
	if (isset($_REQUEST['splitfilternegative'])) {
		$profile->original["splitfilternegative"] = $profile->splitfilternegative;
		$profile->splitfilternegative = $_REQUEST['splitfilternegative'];
	}
	if (isset($_REQUEST['skipips'])) {
		$profile->original["skipips"] = $profile->skipips;
		$profile->skipips = $_REQUEST['skipips'];
	}
	if (isset($_REQUEST['skipfiles'])) {
		$profile->original["skipfiles"] = $profile->skipfiles;
		$profile->skipfiles = $_REQUEST['skipfiles'];
	}
	if (isset($_REQUEST['urlparamfilter'])) {
		$profile->original["urlparamfilter"] = $profile->urlparamfilter;
		$profile->urlparamfilter = $_REQUEST['urlparamfilter'];
	}
	if (isset($_REQUEST['urlparamfiltermode'])) {
		$profile->original["urlparamfiltermode"] = $profile->urlparamfiltermode;
		$profile->urlparamfiltermode = $_REQUEST['urlparamfiltermode'];
	}
	if (isset($_REQUEST['googleparams'])) {
		$profile->original["googleparams"] = $profile->googleparams;
		$profile->googleparams = $_REQUEST['googleparams'];
	}
}

function restoreOriginalOptions(){
	global $profile;
	if (empty($profile->original)) {
		return;
	}
	foreach ($profile->original as $key => $value) {
        $profile->$key = $value;
    }
}

function HandleRunningStatus($mode = 'regular') {
	global $conf, $profile, $running_from_command_line, $lang, $validUserRequired, $session, $template;
	
	if (isset($_REQUEST['reset']) && $_REQUEST['reset'] == 1) {
		$profile->SetUpdateStatus('ready');
	}
	
	$running = $profile->GetUpdateStatus(); 
	//echo "my running status is $running ($profile->profileid)";
	//exit();
	
	if ($running == "running") {
		# we're already running, warn usere		
		$button = Button("update.php?conf=$conf&amp;reset=1", _RESET_STATUS_AND_CONTINUE , "color: black;");
		$out = Notice(_HANDLE__UPDATE_RUNNING_STATUS_WARNING_PART1 . " '$conf' ". _HANDLE__UPDATE_RUNNING_STATUS_WARNING_PART2 . "<br><br>$button\n\n");
		
		
		if ($running_from_command_line == true) {
			echoConsoleSafe($out, true);		
			echo "from the console, use this to reset:\n> php update.php \"conf=$conf&reset=1\"\n";
		} else {
			$res = array("Status" => "Error", "Message" => $out);
			echo json_encode($res);
		}
		
		return false;
	}
	
	$profile->SetUpdateStatus('running');
}


function reset_update_process(){
	global $mysqltmp,$profile;
	
	#True == reset update_running to no
	
	if($profile->GetUpdateStatus() == "ready" ){
		return false;
	}	
	
	$log_file = "{$mysqltmp}{$profile->profilename}_lwa_log";
	if(file_exists($log_file)){
		$last_process = filemtime($log_file);	
		if((time() - $last_process) > 86400 ){
			return true;
		}
	} else {	
		# Get the last action's timestamp
		$last_update_finished = $profile->last_update_finished;
	 	if((time() - $last_update_finished) > 86400) {
		 	return true;
		}	
	}
	# Return false if the file is still in progress
	return false;
}

# this function will change the user the script is currently running as to cpanelloghaolic, so we can write our files as the correct user
function asCpanelLogaholic() {
    global $profile;
    
    if (@_LOGAHOLIC_EDITION == 4 || LOGAHOLIC_BASE_EDITION == "cPanel Edition") {
        # if we are running as root, change the user to cpanellogaholic     
        $userinfo = posix_getpwuid(posix_getuid());
        if ($userinfo['name'] == "root") {
            
            if(!empty($profile) && file_exists($profile->logfilefullpath)){
                # proposed fix: sometimes the log file we want to read is 640, normally it's 644. We need to make sure it's 644 before we give up root privs
                chmod($profile->logfilefullpath, 0644);
            }
        
            $cpuser = posix_getpwnam("cpanellogaholic");
            if (posix_setgid($cpuser['gid'])==true) {
                //echo "running as cpanellogaholic group\n";
                if (posix_setuid($cpuser['uid'])==true) {
                    //echo "running as cpanellogaholic\n";
                }
            } else {
                //echo "failed to change user to cpanellogaholic\n";
            }
        }
    }
}

# this function will run the reports with an update function, thuis creating the datafiles ofr the relevant date range
function UpdateDatafiles($last_inserted_time) {	
	global $profile,$import,$reports;

	# If there has been no update before, set the last update time to zero, so we always create data files.
	$last_report_update = $profile->lastReportUpdate;

	$days_since_update = (time() - $last_report_update) / 86400;

	if($days_since_update >= 1) {

		$profile->lastReportUpdate = time();
		
		foreach($reports as $k => $v){
			
			if($v['Distribution'] == 'Unlisted') {
				continue;
			}
			
			if(isset($v["Update"]) && $v["Update"] === false) {
				continue;
			}
			
			$r = new $reports[$k]["ClassName"]();
			$r->label = constant($k);

			$r->from = mktime(0, 0, 0, date("m", $import->oldest_timestamp), date("d", $import->oldest_timestamp), date("Y", $import->oldest_timestamp));
			$r->to = mktime(23, 59, 59, date("m", $last_inserted_time), date("d", $last_inserted_time), date("Y", $last_inserted_time));

			if($r->UpdateStats()) {
				# ok update stats has run
			}

		}
		
	} else {
		# We should not create data files
		// echoNotice("We should not create data files");
	}	
}

#this function will move analyzed log files to a "done" directory
function MoveDone($files) {
	global $profile;
	
	# do a seperate loop after the update so we relocate all the files to the done folder
	foreach($files as $file) {		
		if(is_dir($profile->logfilefullpath)) {
			$at = $profile->logfilefullpath.str_replace($profile->logfilefullpath, '', $file);
			# Skip done dir
			if(strpos($at, "done") !== false){
				continue;
			}
			$donefile = $profile->logfilefullpath.'done/'.str_replace($profile->logfilefullpath, '', $file);
			if(is_dir($file) && !file_exists($donefile)){
				# Create dir set permissions and create the full path
				mkdir($donefile, 0777, true);
				continue;
			} else if (!is_dir($file)) {
				$fp = str_replace($profile->logfilefullpath, '', $file);

				$x = explode("/", $fp);
				$fname = $x[count($x) - 1];
				unset($x[count($x) - 1]);
				$donefile = implode("/", $x)."/".$fname;
				unset($x, $fname);		
				$donefile = $profile->logfilefullpath.'done/'.$donefile;				

			}
		} else {
			$at = $file;
			$x = explode("/", $file);
			$fname = $x[count($x) - 1];
			unset($x[count($x) - 1]);
			$donefile = implode("/", $x).'/done/'.$fname;
			unset($x, $fname);
		}

		if(!is_dir($at)){			
			if (rename("{$at}", "{$donefile}")) {
				echoConsoleSafe(_MOVED_FILE_TO." $donefile<P>\n", true);
			} else {
				echoConsoleSafe("<span style='color: #F00;'>".str_replace("%s2", $donefile, str_replace("%s1", $at, _MOVING_OF_LOG_FILE_FAILED_DONE_NOT_WRITABLE))."</span>");
			}
		}
	}
}

function PrepareUrlParamFilter() {
	global $profile,$errorHandler;

	if(empty($profile->urlparamfilter)) {
		return "";
	}

	# Prepare the filter by removing linebreaks and spaces from the filter
	$regex_urlparamfilter = preg_replace("/ /i", "", $profile->urlparamfilter);

	$regex_urlparamfilter = preg_replace("/\r\n|\r|\n/",",", $regex_urlparamfilter);	# remove line breaks
	$regex_urlparamfilter = preg_replace("/,,|,/","|", $regex_urlparamfilter);			# remove comma's
	
	# Create our filter regex by replaceing commas with pipes
	$regex_urlparamfilter = '(\?|\&|\b)' . $regex_urlparamfilter . '=';
	$regex_urlparamfilter = preg_replace("/,/i", "=|(\?|\&|\b)", $regex_urlparamfilter);


	# Test if the regex is invalid
	if(@preg_match("/({$regex_urlparamfilter})/i", null) === false){
		echoWarning($errorHandler->error_msg . "<br/>- " . _STRIP_URL_PARAMS . ": <strong>" . $profile->urlparamfilter ."</strong><br/>" ,"margin:10px;" );
		return "";	
	} else {
		return $regex_urlparamfilter;
	}
}

function PrepareEquivDomainFilter() {
	global $profile;
	# Create the regex for equivdomains
	$regex_equivdomains="";
	if (!empty($profile->equivdomains)) {
		if(substr($profile->equivdomains, 0, 1) == '(') {
			$regex_equivdomains = $profile->equivdomains;
		} else {
			$equivdomains = str_replace(" ", "", str_replace(",", "|", $profile->equivdomains));
			$equivdomains = explode("|", $equivdomains);
			foreach($equivdomains as $key => $val) {
				$equivdomains[$key] = '://'.$val;
			}
			$regex_equivdomains = implode("|", $equivdomains);
		}
		$regex_equivdomains = str_replace('/', '\/', $regex_equivdomains);
	}
	return $regex_equivdomains;
}

# this function will loop through the updatehistory array and check all files for expiry. It will clean up elements in the array that are no longer relevant.
// function CleanupHistory() {
// 	global $profile, $reports;
	
// 	# where should we start? get the min value from all the arrays
// 	$min = $max = date("Ymd", time());

// 	$records = 0;

// 	foreach ($profile->updatehistory as $run_date => $affected_dates) {
// 		foreach ($affected_dates as $date) {
// 			if ($date < $min) {
// 				$min = $date; 
// 			}
// 			if ($date > $max) {
// 				$max = $date;
// 			}
// 			$records ++;
// 		}
// 	}

// 	$start_year = substr($min, 0,4);
// 	$end_year = substr($max, 0,4);
	
// 	$hits = [];

// 	while ($start_year <= $end_year) {
	
// 		$path = $profile->datamanagerDir.$profile->profilename."/reports/$start_year";	
	
// 		if(DATAFILE_METHOD == "ziparchive"){	
// 			$files = glob($path."/*.zip");
// 			if (!is_array($files)) {
// 				$start_year++;
// 				continue;
// 			}
// 			foreach($files as $file) {

// 				# first lets check if we actually need to check the report zip
// 				$label = explode("/",$file);
// 				$label = end($label);
// 				$label = str_replace(".zip", "",$label);
// 				if(isset($reports[$label]['DeleteOutdatedFiles']) && $reports[$label]['DeleteOutdatedFiles'] === false){
// 					continue;
// 				}

// 				$zip = new zipArchive;
// 			    if ($zip->open($file) == TRUE) {
// 			    	$i=0;
// 			        while ($info = $zip->statIndex($i)) {
// 			        	$i++;
// 			        	$data_date = explode(".", $info['name']);
// 			        	$data_date = $data_date[1];
// 			        	$file_create_date = $info['mtime'];

// 			            foreach ($profile->updatehistory as $run_date => $affected_dates) {			            	
// 			            	if(in_array($data_date, $affected_dates)) {
// 			            		# this is a suspect date
// 			            		if ($file_create_date < $run_date) {
// 			            			if($records > 200){
// 				            			$zip->deleteName("/$file");
// 		            				} else {
// 		            					@$hits[$run_date]++;
// 		            				}

// 			            		}
// 			            	}
// 			            }
// 			        }
// 			    }
// 			}
// 		} else {
// 			$files = glob("{$path}/*/*.json.gz");
// 			if (!is_array($files)) {
// 				$start_year++;
// 				continue;
// 			}
// 			foreach ($files as $datafile) {
// 				# We only need the filename here so break off the path
// 				$fileparts = explode("/", $datafile);
// 				$file = end($fileparts);

// 				# Now we have the file lets see the date
// 				$data_date = explode(".", $file);

// 				# first lets check if we actually need the report
// 				if(isset($reports[ $data_date[0] ]['DeleteOutdatedFiles']) && $reports[ $data_date[0] ]['DeleteOutdatedFiles'] === false){
// 					continue;
// 				}

// 	        	$data_date = $data_date[1];
// 		       	$file_create_date = filemtime($datafile); 

// 		       	foreach ($profile->updatehistory as $run_date => $affected_dates) {			            	
// 	            	if(in_array($data_date, $affected_dates)) {
// 	            		# this is a suspect date
// 	            		if ($file_create_date < $run_date) {
// 	            			if($records > 200){
// 		            			@unlink($datafile);
//             				} else {
//             					@$hits[$run_date]++;
//             				}
// 	            		}
// 	            	}
// 	            }

// 			}
// 		}
// 		$start_year++;
// 	}

// 	# now cleanup
// 	foreach ($profile->updatehistory as $run_date => $affected_dates) {
// 		if (empty($hits[$run_date]) || empty($affected_dates)) {
// 			unset($profile->updatehistory[$run_date]);
// 		}
// 	}
// 	return $profile->updatehistory;	
// }

# this function will get the highest sessionid from the table so we know where to start couning
function GetLastSessionID($profile) {
	global $db;
	/*
	$t = $profile->last_update_finished - 86400;
	$q = $db->Execute("select max(sessionid) from {$profile->tablename_merge} where timestamp >= {$t}");
	$data = $q->FetchRow();
	$sessioncounter = $data[0] + 1;
	if ($sessioncounter <= 1) {
		$sessioncounter = $profile->sessioncounter;
	}
	*/

	$sessioncounter = $profile->sessioncounter + 1;

	try{
		error_reporting(0); 
		@$q = $db->Execute("select max(sessionid) from {$profile->tablename_merge}");
		if(!$data){
			throw new Exception();
		}

		if ($data = $q->FetchRow()) {
			$sessioncounter = $data[0] + 1;
		}
	} catch(Exception $e){
		if (LOGAHOLIC_VERSION_STATUS=="release") {  
			error_reporting(E_ALL & ~E_NOTICE);    
		} else {
			error_reporting(E_ALL);
		}

		$db->Execute("alter table {$profile->tablename} ENABLE KEYS");
		$q = $db->Execute("select max(sessionid) from $profile->tablename_merge");
		if ($data = $q->FetchRow()) {
			$sessioncounter = $data[0] + 1;
		}
	}
	return $sessioncounter;
}

/*
**	This function Imports the temp log file into the database.
*/
function ImportLogToDatabase($new_log_file){
	global $db, $import, $took, $profile;
	# Import the data parsed by perl with Load Data Infile in MySQL

	$import->ImportLog($new_log_file);
	$took = $import->thisTook($took);

	# Insert the data in the corresponding tables.
	$import->insertIDs();
	
	# Insert the visitor ID's
	$import->insertVisitorIDs();
	
	# Insert the ID's in the main table.
	$import->insertNormalized();
	
	# Add internal referrer detection.
	$import->UpdateInternalReferrers();
	
	# Add useragent detection
	$import->UpdateUseragents();
	
	# If available, detect blacklisted IP numbers
	$import->Blacklist();

	# Move the crawler traffic to a table of it's own
	$import->separateBots();

	# Move the logaholic.gif data traffic to a table of it's own
	$import->separateGIFData();
	
	# Copy the conversions to a table of it's own
	$import->copyConversions();

	# We're done with our log table; delete it.
	$db->Execute("TRUNCATE table ". $profile->tablename ."log");

	# delete the temp file we used for importing into the db
	if(file_exists($new_log_file)){
		if(!@unlink($new_log_file)){
			echoWarning("Failed to delete file: <b>$new_log_file</b>","margin:5px 10px;");
			die();
		}
	}
}

function MakeSkipIpsRegex($value){
	global $errorHandler;
	$skipips = trim($value);

	# Check if there is a star at the start of the regex
	if(substr($skipips,0,1) == "*"){
		$skipips = "." . $skipips;
	}

	# Create the regex needed to skip ips.
	$skipips = str_replace(" ", "", $skipips);
	$regex_skipips = preg_replace("/\r\n|\r|\n/",",", $skipips);	# remove line breaks
	$regex_skipips = preg_replace("/,,|,/","|", $regex_skipips);	# remove comma's

	# Test if the regex is invalid
	if(@preg_match("/({$regex_skipips})/i", null) === false){
		echoWarning($errorHandler->error_msg . "<br/>- " . _SKIP_IP_NUMBERS . ": <strong>" . $value ."</strong>" ,"margin:10px;" );
		return "";	
	} else {
		return $regex_skipips;
	}
}

function ShouldWeManageKeys($preference) {
	global $profile;
		
	if ($preference !== false) {
		# it's been overridden by the user, respect the king!
		return true;
	}

	if ($profile->sessioncounter == 0 ) {
		# expect big data, may be a first time run
		return true;
	}

	if ($profile->sessioncounter > 2000000) {
		# let's treat this as a big profile
		if ((time() - $profile->last_update_finished) < (48 * 1200) ) {
			# it's been less than 12 hours since the last update,
			# we can expect a small up date, so leave the keys alone
			return false;
		}
	}

	if ($profile->sessioncounter > 100000) {
		# not very big, but let's leave the keys alone if the last update was less than 3 hours ago
		if ((time() - $profile->last_update_finished) < (24 * 1200) ) {
			# it's been less than 3 hours since the last update,
			# we can expect a small up date, so leave the keys alone
			return false;
		}
	}

	return true;
}

function GetThirtydayPageviews() {
	global $reports;
	
	$from = mktime(0,0,0, date("m"), date("d") - 30 ,date("Y"));
	$to = mktime(23,59,59, date("m"), date("d") -1  ,date("Y")); 

	if (!isset($reports['_ALL_TRAFFIC_BY_DAY'])) {
		return 0;
	}
	$report = new $reports['_ALL_TRAFFIC_BY_DAY']["ClassName"]();

	$report->from = $from;
	$report->to = $to;

	$data = $report->GetReportData();
	if(count($data) == 0){
		# Skip the profile if it never had any data
		return 0;
	}

	$totalpages = 0;
	$pageviews = 0;
	foreach ($data as $row) {
		$totalpages += $row[2];
		$pageviews += $row[3];
	}
	return $totalpages;
}

?>