<?php
class WPPAS_Stats {	

	public $IP;
	public $today;
	public $year;
	public $month;
	public $day;
	public $hour;
	public $current_time;
	

	public function __construct() 
	{
		global $pro_ads_main;
		
		add_action( 'wp_loaded', array( $this, 'wpproads_pdf_template' ) );	
		
		$this->IP = $pro_ads_main->IP;
		$this->current_time = current_time( 'timestamp' );
		$this->today = mktime(0, 0, 0, $pro_ads_main->time_by_timezone('n'), $pro_ads_main->time_by_timezone('j'), $pro_ads_main->time_by_timezone('Y'));
		$this->year = $pro_ads_main->time_by_timezone('Y');
		$this->month = $pro_ads_main->time_by_timezone('n');
		$this->day = $pro_ads_main->time_by_timezone('j');
		$this->hour = date_i18n("G");
	}
	
	
	
	
	/*
	 * IP Addresses blocked?
	 *
	 * @access public
	 * @return bool
	*/
	public function ip_blocked()
	{
		global $pro_ads_multisite;
		
		$ip_adress = $this->IP;
		$wpproads_stats_blocked_ips = $pro_ads_multisite->wpproads_get_option('wpproads_stats_blocked_ips', '');
		$blocked_ips = explode(',', $wpproads_stats_blocked_ips);
		
		$is_blocked = in_array($ip_adress, $blocked_ips) ? 1 : 0;
		
		return $is_blocked;
	}
	
	
	
	/*
	 * Load stats cache
	 *
	 * @access public
	 * @return array
	*/
	public function load_stats_cache($stats = array())
	{
		global $pro_ads_multisite;
		
		return !empty($stats) ? $stats : $pro_ads_multisite->wpproads_get_option('wpproads_stats_cache', array());
	}
	
	
	
	
	public function default_select()
	{
		$select = current_user_can(WP_ADS_ROLE_ADMIN) ? array() : array('advertiser_id' => get_current_user_id());
		return $select;
	}	
	
	
	
	
	
	/*
	 * Serialize array
	 *
	 * @access public
	 * @return bool
	*/
	public function serialize_array($args = array())
	{	
		return serialize($args);
	}
	
	/*
	 * UN Serialize array
	 *
	 * @access public
	 * @return bool
	*/
	public function unserialize_array($args = array())
	{	
		return unserialize($args);
	}
	
	
	
	/*
	 * Check if string is serialized
	 *
	 * @access public
	 * @return bool
	*/
	public function is_serialized($string)
	{
		$data = @unserialize($string);
		if ($str === 'b:0;' || $data !== false) 
		{
			return 1;
		} 
		else 
		{
			return 0;
		}
	}
	
	
	
	/*
	 * QUERIES
	 *
	 * @access public
	 * @return string
	*/
	public function where_qry($where = '')
	{
		return !empty($where) ? ' WHERE '.$where : '';
	}
	public function limit_qry($limit = '')
	{
		return !empty($limit) ? ' LIMIT '.$limit : '';
	}
	public function order_qry($order = '')
	{
		return !empty($order) ? ' ORDER BY '.$order : '';
	}
	
	
	
	
	
	/**
	 * Get stats CTR
	 *
	 * @access public
	 * @return array
	*/
	public function get_ctr($args = array())
	{
		$ctr = !empty($args['clicks']) && !empty($args['impressions']) ? $args['clicks'] / $args['impressions'] * 100 : 0;
		return round($ctr,2).'%';	
	}
	
	
	
	
	
	/**
	 * Check array match
	 *
	 * @access public
	 * @return bool
	*/
	public function check_array_match($args, $st, $to_check = array('banner_id'))
	{
		$match = 0;
		
		foreach( $to_check as $key )
		{
			if( $args[$key] == $st[$key])
			{
				$match = 1;
			}
			else
			{
				return 0;
			}
		}
		
		return $match;
	}
	
	
	
	
	/**
	 * Select array to get specific data from the stats array.
	 *
	 * @access public
	 * @return array
	*/
	public function select_array($args = array() )
	{
		$groups = explode('-', $args['group']);
		$group_ids = explode('-', $args['group_id']);
		$data = array();
		
		foreach($groups as $i => $group)
		{
			$data[$group] = $group_ids[$i];	
		}
		
		return $data;
	}
	
	
	
	
	
