<?php

/**
* @desc This report displays a overview of referrrer conversion.
*/
$reports["_TRAFFIC_TRENDS"] = Array(
	"ClassName" => "TrafficTrends", 
	"Category" => "_PERFORMANCE",
	"canAggregate" => false,  
	"icon" => "images/icons/32x32/unknown.png",
	"Options" => "daterangeField,profileselector,roadto,trafficsource,source,period,displaymode,columnSelector",
	"Filename" => "traffic_trends",
	"Distribution" => "Premium",
	"Order" => 5,
	"hidden" => true,
	"ReportVersion" => 1.0,
	"MinimumVersion" => 3.0,
	"EmailAlerts" => true
);

class TrafficTrends extends Report {

	function Settings() {
		$this->DefaultDisplay = "barlinechart";
		$this->DisplayModes = "barlinechart,table";
		$this->help = "";
		$this->displayReportButtons = false;
		$this->allowDateFormat = false;
		$this->columnDefinitions[] = array("Label" => _DATE);
		$this->columnDefinitions[] = array("Label" => _UNIQUE_VISITORS, "chart" => "bar");
		$this->columnDefinitions[] = array("Label" => _TARGET, "chart" => "bar", "yAxis" => 2);
		$this->columnDefinitions[] = array("Label" => _VISITOR_TREND, "chart" => "line");
		$this->columnDefinitions[] = array("Label" => _TARGET_TREND, "chart" => "line", "yAxis" => 2);
		
		if(empty($this->displaymode)) { $this->displaymode = $this->DefaultDisplay; }
		if(empty($this->avgperiod)) { $this->avgperiod = 7; }
		$this->chartoptions = array("yAxis1label" => _UNIQUE_VISITORS, "yFormat" => ",2f");
	}

	function DefineQuery() {
		global $qd, $db, $sqlst;
		
		# Define the chosen period / time unit
		if ($this->period == '_DAYS') {
			$qd = "FROM_UNIXTIME(timestamp, '%a, %m/%d/%Y')";
		} else if ($this->period == '_WEEKS') {
			$qd = "FROM_UNIXTIME(timestamp, '%x-W%v')";
		} else if ($this->period == '_MONTHS') {
			$qd = "FROM_UNIXTIME(timestamp, '%b %Y')";
		}

		if (!empty($this->source)) {
			# Get total unique visitors for time unit
			if ($this->sourcetype == "page") {
				$id = getID($this->source,'urls');
				$query  = "SELECT {$qd} AS timeunit, COUNT(DISTINCT visitorid) AS uvisitors FROM {$this->profile->tablename} as a WHERE timestamp BETWEEN ". $db->quote($this->from) ." AND ". $db->quote($this->to) ." AND url='{$id}' GROUP BY timeunit ORDER BY timestamp"; 
			
			} else if ($this->sourcetype == "keyword") {
				$id = getID($this->source,'keyword');
				$query  = "SELECT {$qd} AS timeunit, COUNT(DISTINCT visitorid) AS uvisitors FROM {$this->profile->tablename} AS a WHERE timestamp BETWEEN ". $db->quote($this->from) ." AND ". $db->quote($this->to) ." AND keywords='{$id}' GROUP BY timeunit ORDER BY timestamp"; 
			
			} else if ($this->sourcetype == "referrer") {
				$id = getID($this->source,'referrers');
				$query  = "SELECT {$qd} AS timeunit, COUNT(DISTINCT visitorid) AS uvisitors FROM {$this->profile->tablename} AS a WHERE timestamp BETWEEN ". $db->quote($this->from) ." AND ". $db->quote($this->to) ." AND referrer='{$id}' GROUP BY timeunit ORDER BY timestamp"; 
			}

			if(empty($id)){
				return false;
			}
		} else {
			# Select the amount of unique visitors
			$query = "SELECT {$qd} AS timeunit, COUNT(DISTINCT visitorid) AS uvisitors FROM {$this->profile->tablename} WHERE timestamp BETWEEN ". $db->quote($this->from) ." AND ". $db->quote($this->to) ." GROUP BY timeunit ORDER BY timestamp";
		}
		
		$query = subsetDataToSourceID($query);
		$this->applytrafficsource = false;
		return $query;
	}
	
	function GetReportData() {
		global $db, $qd;
		
		# Query the database with the query defined in DefineQuery function.
		$q = $this->DefineQuery();
		if(empty($q)){
			return [];
		}
		$query = $db->Execute($q);
		
		if(!empty($this->source)) {
			$this->addlabel = _SEARCH_FOR ." {$this->sourcetype}: {$this->source}";
			
			if ($this->sourcetype == "page") {
				$search_query = "url = ". getID($this->source,'urls') ." AND ";
			} else if ($this->sourcetype == "keyword") {
				$search_query = "keywords = ". getID($this->source,'keyword') ." AND ";
			} else if ($this->sourcetype == "referrer") {
				$search_query = "referrer = ". getID($this->source,'referrers') ." AND ";
			}
		} else {
			$search_query = "";
		}
		
		if (!empty($this->source)) {
			# If there is a source, we need to fetch the data set, filtered by that source, and store that data in a temporary table.
			@$db->Execute("DROP TABLE IF EXISTS {$this->profile->tablename}_temptable");
			
			$q = "SELECT visitorid, timestamp FROM {$this->profile->tablename} as a WHERE timestamp BETWEEN ". $db->quote($this->from) ." AND ". $db->quote($this->to) ." AND {$search_query} status = 200";
			$q = subsetDataToSourceID($q);

			$db->Execute("CREATE TEMPORARY TABLE {$this->profile->tablename}_temptable $q");
			
			# Prevent calls to multi-existing columns
			$qd = str_replace("timestamp", "c.timestamp", $qd);
			
			# Select amount of converted visitors
			$query2 = "SELECT {$qd} AS timeunit, COUNT(DISTINCT c.visitorid) AS users FROM {$this->profile->tablename}_temptable AS a, {$this->profile->tablename_conversions} AS c WHERE c.timestamp BETWEEN ". $db->quote($this->from) ." AND ". $db->quote($this->to) ." AND a.visitorid = c.visitorid AND url = ". $db->quote(getID($this->roadto,"urls"))." AND a.timestamp < c.timestamp GROUP BY timeunit ORDER BY c.timestamp";
		} else {
			# Select amount of converted visitors
			$query2 = "SELECT {$qd} AS timeunit, COUNT(DISTINCT visitorid) AS users FROM {$this->profile->tablename_conversions} AS c WHERE timestamp BETWEEN ". $db->quote($this->from) ." AND ". $db->quote($this->to) ." AND url = ".$db->quote(getID($this->roadto,"urls"))." GROUP BY timeunit ORDER BY timestamp";
			$query2 = subsetDataToSourceID($query2);
		}

		$query2 = $db->Execute($query2);
		
		$merge = [];
		
		# Set the data array and do zero fill
		while ($data = $query->FetchRow()) {
			$merge[$data["timeunit"]][1] = $data["uvisitors"];
			$merge[$data["timeunit"]][2] = 0;
			$merge[$data["timeunit"]][3] = 0;
		}
		
		# Merge unique visitors with converted visitors, and calculate conversion rate
		while ($data = $query2->FetchRow()) {
			$merge[$data["timeunit"]][2] = $data["users"];
			if($merge[$data["timeunit"]][1] != 0) {
				$merge[$data["timeunit"]][3] = number_format((($data["users"] / $merge[$data["timeunit"]][1]) * 100), 2);
			}
		}
		return $merge;
	}
	