	/*
	 * > v5.0.5 - Load Stats
	 *
	 * @access public
	 * @return array
	*/
	public function load_stats($args = array())
	{
		global $wpdb, $pro_ads_multisite, $pro_ads_main;
		
		$defaults = array(
			'type'                 => 'impressions',
			'banner_id'            => 0,
			'adzone_id'            => 0,
			'select'               => '*',
			'where'                => '',
			'limit'                => '',
			'order'                => ''
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		$res = $wpdb->get_results("SELECT ".$args['select']." FROM " . $pro_ads_multisite->wpproads_db_prefix() . "wppas_stats".
			$this->where_qry($args['where']).
			$this->order_qry($args['order']).
			$this->limit_qry($args['limit'])
			
		);
		
		return $res;
	}
	
	
	
	
	
	
	/*
	 * v5.0.5+ - Load Daily Stats
	 *
	 * @access public
	 * @return array
	*/
	public function load_daily_stats($args = array())
	{
		global $wpdb, $pro_ads_multisite, $pro_ads_main;
		
		$defaults = array(
			'type'                 => 'impressions',
			'banner_id'            => 0,
			'adzone_id'            => 0,
			'select'               => '*',
			'where'                => '',
			'limit'                => '',
			'order'                => ''
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		$res = $wpdb->get_results("SELECT ".$args['select']." FROM " . $pro_ads_multisite->wpproads_db_prefix() . "wppas_daily_stats".
			$this->where_qry($args['where']).
			$this->order_qry($args['order']).
			$this->limit_qry($args['limit'])
			
		);
		
		return $res;
	}
	
	
	
	
	
	public function select_query($args = array())
	{
		$query = '';
		if(!empty($args))
		{
			foreach($args as $key => $itm)
			{
				$query.= ' AND "'.$key.'" = "'.$itm.'"';
			}
		}
		
		return $query;
	}
	
	
	
	
	
	/*
	 * RESET STATS
	 *
	 * @access public
	 * @return null
	*/
	public function reset_stats()
	{
		global $wpdb;
		
		$table  = $wpdb->prefix . 'wppas_stats';
		$delete = $wpdb->query("TRUNCATE TABLE $table");
		
		$table  = $wpdb->prefix . 'wppas_daily_stats';
		$delete = $wpdb->query("TRUNCATE TABLE $table");
	}
	
	
	
	
	
	
	
	/*
	 * Save Stats
	 *
	 * @access public
	 * @return null
	*/
	public function save_stats( $args = array() )
	{
		global $wpdb, $pro_ads_multisite, $pro_ads_main, $pro_ads_banners;
		
		$defaults = array(
			'type'                 => 'impressions',
			'banner_id'            => 0,
			'advertiser_id'        => 0,
			'campaign_id'          => 0,
			'adzone_id'            => 0,
			'rss'                  => 0
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		$pvbl = $this->load_pvbl_cookie();
		if( !empty($args['banner_id']) && !in_array($args['banner_id'], $pvbl))
		{
			// Check if satistics are enabled
			$wpproads_enable_stats = $pro_ads_multisite->wpproads_get_option('wpproads_enable_stats', 0);
			// Google Analytics
			$wpproads_google_analytics_id = get_option('wpproads_google_analytics_id', '');
			
			$advertiser_id = !empty($args['advertiser_id']) ? $args['advertiser_id'] : get_post_meta( $args['banner_id'], '_banner_advertiser_id', true );
			$campaign_id   = !empty($args['campaign_id']) ? $args['campaign_id'] : get_post_meta( $args['banner_id'], '_banner_campaign_id', true );
			
			$stats_data = array(
				'type'                => $args['type'],
				'banner_id'           => $args['banner_id'], 
				'adzone_id'           => $args['adzone_id'], 
				'advertiser_id'       => $advertiser_id,
				'campaign_id'         => $campaign_id,
				'google_analytics_id' => $wpproads_google_analytics_id
			);
			
			
			// Check if stats need to be saved for this IP
			if( !$this->ip_blocked() && $wpproads_enable_stats )
			{
				// Load user data.	
				$wpproads_enable_userdata_stats = $pro_ads_multisite->wpproads_get_option('wpproads_enable_userdata_stats', 0);
				$stats_data['userdata'] = $wpproads_enable_userdata_stats ? $pro_ads_main->get_user_data() : array();
				
				// INSERT STATISTICS
				$this->update_main_daily_stats_db($stats_data, $args);	
			}
			
			
			
			// GA
			if( !empty($wpproads_google_analytics_id) && !$args['rss'] )
			{
				$this->save_ga_action( $stats_data );
			}
			
			// Update pvbl
			array_push($pvbl, $stats_data['banner_id']);
			$this->update_pvbl_cookie($pvbl);
			
			// Filter -------------------------------------------------------
			apply_filters('wppas_save_stats', $stats_data);
			apply_filters('wp_pro_ads_save_stats', $stats_data);
		}
	}
	
	
	
	
	/**
	 * UPDATE BANNER CONTRACTS
	 */
	public function update_stats_for_banner_contracts($stats_data = array(), $args = array())
	{	
		$post_type = get_post_type($stats_data['banner_id']);
		
		// UPDATE DATA FOR BANNER CONTRACTS
		if($post_type == 'wppas_banners')
		{
			global $wppas_banner_creator;
			
			if($args['type'] == 'clicks')
			{
				// Update banner clicks
				$banner_clicks = get_post_meta( $stats_data['banner_id'], '_wpproads_banner_clicks', true );
				$banner_clicks = $banner_clicks+1;
				update_post_meta( $stats_data['banner_id'], '_wpproads_banner_clicks', $banner_clicks );
				
				// Update banner status
				$wppas_banner_creator->update_banner_status(array('bid' => $stats_data['banner_id']));
			}
			else
			{
				// Update banner impressions
				$banner_impressions = get_post_meta( $stats_data['banner_id'], '_wpproads_banner_impressions', true );
				$banner_impressions = $banner_impressions+1;
				update_post_meta( $stats_data['banner_id'], '_wpproads_banner_impressions', $banner_impressions );
				
				// Update banner status
				$wppas_banner_creator->update_banner_status(array('bid' => $stats_data['banner_id']));
			}
		}
		else
		{
			global $pro_ads_banners;
			
			// FOR OLD BANNERS
			if($args['type'] == 'clicks')
			{
				// Update banner clicks
				$banner_clicks = get_post_meta( $stats_data['banner_id'], '_banner_clicks', true );
				$banner_clicks = $banner_clicks+1;
				update_post_meta( $stats_data['banner_id'], '_banner_clicks', $banner_clicks );
				
				// Update banner status
				$pro_ads_banners->update_banner_status( $stats_data['banner_id'] );
			}
			else
			{
				// Update banner impressions
				$banner_impressions = get_post_meta( $stats_data['banner_id'], '_banner_impressions', true );
				$banner_impressions = $banner_impressions+1;
				update_post_meta( $stats_data['banner_id'], '_banner_impressions', $banner_impressions );
				// Update banner in adzone impressions
				if( !empty($stats_data['adzone_id']) )
				{
					$banner_adzone_impressions = get_post_meta( $stats_data['banner_id'], '_adzone_'.$stats_data['adzone_id'].'_impressions', true );
					$banner_adzone_impressions = $banner_adzone_impressions+1;
					update_post_meta( $stats_data['banner_id'], '_adzone_'.$stats_data['adzone_id'].'_impressions', $banner_adzone_impressions );
				}
				// check banner contract
				$banner_contract = get_post_meta( $stats_data['banner_id'], '_banner_contract', true );
				if( $banner_contract == 2 )
				{
					// Update banner status
					$pro_ads_banners->update_banner_status( $stats_data['banner_id'] );
				}
			}
		}
	}
	
	
	
	
	/*
	 * Update User Stats Cookie
	 *
	 * @access public
	 * @return null
	*/
	public function update_user_stats_cookie($stats_data = array())
	{
		//$expire = mktime(24,0,0);
		$expire = strtotime('today 23:59:59');
		
		if(isset($_COOKIE['wppas_user_stats'])) 
		{
			$cookie = json_decode(stripslashes($_COOKIE['wppas_user_stats']), true);
			//echo '<pre>'.print_r($cookie,true).'</pre>';
			//echo date_i18n('d.m.Y H:i:s', $expire).'<br>';
			/*if( current_user_can(WP_ADS_ROLE_ADMIN) ){
				echo '<pre>'.print_r($cookie,true).'</pre>';
			}*/
			if( is_array($cookie))
			{
				if( array_key_exists($this->today, $cookie))
				{
					$seen = in_array($stats_data['banner_id'], $cookie[$this->today][$stats_data['type']]['banners']) ? 1 : 0;
						
					if(!$seen)
					{
						/*if( current_user_can(WP_ADS_ROLE_ADMIN) ){
							echo 'not seen '.$stats_data['banner_id'].'<br>';
							echo '<pre>'.print_r($cookie[$this->today][$stats_data['type']]['banners'],true).'</pre>';
						}*/
						array_push($cookie[$this->today][$stats_data['type']]['banners'], $stats_data['banner_id']);
						setcookie( 'wppas_user_stats', json_encode($cookie), $expire, COOKIEPATH, COOKIE_DOMAIN );
						$_COOKIE['wppas_user_stats'] = json_encode($cookie);
					}
				}
				else
				{
					$this->remove_user_cookie();
					$cook_arr = array(
						$this->today => array(
							'impressions' => array(
								'banners' => $stats_data['type'] == 'impressions' ? array($stats_data['banner_id']) : array()
							),
							'clicks' => array(
								'banners' => $stats_data['type'] == 'clicks' ? array($stats_data['banner_id']) : array()
							)
						)
					);
					
					setcookie( 'wppas_user_stats', json_encode($cook_arr), $expire, COOKIEPATH, COOKIE_DOMAIN );	
					$_COOKIE['wppas_user_stats'] = json_encode($cook_arr);
				}
			}
		}
		else
		{
			$cook_arr = array(
				$this->today => array(
					'impressions' => array(
						'banners' => $stats_data['type'] == 'impressions' ? array($stats_data['banner_id']) : array()
					),
					'clicks' => array(
						'banners' => $stats_data['type'] == 'clicks' ? array($stats_data['banner_id']) : array()
					)
				)
			);
			
			setcookie( 'wppas_user_stats', json_encode($cook_arr), $expire, COOKIEPATH, COOKIE_DOMAIN );	
			$_COOKIE['wppas_user_stats'] = json_encode($cook_arr);
		}
	}
	
	
	
	/*
	 * Load User Stats Cookie
	 *
	 * @access public
	 * @return array or 0
	*/
	public function load_user_cookie()
	{
		$cookie = 0;
		
		if( isset($_COOKIE['wppas_user_stats']))
		{
			$cookie = json_decode(stripslashes($_COOKIE['wppas_user_stats']), true);
			//echo '<pre>'.print_r($cookie,true).'</pre>';	
		}	
		
		return $cookie;	
	}
	
	
	
	/*
	 * Remove User Stats Cookie
	 *
	 * @access public
	 * @return null
	*/
	public function remove_user_cookie()
	{
		unset( $_COOKIE['wppas_user_stats'] );
		setcookie('wppas_user_stats', '', current_time('timestamp')-3600, COOKIEPATH, COOKIE_DOMAIN);
	}
	
	
	
	/*
	 * Update Page View banner Load (pvbl) Cookie
	 *
	 * @access public
	 * @return null
	*/
	public function update_pvbl_cookie($pvbl = array())
	{
		$expire = 0;
		
		setcookie( 'wppas_pvbl', json_encode($pvbl), $expire, COOKIEPATH, COOKIE_DOMAIN );
		$_COOKIE['wppas_pvbl'] = json_encode($pvbl);
	}
	
	/*
	 * Load Page View banner Load (pvbl) Cookie
	 *
	 * @access public
	 * @return array
	*/
	public function load_pvbl_cookie()
	{
		$cookie = array();
		
		if( isset($_COOKIE['wppas_pvbl']))
		{
			$cookie = json_decode(stripslashes($_COOKIE['wppas_pvbl']), true);
			//echo '<pre>'.print_r($cookie,true).'</pre>';	
		}	
		
		return $cookie;	
	}
	
	
	
	
	
	/*
	 * Update/Insert stats table into main daily stats db
	 *
	 * @since v5.0.5
	 * @access public
	 * @return null
	*/
	public function update_main_daily_stats_db($stats_data = array(), $args = array())
	{
		global $wpdb, $pro_ads_multisite;
		
		$defaults = array(
			'type' => 'impressions',
			'time' => $this->today,
			'hits' => 1
		);
		$args = wp_parse_args( $args, $defaults );
		//$this->remove_user_cookie();
		
		$hour = mktime(date_i18n('G'), 0, 0, $this->month, $this->day, $this->year);
		$wpproads_enable_impr = $pro_ads_multisite->wpproads_get_option('wpproads_enable_impr', 1);
		$save = $args['type'] == 'impressions' && $wpproads_enable_impr || $args['type'] == 'clicks' ? 1 : 0;
		$hourly_default = array();
		for($h = 0; $h < 24; $h++)
		{
			$hr = mktime($h,0,0, $this->month, $this->day, $this->year);
			//$hr = mktime($h, 0, 0);
			//echo $hr.' - '.date('G',$hr).' :: '.mktime(date_i18n('G'), 0, 0).' - '.date('G', mktime(date_i18n('G'), 0, 0)).'<br>';
			$hourly_default[$hr] = array();
		}
		
		//echo '<pre>'.print_r($stats,true).'</pre>';
		if($save)
		{
			$data = $wpdb->get_results("SELECT * FROM " . $pro_ads_multisite->wpproads_db_prefix() . "wppas_daily_stats USE INDEX(time)
				WHERE 
					time = ".$this->today." 
				LIMIT 1"
			);
			$hourly = !empty($data) ? json_decode($data[0]->data,true) : $hourly_default;
			
			$cookie = $this->load_user_cookie();
			$seen = 0;
			
			if( !empty($cookie) && array_key_exists($this->today, $cookie))
			{
				//echo 'exist';
				$seen = in_array($stats_data['banner_id'], $cookie[$this->today][$args['type']]['banners']) ? 1 : 0;
			}
			else
			{
				//echo 'renew';
				// Set cookie @since v5.0.5
				$this->update_user_stats_cookie($stats_data);	
			}
			
			$daily_hits = !empty($data) ? $data[0]->{$args['type']} + 1 : 1;
			$hourly_hits = !empty($hourly[$hour]) ? $hourly[$hour]['hourly_'.$args['type']] + 1 : 1;
			
			if( !$seen )
			{ 
				//echo 'not seen';
				$this->update_user_stats_cookie($stats_data);
				$daily_unique_hits = !empty($data) ? $data[0]->{'unique_'.$args['type']} + 1 : 1;
				$hourly_unique_hits = !empty($hourly[$hour]) ? $hourly[$hour]['hourly_unique_'.$args['type']] + 1 : 1;
				$this->update_stats_for_banner_contracts($stats_data, $args);
			}
			else
			{
				//echo 'seen';
				//print_r($cookie);
				$daily_unique_hits = !empty($data) ? $data[0]->{'unique_'.$args['type']} : 1;
				$hourly_unique_hits = !empty($hourly[$hour]) ? $hourly[$hour]['hourly_unique_'.$args['type']] : 1;
				$this->update_stats_for_banner_contracts($stats_data, $args);
			}
			
			/*if( current_user_can(WP_ADS_ROLE_ADMIN) ){
				if($stats_data['banner_id'] == 11303){
					echo $daily_hits.'<br>';
					echo $daily_unique_hits;
				}
			}*/
			
			if(!empty($hourly[$hour]))
			{
				$hourly[$hour]['hourly_'.$args['type']] = $hourly_hits;
				$hourly[$hour]['hourly_unique_'.$args['type']] = $hourly_unique_hits;
				
				/*if( current_user_can(WP_ADS_ROLE_ADMIN) ){
					echo '<pre>'.print_r($hourly[$hour]['banner_data'],true).'</pre>';
				}*/
				
				if(array_key_exists($stats_data['banner_id'], $hourly[$hour]['banner_data']))
				{	
					//echo '<pre>'.print_r($hourly,true).'</pre>';
					$hourly[$hour]['banner_data'][$stats_data['banner_id']][$args['type']]['all'] = $hourly[$hour]['banner_data'][$stats_data['banner_id']][$args['type']]['all']+1;
					if( !$seen )
					{
						$hourly[$hour]['banner_data'][$stats_data['banner_id']][$args['type']]['unique'] = $hourly[$hour]['banner_data'][$stats_data['banner_id']][$args['type']]['unique']+1;
					}
					
					/*if( current_user_can(WP_ADS_ROLE_ADMIN) ){
						if($stats_data['banner_id'] == 2756){
							echo $hourly[$hour]['banner_data'][$stats_data['banner_id']][$args['type']]['all'].'<br>';
							echo $hourly[$hour]['banner_data'][$stats_data['banner_id']][$args['type']]['unique'];
						}
					}*/
				}
				else
				{
					$hourly[$hour]['banner_data'][$stats_data['banner_id']] = array(
						'banner_id' => $stats_data['banner_id'],
						'advertiser_id' => $stats_data['advertiser_id'],
						'adzone_id' => $stats_data['adzone_id'],
						'campaign_id' => $stats_data['campaign_id'],
						$args['type'] => array(
							'all' => 1,
							'unique' => 1
						)
					);
				}
				
				if( !empty($stats_data['userdata']) && !$seen )
				{
					$hourly[$hour]['user_data'] = $this->collect_user_data($stats_data['userdata'], $hourly[$hour]['user_data']);
				}
			}
			else
			{
				$hourly[$hour] = array(
					'hourly_'.$args['type'] => $hourly_hits,
					'hourly_unique_'.$args['type'] => $hourly_unique_hits,
					'banner_data' => array(
						$stats_data['banner_id'] => array(
							'banner_id' => $stats_data['banner_id'],
							'advertiser_id' => $stats_data['advertiser_id'],
							'adzone_id' => $stats_data['adzone_id'],
							'campaign_id' => $stats_data['campaign_id'],
							$args['type'] => array(
								'all' => 1,
								'unique' => 1
							)
						)
					)
				);
				
				if( !empty($stats_data['userdata']))
				{
					$hourly[$hour]['user_data'] = $this->collect_user_data($stats_data['userdata']);
				}
			}
			
			$hourly = $hourly + $hourly_default;
			ksort($hourly);
			//echo $key.'<pre>'.print_r($hourly,true).'</pre>';
			
			if( empty($data))
			{
				$wpdb->query("INSERT INTO " . $pro_ads_multisite->wpproads_db_prefix() . "wppas_daily_stats 
					SET 
						time                      = '".$this->today."',
						".$args['type']."         = ".$daily_hits.",
						unique_".$args['type']."  = ".$daily_unique_hits.",
						data                      = '".json_encode($hourly)."'												 
				");
			}
			else
			{
				$wpdb->query("UPDATE " . $pro_ads_multisite->wpproads_db_prefix() . "wppas_daily_stats 
					SET 
						".$args['type']."         = ".$daily_hits.",
						unique_".$args['type']."  = ".$daily_unique_hits.",
						data                   = '".json_encode($hourly)."'		
					WHERE 
						id = ".$data[0]->id." 
				");
			}
		}
		//echo '<pre>'.print_r($hourly,true).'</pre>';
	}
	
	
	
	
	
	public function collect_user_data($user_data = array(), $counts = array())
	{
		$defaults = array(
			'geo' => array(),
			'browser' => array(),
			'platform' => array(),
			'device' => array()
		);
		$counts = wp_parse_args( $counts, $defaults );
		
		foreach($user_data as $itm => $item)
		{
			$counts[$itm] = $this->count_user_data_collect(array('data' => $item, 'user_data' => $user_data));
		}
		
		return $counts;
	}
	
	
	
	public function count_user_data_collect($args = array())
	{
		if( !empty($args['data']) && !is_array($args['data']))
		{
			$res = !array_key_exists($args['data'], $args['user_data']) ? array($args['data'] => 1) : array($args['data'] => $args['user_data'][$args['data']]+1);
			return $res;
		}
	}
	
	
	
	
	
	
	/**
	 * update the statistics array
	 * $this->update_stats_array(array('type' => 'click', 'banner_id' => 3));
	 *
	 * @access public
	 * @return array
	*/
	public function update_stats_array($args = array())
	{
		global $pro_ads_multisite, $pro_ads_main;
		
		$defaults = array(
			'stats'                => array(),
			'type'                 => 'impressions',
			'ip_address'           => $this->IP,
			'banner_id'            => 0,
			'adzone_id'            => 0,
			'advertiser_id'        => 0,
			'campaign_id'          => 0,
			'hour'                 => $this->hour,
			'time'                 => $this->current_time,
			'userdata'             => array()
		);
		
		$args = wp_parse_args( $args, $defaults );
		$save_stats_type = $pro_ads_multisite->wpproads_get_option('wpproads_save_stats_type', 'unique');
		
		// Check if daily stats array exists
		if( !empty($args['stats']))
		{
			$match_bid = 0;
			foreach($args['stats'] as $key => $st)
			{
				// Check if banner_id already exists in the daily array.
				if( $this->check_array_match($args, $st, array('banner_id')))
				{
					// user already visited today.
					$match_ip = 0;
					foreach( $st[$args['type']] as $hts => $hits_type)
					{
						if( $this->check_array_match($args, $hits_type, array('ip_address')))
						{
							$match_ip = 1;
							if( $save_stats_type == 'all')
							{
								array_push( 
									$args['stats'][$key][$args['type']][$hts]['hits'], 
									array('time' => $args['time'])
								);
							}
							else
							{
								return 0;	
							}
							break;
						}
					}
					$match_bid = 1;
					
					// New unique daily user.
					// If its a new user we add a new array in the impressions or clicks array. all user data gets stored in this array.
					if( !$match_ip )
					{
						array_push( 
							$args['stats'][$key][$args['type']], 
							array(
								'ip_address' => $args['ip_address'],
								'userdata' => $args['userdata'], 
								'hits' => array(array('time' => $args['time']))
							)
						);
					}	
				}
			}
			
			// No banner_id matches found in the daily array.
			if( !$match_bid )
			{
				array_push( 
					$args['stats'], 
					$this->add_new_array_item($args)
				);
			}	
		}
		else
		{
			// daily array does not yet exist.
			$args['stats'] = array($this->add_new_array_item($args));
		}
		
		return $args['stats'];
	}
	
	
	
	
	
	
	
	
	/**
	 * ADD New array item
	 *
	 * @access public
	 * @return array
	*/
	public function add_new_array_item($args = array())
	{	
		global $pro_ads_main;
		
		$defaults = array(
			'hits' => 1
		);
		$args = wp_parse_args( $args, $defaults );
		
		$impressions = array();
		$clicks = array();
		
		$hits = array();
		//echo $args['hits'].'<br>';
		for($h = 0; $h < $args['hits']; $h++)
		{
			array_push($hits, array('time' => $args['time']));
		}
		//echo '<pre>'.print_r($hits,true).'</pre><br><br>';
		
		if( $args['type'] == 'impressions' )
		{
			array_push($impressions, array('ip_address' => $args['ip_address'], 'userdata' => $args['userdata'], 'hits' => $hits));
		}
		else
		{
			array_push($clicks, array('ip_address' => $args['ip_address'], 'userdata' => $args['userdata'], 'hits' => $hits));
		}
		
		$item = array(
			'banner_id'      => $args['banner_id'],
			'adzone_id'      => $args['adzone_id'],
			'campaign_id'    => $args['campaign_id'],
			'advertiser_id'  => $args['advertiser_id'],
			'impressions'    => $impressions,
			'clicks'         => $clicks
		);
		
		return $item;
	}
	
	
	
	
	
	
	/**
	 * Create stats array from database values
	 *
	 * @access public
	 * @return array
	*/
	public function create_stats_array($args = array() )
	{
		global $wpdb;
		
		$defaults = array(
			'start'  => '',
			'end'    => '',
			'stats'  => array(),
			'select' => array()
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		if( empty($args['stats']) )
		{
			$select = $this->decode_array( $args['select'] );
			$limit = $args['start'] == $args['end'] ? 1 : '';
			
			$stats = $this->load_stats(array(
				'select' => 'time,data',
				'where'  => 'time >= '.$args['start'].' AND time <= '.$args['end'],
				'limit'  => $limit
			));
			
			$stats_arr = array();
			
			foreach($stats as $stat)
			{
				$data = $this->unserialize_array($stat->data);
				$match = !empty($select) ? $this->limit_stats_array($select, $data) : true;
				
				if( $match )
				{
					//echo '<pre>'.print_r($data, true).'</pre>';
					$stats_arr[date_i18n('Y', $stat->time)][date_i18n('n', $stat->time)][date_i18n('j', $stat->time)] = $data;
				}
			}
			
			//echo '<pre>'.print_r($stats_arr, true).'</pre>';
			
			return $stats_arr;
		}
		else
		{
			return $args['stats'];
		}
	}
	
	
	/**
	 * LIMIT STATS ARRAY - Only get the data needed.
	 *
	*/
	public function limit_stats_array($select, $haystack) 
	{	
		if( !empty($select) )
		{
			foreach($select as $key => $sel) 
			{
				foreach($haystack as $item) 
				{
					if( (is_array($item) && array_key_exists($key, $item)) )
					{
						if( $item[$key] == $sel )
						{
							return true;
						}
					}
				}
			}
		}
		//echo key($select);
		//print_r($select);
	
		return false;
	}
	
	
	
	
	/**
	 * Check matching values
	 *
	 * @access public
	 * @return int
	*/
	public function check_maching_values($args = array())
	{
		$select = $this->decode_array( $args['select'] );
		
		if( !empty($select))
		{
			foreach($select as $sk => $sel )
			{
				$match = $select[$sk] == $args['all_stats'][$sk] ? 1 : 0;
				
				if( !$match ){ break; }
			}
			
			return $match;
		}
	}
	
	
	
	
	
	/**
	 * Stats counter
	 *
	 * @access public
	 * @return int
	*/
	public function stats_counter($args = array())
	{
		$defaults = array(
			'stats'        => array(),
			'cnt'          => 0,
			'type'         => 'impressions',
			'unique'       => 0
		);
		
		$args = wp_parse_args( $args, $defaults );
		$cnt = $args['cnt'];
		
		if( !$args['unique'] )
		{
			// ex.: $args['stats']['impressions']
			foreach( $args['stats'][$args['type']] as $val )
			{
				$cnt = $cnt + count($val['hits']);
			}
		}
		else
		{
			$cnt = $cnt + count($args['stats'][$args['type']]);
		}
		
		return $cnt;
	}
	
	
	
	
	
	/**
	 * v5.0.5+ - Filter stats array on banner ID
	 *
	 * @access public
	 * @return array
	*/
	public function filter_stats_on_banner_id($stats = array(), $select = array())
	{
		$res = array();
		if(!empty($select) && array_key_exists('banner_id',$select))
		{
			$res = isset($stats['banner_data'][$select['banner_id']]) ? $stats['banner_data'][$select['banner_id']] : array();
		}
		
		return $res;
	}
	
	
	/*
	 * v5.0.5+ - Filter stats array - for: advertiser_id, adzone_ID OR campaign_id
	 *
	 * @access public
	 * @return array
	*/
	public function filter_stats_array($stats = array(), $select = array())
	{
		$filter = array();
		
		if(!empty($stats))
		{
			//echo '<pre>'.print_r($stats,true).'</pre>';
			foreach($stats as $key => $stat)
			{
				if(!empty($stat))
				{
					//echo '<pre>'.print_r($stat,true).'</pre>';
					foreach($stat['banner_data'] as $bkey => $banner)
					{
						//echo '<pre>'.print_r($banner,true).'</pre><br>';
						//print_r($select);
						foreach($select as $skey => $sel)
						{
							//echo $skey.' '.$key;
							/*if( current_user_can(WP_ADS_ROLE_ADMIN) ){
								if($bkey == 11303){
									echo $bkey.'::'.$stats[$key]['hourly_unique_impressions'].'<br>';
									
								}
							}*/
							if( isset($banner[$skey]) && $banner[$skey] == $sel )
							{
								//echo '1 '.$banner[$skey].' - '.$skey.' '.$sel.': '.$key.'<br>';
								
								$all_impr = !empty($banner['impressions']['all']) ? $banner['impressions']['all'] : 0;
								$unique_impr = !empty($banner['impressions']['unique']) ? $banner['impressions']['unique'] : 0;
								$all_clicks = !empty($banner['clicks']['all']) ? $banner['clicks']['all'] : 0;
								$unique_clicks = !empty($banner['clicks']['unique']) ? $banner['clicks']['unique'] : 0;
								
								$filter[$key]['hourly_impressions'] = $all_impr;
								$filter[$key]['hourly_unique_impressions'] = $unique_impr;
								$filter[$key]['hourly_clicks'] = $all_clicks;
								$filter[$key]['hourly_unique_clicks'] = $unique_clicks;
								$filter[$key]['banner_data'][$bkey] = $stats[$key]['banner_data'][$bkey];
								$filter[$key]['banner_data'][$bkey]['impressions']['all'] = $all_impr;
								$filter[$key]['banner_data'][$bkey]['impressions']['unique'] = $unique_impr;
								$filter[$key]['banner_data'][$bkey]['clicks']['all'] = $all_clicks;
								$filter[$key]['banner_data'][$bkey]['clicks']['unique'] = $unique_clicks;
							}
							else
							{
								//echo '2 '.$banner[$skey].' - '.$skey.' '.$sel.': '.$key.'<br>';
								
								if( !array_key_exists($key, $filter) )
								{
									$filter[$key]['hourly_impressions'] = 0;
									$filter[$key]['hourly_unique_impressions'] = 0;
									$filter[$key]['hourly_clicks'] = 0;
									$filter[$key]['hourly_unique_clicks'] = 0;
								}
							}
							
							/*if( !isset($banner[$skey]) || $banner[$skey] != $sel )
							{
								if(array_key_exists('hourly_impressions', $stats[$key]))
								{
									
									$stats[$key]['hourly_impressions'] = $stats[$key]['hourly_impressions'] > 0 ? $stats[$key]['hourly_impressions']-$banner['impressions']['all'] : 0;
									$stats[$key]['hourly_unique_impressions'] = $stats[$key]['hourly_unique_impressions'] > 0 ? $stats[$key]['hourly_unique_impressions']-$banner['impressions']['unique'] : 0;
								}
								if( array_key_exists('clicks', $stats[$key]))
								{
									$stats[$key]['hourly_clicks'] = $stats[$key]['hourly_clicks'] > 0 ? $stats[$key]['hourly_clicks']-$banner['clicks']['all'] : 0;
									$stats[$key]['hourly_unique_clicks'] = $stats[$key]['hourly_unique_clicks'] > 0 ? $stats[$key]['hourly_unique_clicks']-$banner['clicks']['unique'] : 0;
								}
								
								unset($stats[$key]['banner_data'][$bkey]);
							}*/
						}
					}
				}
				else
				{
					$filter[$key]['hourly_impressions'] = 0;
					$filter[$key]['hourly_unique_impressions'] = 0;
					$filter[$key]['hourly_clicks'] = 0;
					$filter[$key]['hourly_unique_clicks'] = 0;
					//$filter[$key]['banner_data'][$bkey] = array();
				}
			}
		}
		
		//echo '<pre>'.print_r($stats,true).'</pre><br>';
		//echo $hourly_unique_impressions;
		//echo '<pre>'.print_r($filter,true).'</pre>';
		return $filter;
	}
	
	
	/*
	 * v5.0.5+ - Use stats Filter - for: advertiser_id, adzone_ID OR campaign_id
	 * This function checks if a select value matches the array and returns true or false to use the stats or not.
	 *
	 * @access public
	 * @return bool
	*/
	public function use_stats_filter($banner_stats = array(), $select = array())
	{
		$use = 1;
		if(!empty($select))
		{
			foreach($select as $key => $sel)
			{
				if( !isset($banner_stats[$key]) || $banner_stats[$key] != $sel )
				{
					$use = 0;
					return $use;
					break;
				}
			}
		}
		return $use;
	}
	
	
	
	
	
	/**
	 * > v5.0.5 - Get hourly stats
	 *
	 * @access public
	 * @return int
	*/
	public function get_hourly_stats( $args = array() )
	{
		global $pro_ads_multisite;
		
		$defaults = array(
			'stats'                => array(),
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'hour'                 => $this->hour,
			'type'                 => 'impressions',
			'unique'               => 0,
			'select'               => array(),
			'start'                => '',
			'end'                  => ''
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		// load stats array
		$stats = $this->create_stats_array(array('stats' => $args['stats'], 'start' => $args['start'], 'end' => $args['end'], 'select' => $args['select']));
		$select = $this->decode_array( $args['select'] );
		
		$cnt = 0;
		if( !empty($stats) && !empty($stats[$args['year']][$args['month']][$args['day']]))
		{
			foreach($stats[$args['year']][$args['month']][$args['day']] as $today)
			{
				$match = !empty($select) ? $this->check_maching_values(array('select' => $select, 'all_stats' => $today)) : 1;
				
				if( $match )
				{
					// Impressions | clicks
					if(!empty($today[$args['type']]))
					{
						foreach($today[$args['type']] as $val)
						{
							// All data - not unique.
							if( !$args['unique'] )
							{
								foreach($val['hits'] as $hits)
								{
									if(date('G', $hits['time']) == $args['hour'])
									{
										$cnt++;
									}
								}
							}
							else
							{
								// Unique data.
								if(date('G', $val['hits'][0]['time']) == $args['hour'])
								{
									$cnt++;
								}
							}
						}
					}
				}
			}	
		}
		
		return $cnt;	
	}
	
	
	
	
	
	
	
	/**
	 * > v5.0.5 - Get daily stats
	 *
	 * @access public
	 * @return int
	*/
	public function get_daily_stats($args = array())
	{
		global $pro_ads_multisite;
		
		$defaults = array(
			'stats'                => array(),
			'start'                => $this->today,
			'end'                  => $this->today,
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'type'                 => 'impressions',
			'unique'               => 0,
			'select'               => array()
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		// load stats array
		$cnt = 0;
		
		if( !empty($args['select']) && $args['select'] != 'W10=')
		{	
			$stats = $this->create_stats_array(array('stats' => $args['stats'], 'start' => $args['start'], 'end' => $args['end'], 'select' => $args['select']));
			
			//echo '<pre>'.print_r($stats[$args['year']][$args['month']][$args['day']], true).'</pre>';
			for( $i = 0; $i <= 23; $i++ ){
				if( !empty($stats[$args['year']][$args['month']][$args['day']]))
				{
					$cnt += $this->get_hourly_stats(
						array(
							'stats'   => $stats,
							'start'   => $args['start'],
							'end'     => $args['end'],
							'year'    => $args['year'],
							'month'   => $args['month'],
							'day'     => $args['day'],
							'hour'    => $i,
							'type'    => $args['type'],
							'unique'  => $args['unique'],
							'select'  => $args['select']
						)
					);
				}
			}
			//echo $args['start'].'<br>';
		}
		else
		{
			$sdate = mktime(0,0,0,$args['month'], $args['day'], $args['year']);
			$edate = mktime(23,59,59,$args['month'], $args['day'], $args['year']);
			
			$stats = $this->load_stats(array(
				'select' => $args['type'],
				'where'  => 'time >= '.$sdate.' AND time <= '.$edate
			));
			
			$cnt += $stats[0]->{$args['type']};
		}
		
		
		
		return $cnt;
	}
	
	
	
	public function _get_daily_stats($args = array())
	{
		$defaults = array(
			'start'                => $this->today,
			'end'                  => $this->today,
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'type'                 => 'impressions',
			'unique'               => 0,
			'select'               => array()
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		$sdate = mktime(0,0,0,$args['month'], $args['day'], $args['year']);
		$edate = mktime(23,59,59,$args['month'], $args['day'], $args['year']);
		$unique_str = $args['unique'] ? 'unique_' : '';
		$select = $this->decode_array( $args['select'] );
		
		if( !empty($select) )
		{
			$cnt = 0;
			$stats = $this->load_daily_stats(array(
				'select' => 'data', 
				'where'  => 'time >= '.$sdate.' AND time <= '.$edate,
				'limit'  => 1
			));
			//echo '<pre>'.print_r(json_decode($stats[0]->data,true),true).'</pre>';
			if( !empty($stats) )
			{
				$array = json_decode($stats[0]->data,true);
				$array = $this->filter_stats_array($array, $select);
				//echo '<pre>'.print_r($array,true).'</pre>';
				//echo date('d.m.Y H:i', 1490580000);
				foreach($array as $key => $arr)
				{
					if(!empty($arr))
					{
						//echo '<pre>'.print_r($arr,true).'</pre><br>';
						$cnt+= array_key_exists('hourly_'.$unique_str.$args['type'], $arr) ? $arr['hourly_'.$unique_str.$args['type']] : 0;
					}
				}
			}
		
			return $cnt;
		}
		else
		{
			$stats = $this->load_daily_stats(array(
				'select' => $unique_str.$args['type'], 
				'where'  => 'time >= '.$sdate.' AND time <= '.$edate,
				'limit'  => 1
			));
		
			return !empty($stats) ? $stats[0]->{$unique_str.$args['type']} : 0;
		}
	}
	
	
	
	
	
	/**
	 * > v5.0.5 - Get monthly stats
	 *
	 * @access public
	 * @return int
	*/
	public function get_monthly_stats($args = array())
	{
		global $pro_ads_multisite;
		
		$am_days = cal_days_in_month(CAL_GREGORIAN, $args['month'], $args['year']);
		
		$defaults = array(
			'stats'                => array(),
			'start'                => mktime(0,0,0, $this->month, 1, $this->year),
			'end'                  => mktime(0,0,0, $this->month, $am_days, $this->year),
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'type'                 => 'impressions',
			'unique'               => 0,
			'select'               => array()
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		// load stats array
		$cnt = 0;	
		
		if( !empty($args['select']) && $args['select'] != 'W10=')
		{
			$stats = $this->create_stats_array(array('stats' => $args['stats'], 'start' => $args['start'], 'end' => $args['end'], 'select' => $args['select']));
			
			for( $i = 1; $i <= $am_days; $i++ )
			{
				if( !empty($stats[$args['year']][$args['month']][$i]))
				{
					$cnt += $this->get_daily_stats(
						array(
							'stats'   => $stats,
							'start'   => $args['start'],
							'end'     => $args['end'],
							'year'    => $args['year'],
							'month'   => $args['month'],
							'day'     => $i,
							'type'    => $args['type'],
							'unique'  => $args['unique'],
							'select'  => $args['select']
						)
					);
				}
			}
		}
		else
		{
			for( $i = 1; $i <= $am_days; $i++ )
			{
				$sdate = mktime(0,0,0,$args['month'], $i, $args['year']);
				$edate = mktime(23,59,59,$args['month'], $i, $args['year']);
				
				$stats = $this->load_stats(array(
					'select' => $args['type'],
					'where'  => 'time >= '.$sdate.' AND time <= '.$edate
				));
				
				$cnt += $stats[0]->{$args['type']};
			}
		}
		
		return $cnt;
	}
	
	
	
	public function _get_monthly_stats($args = array())
	{
		$am_days = cal_days_in_month(CAL_GREGORIAN, $args['month'], $args['year']);
		
		$defaults = array(
			'stats'                => array(),
			'start'                => mktime(0,0,0, $this->month, 1, $this->year),
			'end'                  => mktime(0,0,0, $this->month, $am_days, $this->year),
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'type'                 => 'impressions',
			'unique'               => 0,
			'select'               => array()
		);
		
		$args = wp_parse_args( $args, $defaults );
		$cnt = 0;
		
		for( $d = 1; $d <= $am_days; $d++ )
		{	
			$cnt += $this->_get_daily_stats(
				array(
					'year'    => $args['year'],
					'month'   => $args['month'],
					'day'     => $d,
					'type'    => $args['type'],
					'unique'  => $args['unique'],
					'select'  => $args['select']
				)
			);
		}
		
		return $cnt;
	}
	
	
	
	
	
	
	
	/**
	 * > v5.0.5 - Get yearly stats
	 *
	 * @access public
	 * @return int
	*/
	public function get_yearly_stats($args = array())
	{
		global $pro_ads_multisite;
		
		$defaults = array(
			'stats'                => array(),
			'start'                => mktime(0,0,0, 1, 1, $this->year),
			'end'                  => mktime(23,59,59, 12, 31, $this->year),
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'type'                 => 'impressions',
			'unique'               => 0,
			'select'               => array()
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		// load stats array
		$stats = $this->create_stats_array(array('stats' => $args['stats'], 'start' => $args['start'], 'end' => $args['end'], 'select' => $args['select']));
		//print_r($stats);
		$cnt = 0;
		for( $i = 1; $i <= 12; $i++ )
		{
			if( !empty($stats[$args['year']][$i]))
			{
				$cnt += $this->get_monthly_stats(
					array(
						'stats'   => $stats,
						'year'    => $args['year'],
						'month'   => $i,
						'day'     => $args['day'],
						'start'   => $args['start'],
						'end'     => $args['end'],
						'type'    => $args['type'],
						'unique'  => $args['unique'],
						'select'  => $args['select']
					)
				);
			}
		}
			
		return $cnt;
	}
	
	
	public function _get_yearly_stats($args = array())
	{
		$defaults = array(
			'start'                => mktime(0,0,0, 1, 1, $this->year),
			'end'                  => mktime(23,59,59, 12, 31, $this->year),
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'type'                 => 'impressions',
			'unique'               => 0,
			'select'               => array()
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		$cnt = 0;
		for( $i = 1; $i <= 12; $i++ )
		{
			$cnt += $this->_get_monthly_stats(
				array(
					'year'    => $args['year'],
					'month'   => $i,
					'day'     => $args['day'],
					'start'   => $args['start'],
					'end'     => $args['end'],
					'type'    => $args['type'],
					'unique'  => $args['unique'],
					'select'  => $args['select']
				)
			);
		}
		
		return $cnt;
	}
	
	
	
	
	
	
	
	/**
	 * > v5.0.5 - Get all time stats
	 *
	 * @access public
	 * @return int
	*/
	public function get_alltime_stats($args = array())
	{
		global $pro_ads_multisite;
		
		$defaults = array(
			'stats'                => array(),
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'type'                 => 'impressions',
			'unique'               => 0,
			'select'               => array()
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		$years = $this->get_stat_years();
		
		if( empty($args['stats']))
		{
			$l = count($years)-1;
			
			$start = mktime(0,0,0, 1, 1, $years[0]);
			$end = mktime(0,0,0, 12, 31, $years[$l]);
			
			// load stats array
			$stats = $this->create_stats_array(array('stats' => $args['stats'], 'start' => $start, 'end' => $end, 'select' => $args['select']));
		}
		else
		{
			$stats = $args['stats'];	
		}
		
		
		//print_r($stats);
		$cnt = 0;
		foreach( $years as $year )
		{
			$cnt += $this->get_yearly_stats(
				array(
					'stats'   => $stats,
					'year'    => $year,
					'start'   => mktime(0,0,0, 1, 1, $year),
					'end'     => mktime(23,59,59, 12, 31, $year),
					'month'   => $args['month'],
					'day'     => $args['day'],
					'type'    => $args['type'],
					'unique'  => $args['unique'],
					'select'  => $args['select']
				)
			);
		}
			
		return $cnt;
	}
	
	
	
	public function _get_alltime_stats($args = array())
	{
		$defaults = array(
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'type'                 => 'impressions',
			'unique'               => 0,
			'select'               => array()
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		$years = $this->get_stat_years();
		
		$cnt = 0;
		foreach( $years as $year )
		{
			$cnt += $this->_get_yearly_stats(
				array(
					'year'    => $year,
					'start'   => mktime(0,0,0, 1, 1, $year),
					'end'     => mktime(23,59,59, 12, 31, $year),
					'month'   => $args['month'],
					'day'     => $args['day'],
					'type'    => $args['type'],
					'unique'  => $args['unique'],
					'select'  => $args['select']
				)
			);
		}
		
		return $cnt;
	}
	
	
	
	
	
	
	/**
	 * Daily Device Stats
	 *
	 * @access public
	 * @return arr
	*/
	public function count_daily_device_stats($args = array())
	{
		$defaults = array(
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'unique'               => 0,
			'select'               => array(),
			'device_count'         => array('desktop' => 0, 'tablet'  => 0, 'mobile'  => 0, 'unknown' => 0)
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		$select = $this->decode_array( $args['select'] );
		$sdate = mktime(0,0,0,$args['month'], $args['day'], $args['year']);
		$edate = mktime(23,59,59,$args['month'], $args['day'], $args['year']);
			
		$stats = $this->load_daily_stats(array(
			'select' => 'data', 
			'where'  => 'time >= '.$sdate.' AND time <= '.$edate,
			'limit'  => 1
		));
		
		if(!empty($stats))
		{
			foreach(json_decode($stats[0]->data,true) as $stat)
			{
				if(!empty($stat))
				{
					if(is_array($stat['user_data']['device']))
					{
						$key = key($stat['user_data']['device']);
						//echo $args['device_count'][$key]. ' - '.$stat['user_data']['device'];
						$args['device_count'][$key]+= $stat['user_data']['device'][$key];
						//print_r($stat['user_data']['device'][$key]);
					}
				}
			}
		}
		
		return $args['device_count'];
	}
	
	
	
	
	
	/**
	 * Monthly Device Stats
	 *
	 * @access public
	 * @return arr
	*/
	public function count_monthly_device_stats($args = array())
	{
		$defaults = array(
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'unique'               => 0,
			'select'               => array(),
			'device_count'         => array('desktop' => 0, 'tablet'  => 0, 'mobile'  => 0, 'unknown' => 0)
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		$am_days = cal_days_in_month(CAL_GREGORIAN, $args['month'], $args['year']);
		
		for( $i = 1; $i <= $am_days; $i++ )
		{
			$args['device_count'] = $this->count_daily_device_stats(wp_parse_args(array('day' => $i), $args));
		}
		
		return $args['device_count'];
	}
	
	
	
	/**
	 * Yearly Device Stats
	 *
	 * @access public
	 * @return arr
	*/
	public function count_yearly_device_stats($args = array())
	{
		$defaults = array(   
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'unique'               => 0,
			'select'               => array(),
			'device_count'         => array('desktop' => 0, 'tablet'  => 0, 'mobile'  => 0, 'unknown' => 0)
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		for( $i = 1; $i <= 12; $i++ )
		{
			$args['device_count'] = $this->count_monthly_device_stats(wp_parse_args(array('month' => $i), $args));
		}
		
		return $args['device_count'];
	}
	
	
	
	
	/**
	 * All Time Device Stats
	 *
	 * @access public
	 * @return arr
	*/
	public function count_all_device_stats($args = array())
	{
		$defaults = array(
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'unique'               => 0,
			'select'               => array(),
			'device_count'         => array('desktop' => 0, 'tablet'  => 0, 'mobile'  => 0, 'unknown' => 0)
		);
		
		$args = wp_parse_args( $args, $defaults );
	
		$years_all = $this->get_stat_years();
		
		foreach($years_all as $year)
		{
			$args['device_count'] = $this->count_yearly_device_stats(wp_parse_args(array('year' => $year), $args));
		}
		
		return $args['device_count'];
	}
	
	
	
	
	
	
	
	
	
	
	/**
	 * Graph data values
	*/
	public function graph_data($args = array())
	{
		$defaults = array(
			'stats'                => array(),
			's_type'               => 'day',
			'type'                 => 'impressions',     
			'year'                 => $this->year,
			'month'                => $this->month,
			'day'                  => $this->day,
			'unique'               => 0,
			'select'               => array()
		);
		
		$args = wp_parse_args( $args, $defaults );
		
		$html = '';
		$select = $this->decode_array( $args['select'] );
		$unique_str = $args['unique'] ? 'unique_' : '';
		
		// Daily stats data
		if( $args['s_type'] == 'day' )
		{
			//echo '<pre>'.print_r(json_decode($args['stats'][0]->data,true),true).'</pre>';
			if(!empty($args['stats']))
			{
				$sdate = mktime(0,0,0,$args['month'], $args['day'], $args['year']);
				$edate = mktime(23,59,59,$args['month'], $args['day'], $args['year']);
			
				foreach($args['stats'] as $stats)
				{
					$cnt = 0;
					if( !empty($stats) )
					{
						$array = json_decode($stats->data,true);
						//echo '<pre>'.print_r($array,true).'</pre>';
						$array = !empty($select) ? $this->filter_stats_array($array, $select) : $array;
						
						$h = 0;
						foreach($array as $timestamp => $arr)
						{	
							//echo date('d.m.Y - H:i',$timestamp).' :: '.date('d.m.Y - H:i',current_time('timestamp')).'<br>';
							if( $timestamp >= $sdate && $timestamp <= $edate)
							{
								//echo $h.' - '.date('d.m.Y - H:i',$timestamp).'<br>';
								$cnt = array_key_exists('hourly_'.$unique_str.$args['type'], $arr) ? $arr['hourly_'.$unique_str.$args['type']] : 0;
								$cnt = !empty($cnt) ? $cnt : 0;
								//echo $h.' '.$cnt.'<br>';
								$html.= '["'.$h.'", '.$cnt.'],';
								$h++;
							}
							//if($h > 23){ break; }
						}
					}
					else
					{
						for($h=0; $h < 24; $h++)
						{
							$html.= '["'.$h.'", 0],';
						}
					}
				}
			}
			else
			{
				for($h=0; $h < 24; $h++)
				{
					$html.= '["'.$h.'", 0],';
				}
			}
		}
		elseif( $args['s_type'] == 'month' )
		{
			$am_days = cal_days_in_month(CAL_GREGORIAN, $args['month'], $args['year']);
			
			for( $i = 1; $i <= $am_days; $i++ )
			{
				$sdate = mktime(0,0,0,$args['month'], $i, $args['year']);
				$edate = mktime(23,59,59,$args['month'], $i, $args['year']);
				
				$cnt = $this->_get_daily_stats(
					array(
						'start'  => $sdate,
						'end'    => $edate,
						'year'   => $args['year'],
						'month'  => $args['month'],
						'day'    => $i,
						'type'   => $args['type'],
						'unique' => $args['unique'],
						'select' => $args['select']
					)
				);
				
				$html.= '["'.$i.'", '.$cnt.'],';
			}
		}
		elseif( $args['s_type'] == 'year' )
		{
			for( $i = 1; $i <= 12; $i++ )
			{
				$cnt = $this->_get_monthly_stats(
					array(
						'year' => $args['year'],
						'month' => $i,
						'type' => $args['type'],
						'unique' => $args['unique'],
						'select' => $args['select']
					)
				);
				$html.= '["'.$i.'", '.$cnt.'],';
			}
		}
		elseif( $args['s_type'] == 'all' )
		{	
			// All Time Stats
			$years_arr = $this->get_stat_years();
			
			$html.= '["'.$years_arr[0].'", 0],';
			
			
			if( !empty($years_arr) )
			{
				foreach($years_arr as $year)
				{
					$cnt = $this->_get_yearly_stats(wp_parse_args( array('year' => $year), $args));
					$html.= '["'.$year.'", '.$cnt.'],';
				}
			}
			else
			{
				$html.= '["'.date('Y').'", 0],';
			}
		}
		
		
		return $html;
	}
	
	
	
	
	
	
	
	
	
	
	/**
	 * Encode array
	 *
	 * @access public
	 * @return array
	*/
	public function encode_array( $array )
	{
		if( is_array($array) )
		{
			$string = base64_encode(json_encode($array));
			return $string;
		}
		else
		{
			return $array;	
		}
	}
	
	
	
	
	/**
	 * Check if array needs to be decoded
	 *
	 * @access public
	 * @return array
	*/
	public function decode_array( $string )
	{
		if( !is_array($string) )
		{
			$string = $this->validBase64($string) ? base64_decode($string) : $string;
			return json_decode($string, true);
		}
		else
		{
			return $string;	
		}
	}
	
	
	
	/**
	 * Check if string is base64 encoded. 
	 *
	 * @access public
	 * @return array
	*/
	public function validBase64($string)
	{
        $decoded = base64_decode($string, true);
        // Check if there is no invalid character in strin
        if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $string)) return false;

        // Decode the string in strict mode and send the responce
         if(!base64_decode($string, true)) return false;

        // Encode and compare it to origional one
        if(base64_encode($decoded) != $string) return false;

        return true;
    }
	
	
	
	
	
	
	
	
	/**
	 * Get array keys for all years from the stats array.
	*/
	public function get_stat_years()
	{
		$years = array();
		
		$first_year = $this->load_stats(array('select' => 'time', 'order' => 'id ASC', 'limit' => 1));
		
		$first_year = !empty($first_year) ? date_i18n('Y', $first_year[0]->time) : date_i18n('Y')-1;
		$last_year = date_i18n('Y');
		
		// Years array
		$years[0] = $first_year == $last_year ? $first_year - 1 : $first_year; // first year
		$years[1] = $last_year; // current year
		
		$dif = $years[1] - $years[0];
		
		if( $dif > 1 )
		{
			$y = 0;
			for($i = 1; $i < $dif; $i++)
			{
				$y = $y == 0 ? $years[0] + 1 : $y + 1;
				array_push($years, $y);
			}
		}
		
		// Sort years
		sort( $years );
		array_values($years);
		
		return $years;
	}
	
	
	
	
	
	
	
	
	/*
	 * PDF Invoice template
	*/ 
	function wpproads_pdf_template( $pdf_template_path )
	{	
		if(isset($_GET['stats_pdf']) && !empty($_GET['stats_pdf'])) 
		{
			$data = unserialize(htmlspecialchars_decode(base64_decode($_GET['data'])));
			
			$this->wpproads_save_stats_pdf($data);
		}
		
		return $pdf_template_path;
	}
	
	
	
	/*
	 * Save PDF
	 *
	 * This function creates the PDF invoice
	 * there are 2 options
	 * - view (will show the invoice in the browser)
	 * - save (will save the invoice to your computer)
	 *
	 * @access public
	 * @return html
	*/
	public function wpproads_save_stats_pdf( $args = array() )
	{
		if(isset($_GET['stats_pdf']) && !empty($_GET['stats_pdf'])) 
		{	
			require_once(WP_ADS_INC_DIR.'/tcpdf/tcpdf_include.php');
			
			$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
			$pdf->AddPage();

			// set margins
			$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
			$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
			
			if ( $html = locate_template( array( 'wpproads/stats-pdf.php' ) ) ) 
			{
				include( $html );
			}
			else
			{
				include( WP_ADS_TPL_DIR.'/pdf/stats-pdf.php');
			}
			
			// Print text using writeHTMLCell()
			$pdf->writeHTMLCell(0, 0, '', '', $html, 0, 1, 0, true, '', true);
			
			// ---------------------------------------------------------
			
			// Close and output PDF document
			// This method has several options, check the source code documentation for more information.
			// https://tcpdf.org/docs/source_docs/classTCPDF/#a3d6dcb62298ec9d42e9125ee2f5b23a1
			$pdf->Output('stats.pdf', 'I');
			
			exit();
		}
	}
	
	
	
	
	
	/*
	 * Save action with Google Analitics
	 *
	 * https://support.google.com/analytics/answer/1033068?hl=en 
	 *
	 * @access public
	 * @return html
	*/
	public function save_ga_action( $args )
	{
		if( !empty(	$args['google_analytics_id'] ))
		{
			$loops = array('banner', 'adzone', 'advertiser');
			
			//set POST variables
			$url = 'http://www.google-analytics.com/collect';
			
			foreach( $loops as $loop )
			{
				$data = get_post($args[$loop.'_id'], ARRAY_A);
				
				if($args['type'] != 'clicks')
				{	
					// http://tunasite.com/helpdesk/ftopic/google-analytics-integration-is-unusable/
					echo "<script>if(typeof wppas_ga != 'undefined'){wppas_ga('send', 'event', 'wpproads ".$loop." statistics', '".$args['type']."', '".$loop.': '.$data['post_name'].'-'.$args[$loop.'_id']."',{nonInteraction: true});}</script>";
					
				}
				else
				{
					// https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters
					$fields_string = '';
					$fields = array(
						'v'   => 1,
						'tid' => $args['google_analytics_id'],
						'cid' => 5555,
						't'   => 'event',
						'ec'  => 'wpproads '.$loop.' statistics',
						'ea'  => $args['type'],
						'el'  => $loop.': '.$data['post_name'].'-'.$args[$loop.'_id'],
						'ni'  => 1
					);
					
					//url-ify the data for the POST
					foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
					rtrim($fields_string, '&');
					
					$ch = curl_init();
					curl_setopt($ch,CURLOPT_URL, $url); //curl the url
					curl_setopt($ch,CURLOPT_POST, count($fields));
					curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
					curl_setopt($ch,CURLOPT_RETURNTRANSFER, TRUE); //return the transfer to be later saved to a variable
					$result = curl_exec($ch);
					
					//close connection
					curl_close($ch);
				}
			}
		}
	}
	
}
?>