	# This function prepares the data so it can be plotted
	function ConvertData($data = []) {
		# There is no data; give a warning
		$n = count($data);
		if ($n == 0) {
			return false;
		}
		
		# Start calculating trend line and rolling average
		$i = 1;
		while (list ($day, $row) = each ($data)) {
			$traffic_x[$i] = $i; # trend line for total traffic
			$target_x[$i] = $i; # trend line for conversion rate

			$traffic_y[$i] = $row[1];
			$target_y[$i] = $row[2];

			# begin calculation
			$traffic_xy[$i] = $traffic_x[$i] * $row[1];
			$target_xy[$i] = $target_x[$i] * $row[2];

			$traffic_xsq[$i] = $traffic_x[$i] * $traffic_x[$i];
			$target_xsq[$i] = $target_x[$i] * $target_x[$i];

			$i++;
		}
		
		# $n has already been vetted to be <> 0, so we can divide by $n with impunity here
		$traffic_a_part = array_sum($traffic_xy) - ((array_sum($traffic_x) * array_sum($traffic_y)) / $n);
		$target_a_part = array_sum($target_xy) - ((array_sum($target_x) * array_sum($target_y)) / $n);

		# array_sum($x) isn't vetted, so we need to protect from a division by 0 here.
		$traffic_a = @($traffic_a_part / (array_sum($traffic_xsq) - (1 / $n) * (array_sum($traffic_x) * array_sum($traffic_x))));
		$target_a = @($target_a_part / (array_sum($target_xsq) - (1 / $n) * (array_sum($target_x) * array_sum($target_x))));

		$traffic_b = (array_sum($traffic_y) / $n) - ($traffic_a * (array_sum($traffic_x) / $n));
		$target_b = (array_sum($target_y) / $n) - ($target_a * (array_sum($target_x) / $n));

		# add rolling average and plot point for trend
		reset($data);
		$ndays = count($data);
		$maxval = 0;
		$cstr = 0;
		
		$i = 0;
		while (list ($day, $row) = each ($data)) {
			while (list ($skey, $sval) = each ($row)) {
				switch ($skey) {
					# Case 1: Total Traffic
					case 1:
						$traffic_regval[$i] = ($traffic_a * $traffic_x[($i + 1)]) + $traffic_b;
					break;
					# Case 2: Target Traffic
					case 2:
						$target_regval[$i] = ($target_a * $target_x[($i + 1)]) + $target_b;
					break;
				}
			}
			$i++;
		}
		
		$looptime = getmicrotime();
		
		reset($data);
		//dump($data);
		$maxval = 0;
		$i = 0;
		# Merge trend line and rolling average into stuff
		while (list ($day, $row) = each ($data)) {
			if ($maxval < $row[1]) {
				$maxval = $row[1];
			}
			
			$graphdata[$i][0] = $day;
			$graphdata[$i][1] = $row[1];			
			$graphdata[$i][2] = $row[2];
			
			if($traffic_regval[($i)] <= 0) {
				$graphdata[$i][3] = 0;
			} else {
				$graphdata[$i][3] = round($traffic_regval[($i)]);
			}
			
			$graphdata[$i][4] = round($target_regval[($i)]);

			$i++;
		}

		return $graphdata;
	}
	
	function DisplayReport() {
		
		
		# Fetch the basic data
		$data = $this->GetReportData();
				
		# Convert the data to plottable data
		$data = $this->ConvertData($data);
		if(empty($data)){
			return false;
		}

		# If we want to view this report as a bar/line chart
		if($this->displaymode == 'barlinechart') {
			$this->ReportHeader();
			
			$this->MultiChart($data);
			
			echo "<div class='clear'></div>";
		} else {
			$this->sortTable = false;
			$this->displayTotalRow = false;
			$this->Table($data);
		}
	}
	
	function DisplayCustomForm() {
		# Rolling Average Field
		echo "<label for='avgperiod'>"._ROLLING_AVERAGE_PERIODS.": </label>";
		echo "<input class='report_option_field' type=\"text\" size=\"2\" name=\"avgperiod\" id='avgperiod' value=\"".@$this->avgperiod."\" />";
	}
	
	function UpdateStats($from = '', $to = '',$print = 2) {
		# not using datafiles yet
		return false;		
	}
}
?>