<?php
/*
	This is the primary set of functions used to calculate the statistics, they are available for other developers to call.
	
	NOTE:  Many of the functions return an MySQL result object, using this object like a variable (ie. echo $result) will output 
		   the number of rows returned, but you can also use it an a foreach loop to to get the details of the rows.
*/

// This function returns the current users online.
function wp_statistics_useronline() {

	global $wpdb;

	return $wpdb->query("SELECT * FROM {$wpdb->prefix}statistics_useronline");
}

// This function get the visit statistics for a given time frame.
function wp_statistics_visit( $time, $daily = null ) {

	// We need database and the global $WP_Statistics object access.
	global $wpdb, $WP_Statistics;

	// If we've been asked to do a daily count, it's a slightly different SQL query, so handle it separately.
	if ( $daily == true ) {

		// Fetch the results from the database.
		$result = $wpdb->get_row(
			"SELECT * FROM {$wpdb->prefix}statistics_visit WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', $time )}'"
		);

		// If we have a result, return it, otherwise force a 0 to be returned instead of the logical FALSE that would otherwise be the case.
		if ( $result ) {
			return $result->visit;
		} else {
			return 0;
		}

	} else {

		// This function accepts several options for time parameter, each one has a unique SQL query string.
		// They're pretty self explanatory.

		switch ( $time ) {
			case 'today':
				$result = $wpdb->get_var(
					"SELECT SUM(visit) FROM {$wpdb->prefix}statistics_visit WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d' )}'"
				);
			break;

			case 'yesterday':
				$result = $wpdb->get_var(
					"SELECT SUM(visit) FROM {$wpdb->prefix}statistics_visit WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', -1 )}'"
				);
			break;

			case 'week':
				$result = $wpdb->get_var(
					"SELECT SUM(visit) FROM {$wpdb->prefix}statistics_visit WHERE `last_counter` BETWEEN '{$WP_Statistics->Current_Date( 'Y-m-d', -7 )}' AND '{$WP_Statistics->Current_Date( 'Y-m-d' )}'"
				);
			break;

			case 'month':
				$result = $wpdb->get_var(
					"SELECT SUM(visit) FROM {$wpdb->prefix}statistics_visit WHERE `last_counter` BETWEEN '{$WP_Statistics->Current_Date( 'Y-m-d', -30 )}' AND '{$WP_Statistics->Current_Date( 'Y-m-d' )}'"
				);
			break;

			case 'year':
				$result = $wpdb->get_var(
					"SELECT SUM(visit) FROM {$wpdb->prefix}statistics_visit WHERE `last_counter` BETWEEN '{$WP_Statistics->Current_Date( 'Y-m-d', -365 )}' AND '{$WP_Statistics->Current_Date( 'Y-m-d' )}'"
				);
			break;

			case 'total':
				$result = $wpdb->get_var("SELECT SUM(visit) FROM {$wpdb->prefix}statistics_visit");
				$result += $WP_Statistics->Get_Historical_Data('visits');
			break;

			default:
				$result = $wpdb->get_var(
					"SELECT SUM(visit) FROM {$wpdb->prefix}statistics_visit WHERE `last_counter` BETWEEN '{$WP_Statistics->Current_Date( 'Y-m-d', $time )}' AND '{$WP_Statistics->Current_Date( 'Y-m-d' )}'"
				);
			break;
		}
	}

	// If we have a result, return it, otherwise force a 0 to be returned instead of the logical FALSE that would otherwise be the case.
	if ( $result == null ) {
		$result = 0;
	}

	return $result;
}

// This function gets the visitor statistics for a given time frame.
function wp_statistics_visitor( $time, $daily = null, $countonly = false ) {

	// We need database and the global $WP_Statistics object access.
	global $wpdb, $WP_Statistics;

	$history      = 0;
	$select       = '*';
	$sqlstatement = '';

	// We often don't need the complete results but just the count of rows, if that's the case, let's have MySQL just count the results for us.
	if ( $countonly == true ) {
		$select = 'count(last_counter)';
	}

	// If we've been asked to do a daily count, it's a slightly different SQL query, so handle it seperatly.
	if ( $daily == true ) {

		// Fetch the results from the database.
		$result = $wpdb->query(
			"SELECT {$select} FROM {$wpdb->prefix}statistics_visitor WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', $time )}'"
		);

		return $result;

	} else {

		// This function accepts several options for time parameter, each one has a unique SQL query string.
		// They're pretty self explanatory.
		switch ( $time ) {
			case 'today':
				$sqlstatement
					= "SELECT {$select} FROM {$wpdb->prefix}statistics_visitor WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d' )}'";
			break;

			case 'yesterday':
				$sqlstatement
					= "SELECT {$select} FROM {$wpdb->prefix}statistics_visitor WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', -1 )}'";
			break;

			case 'week':
				$sqlstatement
					= "SELECT {$select} FROM {$wpdb->prefix}statistics_visitor WHERE `last_counter` BETWEEN '{$WP_Statistics->Current_Date( 'Y-m-d', -7 )}' AND '{$WP_Statistics->Current_Date( 'Y-m-d' )}'";
			break;

			case 'month':
				$sqlstatement
					= "SELECT {$select} FROM {$wpdb->prefix}statistics_visitor WHERE `last_counter` BETWEEN '{$WP_Statistics->Current_Date( 'Y-m-d', -30 )}' AND '{$WP_Statistics->Current_Date( 'Y-m-d' )}'";
			break;

			case 'year':
				$sqlstatement
					= "SELECT {$select} FROM {$wpdb->prefix}statistics_visitor WHERE `last_counter` BETWEEN '{$WP_Statistics->Current_Date( 'Y-m-d', -365 )}' AND '{$WP_Statistics->Current_Date( 'Y-m-d' )}'";
			break;

			case 'total':
				$sqlstatement = "SELECT {$select} FROM {$wpdb->prefix}statistics_visitor";
				$history      = $WP_Statistics->Get_Historical_Data('visitors');
			break;

			default:
				$sqlstatement
					= "SELECT {$select} FROM {$wpdb->prefix}statistics_visitor WHERE `last_counter` BETWEEN '{$WP_Statistics->Current_Date( 'Y-m-d', $time )}' AND '{$WP_Statistics->Current_Date( 'Y-m-d' )}'";
			break;
		}
	}

	// Execute the SQL call, if we're only counting we can use get_var(), otherwise we use query().
	if ( $countonly == true ) {
		$result = $wpdb->get_var($sqlstatement);
		$result += $history;
	} else {
		$result = $wpdb->query($sqlstatement);
	}

	return $result;
}

// This function returns the statistics for a given page.
function wp_statistics_pages( $time, $page_uri = '', $id = -1, $rangestartdate = null, $rangeenddate = null ) {

	// We need database and the global $WP_Statistics object access.
	global $wpdb, $WP_Statistics;

	$history      = 0;
	$sqlstatement = '';

	// If no page URI has been passed in, get the current page URI.
	if ( $page_uri == '' ) {
		$page_uri = wp_statistics_get_uri();
	}

	$page_uri_sql = esc_sql($page_uri);

	// If a page/post ID has been passed, use it to select the rows, otherwise use the URI.
	//  Note that a single page/post ID can have multiple URI's associated with it.
	if ( $id != -1 ) {
		$page_sql    = '`id` = ' . absint($id);
		$history_key = 'page';
		$history_id  = absint($id);
	} else {
		$page_sql    = "`URI` = '{$page_uri_sql}'";
		$history_key = 'uri';
		$history_id  = $page_uri;
	}

	// This function accepts several options for time parameter, each one has a unique SQL query string.
	// They're pretty self explanatory.
	switch ( $time ) {
		case 'today':
			$sqlstatement
				= "SELECT SUM(count) FROM {$wpdb->prefix}statistics_pages WHERE `date` = '{$WP_Statistics->Current_Date( 'Y-m-d' )}' AND {$page_sql}";
		break;

		case 'yesterday':
			$sqlstatement
				= "SELECT SUM(count) FROM {$wpdb->prefix}statistics_pages WHERE `date` = '{$WP_Statistics->Current_Date( 'Y-m-d', -1 )}' AND {$page_sql}";
		break;

		case 'week':
			$sqlstatement
				= "SELECT SUM(count) FROM {$wpdb->prefix}statistics_pages WHERE `date` BETWEEN '{$WP_Statistics->Current_Date( 'Y-m-d', -7 )}' AND '{$WP_Statistics->Current_Date( 'Y-m-d' )}' AND {$page_sql}";
		break;

		case 'month':
			$sqlstatement
				= "SELECT SUM(count) FROM {$wpdb->prefix}statistics_pages WHERE `date` BETWEEN '{$WP_Statistics->Current_Date( 'Y-m-d', -30 )}' AND '{$WP_Statistics->Current_Date( 'Y-m-d' )}' AND {$page_sql}";
		break;

		case 'year':
			$sqlstatement
				= "SELECT SUM(count) FROM {$wpdb->prefix}statistics_pages WHERE `date` BETWEEN '{$WP_Statistics->Current_Date( 'Y-m-d', -365 )}' AND '{$WP_Statistics->Current_Date( 'Y-m-d' )}' AND {$page_sql}";
		break;

		case 'total':
			$sqlstatement = "SELECT SUM(count) FROM {$wpdb->prefix}statistics_pages WHERE {$page_sql}";
			$history      = $WP_Statistics->Get_Historical_Data($history_key, $history_id);
		break;
		case 'range':
			$sqlstatement = "SELECT SUM(count) FROM {$wpdb->prefix}statistics_pages WHERE `date` BETWEEN '" .
			                $WP_Statistics->Current_Date('Y-m-d', '-0', strtotime($rangestartdate)) .
			                "' AND '" .
			                $WP_Statistics->Current_Date('Y-m-d', '-0', strtotime($rangeenddate)) .
			                "' AND {$page_sql}";

		break;
		default:
			$sqlstatement
				= "SELECT SUM(count) FROM {$wpdb->prefix}statistics_pages WHERE `date` = '{$WP_Statistics->Current_Date( 'Y-m-d', $time )}' AND {$page_sql}";
		break;
	}

	// Since this function only every returns a count, just use get_var().
	$result = $wpdb->get_var($sqlstatement);
	$result += $history;

	// If we have an empty result, return 0 instead of a blank.
	if ( $result == '' ) {
		$result = 0;
	}

	return $result;
}

// This function converts a page URI to a page/post ID.  It does this by looking up in the pages database
// the URI and getting the associated ID.  This will only work if the page has been visited at least once.
function wp_statistics_uri_to_id( $uri ) {
	global $wpdb;

	// Create the SQL query to use.
	$sqlstatement = $wpdb->prepare(
		"SELECT id FROM {$wpdb->prefix}statistics_pages WHERE `URI` = %s AND id > 0 ORDER BY date DESC",
		$uri
	);

	// Execute the query.
	$result = $wpdb->get_var($sqlstatement);

	// If we returned a false or some other 0 equivalent value, make sure $result is set to an integer 0.
	if ( $result == 0 ) {
		$result = 0;
	}

	return $result;
}

// We need a quick function to pass to usort to properly sort the most popular pages.
function wp_stats_compare_uri_hits( $a, $b ) {
	return $a[1] < $b[1];
}

// This function returns a multi-dimensional array, with the total number of pages and an array or URI's sorted in order with their URI, count, id and title.
function wp_statistics_get_top_pages( $rangestartdate = null, $rangeenddate = null ) {
	global $wpdb;

	// Get every unique URI from the pages database.
	if ( $rangestartdate != null && $rangeenddate != null ) {
		$result = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT DISTINCT uri FROM {$wpdb->prefix}statistics_pages WHERE `date` BETWEEN %s AND %s",
				$rangestartdate,
				$rangeenddate
			),
			ARRAY_N
		);
	} else {
		$result = $wpdb->get_results("SELECT DISTINCT uri FROM {$wpdb->prefix}statistics_pages", ARRAY_N);
	}

	$total = 0;
	$uris  = array();

	// Now get the total page visit count for each unique URI.
	foreach ( $result as $out ) {
		// Increment the total number of results.
		$total++;

		// Retreive the post ID for the URI.
		$id = wp_statistics_uri_to_id($out[0]);

		// Lookup the post title.
		$post = get_post($id);

		if ( is_object($post) ) {
			$title = $post->post_title;
		} else {
			if ( $out[0] == '/' ) {
				$title = get_bloginfo();
			} else {
				$title = '';
			}
		}

		// Add the current post to the array.
		if ( $rangestartdate != null && $rangeenddate != null ) {
			$uris[] = array(
				$out[0],
				wp_statistics_pages('range', $out[0], -1, $rangestartdate, $rangeenddate),
				$id,
				$title,
			);
		} else {
			$uris[] = array( $out[0], wp_statistics_pages('total', $out[0]), $id, $title );
		}
	}

	// If we have more than one result, let's sort them using usort.
	if ( count($uris) > 1 ) {
		// Sort the URI's based on their hit count.
		usort($uris, 'wp_stats_compare_uri_hits');
	}

	return array( $total, $uris );
}

// This function gets the current page URI.
function wp_statistics_get_uri() {
	// Get the site's path from the URL.
	$site_uri     = parse_url(site_url(), PHP_URL_PATH);
	$site_uri_len = strlen($site_uri);

	// Get the site's path from the URL.
	$home_uri     = parse_url(home_url(), PHP_URL_PATH);
	$home_uri_len = strlen($home_uri);

	// Get the current page URI.
	$page_uri = $_SERVER["REQUEST_URI"];

	/*
	 * We need to check which URI is longer in case one contains the other.
	 *
	 * For example home_uri might be "/site/wp" and site_uri might be "/site".
	 *
	 * In that case we want to check to see if the page_uri starts with "/site/wp" before
	 * we check for "/site", but in the reverse case, we need to swap the order of the check.
	 */
	if ( $site_uri_len > $home_uri_len ) {
		if ( substr($page_uri, 0, $site_uri_len) == $site_uri ) {
			$page_uri = substr($page_uri, $site_uri_len);
		}

		if ( substr($page_uri, 0, $home_uri_len) == $home_uri ) {
			$page_uri = substr($page_uri, $home_uri_len);
		}
	} else {
		if ( substr($page_uri, 0, $home_uri_len) == $home_uri ) {
			$page_uri = substr($page_uri, $home_uri_len);
		}

		if ( substr($page_uri, 0, $site_uri_len) == $site_uri ) {
			$page_uri = substr($page_uri, $site_uri_len);
		}
	}

	// If we're at the root (aka the URI is blank), let's make sure to indicate it.
	if ( $page_uri == '' ) {
		$page_uri = '/';
	}

	return $page_uri;
}

// This function returns all unique user agents in the database.
function wp_statistics_ua_list( $rangestartdate = null, $rangeenddate = null ) {

	global $wpdb;

	if ( $rangestartdate != null && $rangeenddate != null ) {
		$result = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT DISTINCT agent FROM {$wpdb->prefix}statistics_visitor AND `last_counter` BETWEEN %s AND %s",
				$rangestartdate,
				$rangeenddate
			),
			ARRAY_N
		);
	} else {
		$result = $wpdb->get_results("SELECT DISTINCT agent FROM {$wpdb->prefix}statistics_visitor", ARRAY_N);
	}

	$Browers = array();

	foreach ( $result as $out ) {
		$Browsers[] = $out[0];
	}

	return $Browsers;
}

// This function returns the count of a given user agent in the database.
function wp_statistics_useragent( $agent, $rangestartdate = null, $rangeenddate = null ) {

	global $wpdb;

	if ( $rangestartdate != null && $rangeenddate != null ) {
		$result = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT(agent) FROM {$wpdb->prefix}statistics_visitor WHERE `agent` = %s AND `last_counter` BETWEEN %s AND %s",
				$agent,
				$rangestartdate,
				$rangeenddate
			)
		);
	} else {
		$result = $wpdb->get_var(
			$wpdb->prepare("SELECT COUNT(agent) FROM {$wpdb->prefix}statistics_visitor WHERE `agent` = %s", $agent)
		);
	}

	return $result;
}

// This function returns all unique platform types from the database.
function wp_statistics_platform_list( $rangestartdate = null, $rangeenddate = null ) {

	global $wpdb;

	if ( $rangestartdate != null && $rangeenddate != null ) {
		$result = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT DISTINCT platform FROM {$wpdb->prefix}statistics_visitor WHERE `last_counter` BETWEEN %s AND %s",
				$rangestartdate,
				$rangeenddate
			),
			ARRAY_N
		);
	} else {
		$result = $wpdb->get_results("SELECT DISTINCT platform FROM {$wpdb->prefix}statistics_visitor", ARRAY_N);
	}

	$Platforms = array();

	foreach ( $result as $out ) {
		$Platforms[] = $out[0];
	}

	return $Platforms;
}

// This function returns the count of a given platform in the database.
function wp_statistics_platform( $platform, $rangestartdate = null, $rangeenddate = null ) {

	global $wpdb;

	if ( $rangestartdate != null && $rangeenddate != null ) {
		$result = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT(platform) FROM {$wpdb->prefix}statistics_visitor WHERE `platform` = %s AND `last_counter` BETWEEN %s AND %s",
				$platform,
				$rangestartdate,
				$rangeenddate
			)
		);
	} else {
		$result = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT(platform) FROM {$wpdb->prefix}statistics_visitor WHERE `platform` = %s",
				$platform
			)
		);
	}

	return $result;
}

// This function returns all unique versions for a given agent from the database.
function wp_statistics_agent_version_list( $agent, $rangestartdate = null, $rangeenddate = null ) {

	global $wpdb;

	if ( $rangestartdate != null && $rangeenddate != null ) {
		$result = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT DISTINCT version FROM {$wpdb->prefix}statistics_visitor WHERE agent = %s AND `last_counter` BETWEEN %s AND %s",
				$agent,
				$rangestartdate,
				$rangeenddate
			),
			ARRAY_N
		);
	} else {
		$result = $wpdb->get_results(
			$wpdb->prepare("SELECT DISTINCT version FROM {$wpdb->prefix}statistics_visitor WHERE agent = %s", $agent),
			ARRAY_N
		);
	}

	$Versions = array();

	foreach ( $result as $out ) {
		$Versions[] = $out[0];
	}

	return $Versions;
}

// This function returns the statistics for a given agent/version pair from the database.
function wp_statistics_agent_version( $agent, $version, $rangestartdate = null, $rangeenddate = null ) {

	global $wpdb;

	if ( $rangestartdate != null && $rangeenddate != null ) {
		$result = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT(version) FROM {$wpdb->prefix}statistics_visitor WHERE agent = %s AND version = %s AND `last_counter` BETWEEN %s AND %s",
				$agent,
				$version,
				$rangestartdate,
				$rangeenddate
			)
		);
	} else {
		$result = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT(version) FROM {$wpdb->prefix}statistics_visitor WHERE agent = %s AND version = %s",
				$agent,
				$version
			)
		);
	}

	return $result;
}

// This function returns an array or array's which define what search engines we should look for.
//
// By default will only return ones that have not been disabled by the user, this can be overridden by the $all parameter.
//
// Each sub array is made up of the following items:
//		name 		 = The proper name of the search engine
//		translated   = The proper name translated to the local language
//		tag 		 = a short one word, all lower case, representation of the search engine
//		sqlpattern   = either a single SQL style search pattern OR an array or search patterns to match the hostname in a URL against
//		regexpattern = either a single regex style search pattern OR an array or search patterns to match the hostname in a URL against
//		querykey 	 = the URL key that contains the search string for the search engine
//		image		 = the name of the image file to associate with this search engine (just the filename, no path info)
//
function wp_statistics_searchengine_list( $all = false ) {
	GLOBAL $WP_Statistics;

	$default = $engines = array(
		'ask'        => array(
			'name'         => 'Ask.com',
			'translated'   => __('Ask.com', 'wp-statistics'),
			'tag'          => 'ask',
			'sqlpattern'   => '%ask.com%',
			'regexpattern' => 'ask\.com',
			'querykey'     => 'q',
			'image'        => 'ask.png',
		),
		'baidu'      => array(
			'name'         => 'Baidu',
			'translated'   => __('Baidu', 'wp-statistics'),
			'tag'          => 'baidu',
			'sqlpattern'   => '%baidu.com%',
			'regexpattern' => 'baidu\.com',
			'querykey'     => 'wd',
			'image'        => 'baidu.png',
		),
		'bing'       => array(
			'name'         => 'Bing',
			'translated'   => __('Bing', 'wp-statistics'),
			'tag'          => 'bing',
			'sqlpattern'   => '%bing.com%',
			'regexpattern' => 'bing\.com',
			'querykey'     => 'q',
			'image'        => 'bing.png',
		),
		'clearch'    => array(
			'name'         => 'clearch.org',
			'translated'   => __('clearch.org', 'wp-statistics'),
			'tag'          => 'clearch',
			'sqlpattern'   => '%clearch.org%',
			'regexpattern' => 'clearch\.org',
			'querykey'     => 'q',
			'image'        => 'clearch.png',
		),
		'duckduckgo' => array(
			'name'         => 'DuckDuckGo',
			'translated'   => __('DuckDuckGo', 'wp-statistics'),
			'tag'          => 'duckduckgo',
			'sqlpattern'   => array( '%duckduckgo.com%', '%ddg.gg%' ),
			'regexpattern' => array( 'duckduckgo\.com', 'ddg\.gg' ),
			'querykey'     => 'q',
			'image'        => 'duckduckgo.png',
		),
		'google'     => array(
			'name'         => 'Google',
			'translated'   => __('Google', 'wp-statistics'),
			'tag'          => 'google',
			'sqlpattern'   => '%google.%',
			'regexpattern' => 'google\.',
			'querykey'     => 'q',
			'image'        => 'google.png',
		),
		'yahoo'      => array(
			'name'         => 'Yahoo!',
			'translated'   => __('Yahoo!', 'wp-statistics'),
			'tag'          => 'yahoo',
			'sqlpattern'   => '%yahoo.com%',
			'regexpattern' => 'yahoo\.com',
			'querykey'     => 'p',
			'image'        => 'yahoo.png',
		),
		'yandex'     => array(
			'name'         => 'Yandex',
			'translated'   => __('Yandex', 'wp-statistics'),
			'tag'          => 'yandex',
			'sqlpattern'   => '%yandex.ru%',
			'regexpattern' => 'yandex\.ru',
			'querykey'     => 'text',
			'image'        => 'yandex.png',
		),
	);

	if ( $all == false ) {
		foreach ( $engines as $key => $engine ) {
			if ( $WP_Statistics->get_option('disable_se_' . $engine['tag']) ) {
				unset( $engines[ $key ] );
			}
		}

		// If we've disabled all the search engines, reset the list back to default.
		if ( count($engines) == 0 ) {
			$engines = $default;
		}
	}

	return $engines;
}

// This function will return the SQL WHERE clause for getting the search words for a given search engine.
function wp_statistics_searchword_query( $search_engine = 'all' ) {
	GLOBAL $WP_Statistics;

	// Get a complete list of search engines
	$searchengine_list = wp_statistics_searchengine_list();
	$search_query      = '';

	if ( $WP_Statistics->get_option('search_converted') ) {
		// Are we getting results for all search engines or a specific one?
		if ( strtolower($search_engine) == 'all' ) {
			// For all of them?  Ok, look through the search engine list and create a SQL query string to get them all from the database.
			foreach ( $searchengine_list as $key => $se ) {
				$search_query .= "( `engine` = '{$key}' AND `words` <> '' ) OR ";
			}

			// Trim off the last ' OR ' for the loop above.
			$search_query = substr($search_query, 0, strlen($search_query) - 4);
		} else {
			$search_query .= "`engine` = '{$search_engine}' AND `words` <> ''";
		}
	} else {
		// Are we getting results for all search engines or a specific one?
		if ( strtolower($search_engine) == 'all' ) {
			// For all of them?  Ok, look through the search engine list and create a SQL query string to get them all from the database.
			// NOTE:  This SQL query can be *VERY* long.
			foreach ( $searchengine_list as $se ) {
				// The SQL pattern for a search engine may be an array if it has to handle multiple domains (like google.com and google.ca) or other factors.
				if ( is_array($se['sqlpattern']) ) {
					foreach ( $se['sqlpattern'] as $subse ) {
						$search_query .= "(`referred` LIKE '{$subse}{$se['querykey']}=%' AND `referred` NOT LIKE '{$subse}{$se['querykey']}=&%' AND `referred` NOT LIKE '{$subse}{$se['querykey']}=') OR ";
					}
				} else {
					$search_query .= "(`referred` LIKE '{$se['sqlpattern']}{$se['querykey']}=%' AND `referred` NOT LIKE '{$se['sqlpattern']}{$se['querykey']}=&%' AND `referred` NOT LIKE '{$se['sqlpattern']}{$se['querykey']}=')  OR ";
				}
			}

			// Trim off the last ' OR ' for the loop above.
			$search_query = substr($search_query, 0, strlen($search_query) - 4);
		} else {
			// For just one?  Ok, the SQL pattern for a search engine may be an array if it has to handle multiple domains (like google.com and google.ca) or other factors.
			if ( is_array($searchengine_list[ $search_engine ]['sqlpattern']) ) {
				foreach ( $searchengine_list[ $search_engine ]['sqlpattern'] as $se ) {
					$search_query .= "(`referred` LIKE '{$se}{$searchengine_list[$search_engine]['querykey']}=%' AND `referred` NOT LIKE '{$se}{$searchengine_list[$search_engine]['querykey']}=&%' AND `referred` NOT LIKE '{$se}{$searchengine_list[$search_engine]['querykey']}=') OR ";
				}

				// Trim off the last ' OR ' for the loop above.
				$search_query = substr($search_query, 0, strlen($search_query) - 4);
			} else {
				$search_query .= "(`referred` LIKE '{$searchengine_list[$search_engine]['sqlpattern']}{$searchengine_list[$search_engine]['querykey']}=%' AND `referred` NOT LIKE '{$searchengine_list[$search_engine]['sqlpattern']}{$searchengine_list[$search_engine]['querykey']}=&%' AND `referred` NOT LIKE '{$searchengine_list[$search_engine]['sqlpattern']}{$searchengine_list[$search_engine]['querykey']}=')";
			}
		}
	}

	return $search_query;
}

// This function will return the SQL WHERE clause for getting the search engine.
function wp_statistics_searchengine_query( $search_engine = 'all' ) {
	GLOBAL $WP_Statistics;

	// Get a complete list of search engines
	$searchengine_list = wp_statistics_searchengine_list();
	$search_query      = '';

	if ( $WP_Statistics->get_option('search_converted') ) {
		// Are we getting results for all search engines or a specific one?
		if ( strtolower($search_engine) == 'all' ) {
			// For all of them?  Ok, look through the search engine list and create a SQL query string to get them all from the database.
			foreach ( $searchengine_list as $key => $se ) {
				$key = esc_sql($key);
				$search_query .= "`engine` = '{$key}' OR ";
			}

			// Trim off the last ' OR ' for the loop above.
			$search_query = substr($search_query, 0, strlen($search_query) - 4);
		} else {
			$search_engine = esc_sql($search_engine);
			$search_query .= "`engine` = '{$search_engine}'";
		}
	} else {
		// Are we getting results for all search engines or a specific one?
		if ( strtolower($search_engine) == 'all' ) {
			// For all of them?  Ok, look through the search engine list and create a SQL query string to get them all from the database.
			// NOTE:  This SQL query can be long.
			foreach ( $searchengine_list as $se ) {
				// The SQL pattern for a search engine may be an array if it has to handle multiple domains (like google.com and google.ca) or other factors.
				if ( is_array($se['sqlpattern']) ) {
					foreach ( $se['sqlpattern'] as $subse ) {
						$subse = esc_sql($subse);
						$search_query .= "`referred` LIKE '{$subse}' OR ";
					}
				} else {
					$se['sqlpattern'] = esc_sql($se['sqlpattern']);
					$search_query .= "`referred` LIKE '{$se['sqlpattern']}' OR ";
				}
			}

			// Trim off the last ' OR ' for the loop above.
			$search_query = substr($search_query, 0, strlen($search_query) - 4);
		} else {
			// For just one?  Ok, the SQL pattern for a search engine may be an array if it has to handle multiple domains (like google.com and google.ca) or other factors.
			if ( is_array($searchengine_list[ $search_engine ]['sqlpattern']) ) {
				foreach ( $searchengine_list[ $search_engine ]['sqlpattern'] as $se ) {
					$se = esc_sql($se);
					$search_query .= "`referred` LIKE '{$se}' OR ";
				}

				// Trim off the last ' OR ' for the loop above.
				$search_query = substr($search_query, 0, strlen($search_query) - 4);
			} else {
				$searchengine_list[ $search_engine ]['sqlpattern'] = esc_sql(
					$searchengine_list[ $search_engine ]['sqlpattern']
				);
				$search_query .= "`referred` LIKE '{$searchengine_list[$search_engine]['sqlpattern']}'";
			}
		}
	}

	return $search_query;
}

// This function will return a regular expression clause for matching one or more search engines.
function wp_statistics_searchengine_regex( $search_engine = 'all' ) {

	// Get a complete list of search engines
	$searchengine_list = wp_statistics_searchengine_list();
	$search_query      = '';

	// Are we getting results for all search engines or a specific one?
	if ( strtolower($search_engine) == 'all' ) {
		foreach ( $searchengine_list as $se ) {
			// The SQL pattern for a search engine may be an array if it has to handle multiple domains (like google.com and google.ca) or other factors.
			if ( is_array($se['regexpattern']) ) {
				foreach ( $se['regexpattern'] as $subse ) {
					$search_query .= "{$subse}|";
				}
			} else {
				$search_query .= "{$se['regexpattern']}|";
			}
		}

		// Trim off the last '|' for the loop above.
		$search_query = substr($search_query, 0, strlen($search_query) - 1);
	} else {
		// For just one?  Ok, the SQL pattern for a search engine may be an array if it has to handle multiple domains (like google.com and google.ca) or other factors.
		if ( is_array($searchengine_list[ $search_engine ]['regexpattern']) ) {
			foreach ( $searchengine_list[ $search_engine ]['regexpattern'] as $se ) {
				$search_query .= "{$se}|";
			}

			// Trim off the last '|' for the loop above.
			$search_query = substr($search_query, 0, strlen($search_query) - 1);
		} else {
			$search_query .= $searchengine_list[ $search_engine ]['regexpattern'];
		}
	}

	// Add the brackets and return
	return "({$search_query})";
}

// This function will return the statistics for a given search engine.
function wp_statistics_searchengine( $search_engine = 'all', $time = 'total' ) {

	global $wpdb, $WP_Statistics;

	// Determine if we're using the old or new method of storing search engine info and build the appropriate table name.
	$tablename = $wpdb->prefix . 'statistics_';

	if ( $WP_Statistics->get_option('search_converted') ) {
		$tablename .= 'search';
	} else {
		$tablename .= 'visitor';
	}

	// Get a complete list of search engines
	$search_query = wp_statistics_searchengine_query($search_engine);

	// This function accepts several options for time parameter, each one has a unique SQL query string.
	// They're pretty self explanatory.
	switch ( $time ) {
		case 'today':
			$result = $wpdb->query(
				"SELECT * FROM `{$tablename}` WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d' )}' AND {$search_query}"
			);
		break;

		case 'yesterday':
			$result = $wpdb->query(
				"SELECT * FROM `{$tablename}` WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', -1 )}' AND {$search_query}"
			);

		break;

		case 'week':
			$result = $wpdb->query(
				"SELECT * FROM `{$tablename}` WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', -7 )}' AND {$search_query}"
			);

		break;

		case 'month':
			$result = $wpdb->query(
				"SELECT * FROM `{$tablename}` WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', -30 )}' AND {$search_query}"
			);

		break;

		case 'year':
			$result = $wpdb->query(
				"SELECT * FROM `{$tablename}` WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', -365 )}' AND {$search_query}"
			);

		break;

		case 'total':
			$result = $wpdb->query("SELECT * FROM `{$tablename}` WHERE {$search_query}");

		break;

		default:
			$result = $wpdb->query(
				"SELECT * FROM `{$tablename}` WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', $time)}' AND {$search_query}"
			);

		break;
	}

	return $result;
}

// This function will return the statistics for a given search engine for a given time frame.
function wp_statistics_searchword( $search_engine = 'all', $time = 'total' ) {

	global $wpdb, $WP_Statistics;

	// Determine if we're using the old or new method of storing search engine info and build the appropriate table name.
	$tablename = $wpdb->prefix . 'statistics_';

	if ( $WP_Statistics->get_option('search_converted') ) {
		$tablename .= 'search';
	} else {
		$tablename .= 'visitor';
	}

	// Get a complete list of search engines
	$search_query = wp_statistics_searchword_query($search_engine);

	// This function accepts several options for time parameter, each one has a unique SQL query string.
	// They're pretty self explanatory.
	switch ( $time ) {
		case 'today':
			$result = $wpdb->query(
				"SELECT * FROM `{$tablename}` WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d' )}' AND {$search_query}"
			);
		break;

		case 'yesterday':
			$result = $wpdb->query(
				"SELECT * FROM `{$tablename}` WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', -1 )}' AND {$search_query}"
			);

		break;

		case 'week':
			$result = $wpdb->query(
				"SELECT * FROM `{$tablename}` WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', -7 )}' AND {$search_query}"
			);

		break;

		case 'month':
			$result = $wpdb->query(
				"SELECT * FROM `{$tablename}` WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', -30 )}' AND {$search_query}"
			);

		break;

		case 'year':
			$result = $wpdb->query(
				"SELECT * FROM `{$tablename}` WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', -365 )}' AND {$search_query}"
			);

		break;

		case 'total':
			$result = $wpdb->query("SELECT * FROM `{$tablename}` WHERE {$search_query}");

		break;

		default:
			$result = $wpdb->query(
				"SELECT * FROM `{$tablename}` WHERE `last_counter` = '{$WP_Statistics->Current_Date( 'Y-m-d', $time )}' AND {$search_query}"
			);

		break;
	}

	return $result;
}

// This function will return the total number of posts in WordPress.
function wp_statistics_countposts() {

	$count_posts = wp_count_posts('post');

	$ret = 0;

	if ( is_object($count_posts) ) {
		$ret = $count_posts->publish;
	}

	return $ret;
}

// This function will return the total number of pages in WordPress.
function wp_statistics_countpages() {

	$count_pages = wp_count_posts('page');

	$ret = 0;

	if ( is_object($count_pages) ) {
		$ret = $count_pages->publish;
	}

	return $ret;
}

// This function will return the total number of comments in WordPress.
function wp_statistics_countcomment() {

	global $wpdb;

	$countcomms = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->comments} WHERE comment_approved = '1'");

	return $countcomms;
}

// This function will return the total number of spam comments *IF* akismet is installed.
function wp_statistics_countspam() {

	return number_format_i18n(get_option('akismet_spam_count'));
}

// This function will return the total number of users in WordPress.
function wp_statistics_countusers() {

	$result = count_users();

	return $result['total_users'];
}

// This function will return the last date a post was published on your site.
function wp_statistics_lastpostdate() {

	global $wpdb, $WP_Statistics;

	$db_date = $wpdb->get_var(
		"SELECT post_date FROM {$wpdb->posts} WHERE post_type='post' AND post_status='publish' ORDER BY post_date DESC LIMIT 1"
	);

	$date_format = get_option('date_format');

	return $WP_Statistics->Current_Date_i18n($date_format, $db_date, false);
}

// This function will return the average number of posts per day that are published on your site.
// Alternatively if $days is set to true it returns the average number of days between posts on your site.
function wp_statistics_average_post( $days = false ) {

	global $wpdb;

	$get_first_post = $wpdb->get_var(
		"SELECT post_date FROM {$wpdb->posts} WHERE post_status = 'publish' ORDER BY post_date LIMIT 1"
	);
	$get_total_post = $wpdb->get_var(
		"SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_type = 'post'"
	);

	$days_spend = intval(
		( time() - strtotime($get_first_post) ) / 86400
	); // 86400 = 60 * 60 * 24 = number of seconds in a day

	if ( $days == true ) {
		if ( $get_total_post == 0 ) {
			$get_total_post = 1;
		} // Avoid divide by zero errors.

		return round($days_spend / $get_total_post, 0);
	} else {
		if ( $days_spend == 0 ) {
			$days_spend = 1;
		} // Avoid divide by zero errors.

		return round($get_total_post / $days_spend, 2);
	}
}

// This function will return the average number of comments per day that are published on your site.
// Alternatively if $days is set to true it returns the average number of days between comments on your site.
function wp_statistics_average_comment( $days = false ) {

	global $wpdb;

	$get_first_comment = $wpdb->get_var("SELECT comment_date FROM {$wpdb->comments} ORDER BY comment_date LIMIT 1");
	$get_total_comment = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->comments} WHERE comment_approved = '1'");

	$days_spend = intval(
		( time() - strtotime($get_first_comment) ) / 86400
	); // 86400 = 60 * 60 * 24 = number of seconds in a day

	if ( $days == true ) {
		if ( $get_total_comment == 0 ) {
			$get_total_comment = 1;
		} // Avoid divide by zero errors.

		return round($days_spend / $get_total_comment, 0);
	} else {
		if ( $days_spend == 0 ) {
			$days_spend = 1;
		} // Avoid divide by zero errors.

		return round($get_total_comment / $days_spend, 2);
	}
}

// This function will return the average number of users per day that are registered on your site.
// Alternatively if $days is set to true it returns the average number of days between user registrations on your site.
function wp_statistics_average_registeruser( $days = false ) {

	global $wpdb;

	$get_first_user = $wpdb->get_var("SELECT user_registered FROM {$wpdb->users} ORDER BY user_registered LIMIT 1");
	$get_total_user = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->users}");

	$days_spend = intval(
		( time() - strtotime($get_first_user) ) / 86400
	); // 86400 = 60 * 60 * 24 = number of seconds in a day

	if ( $days == true ) {
		if ( $get_total_user == 0 ) {
			$get_total_user = 1;
		} // Avoid divide by zero errors.

		return round($days_spend / $get_total_user, 0);
	} else {
		if ( $days_spend == 0 ) {
			$days_spend = 1;
		} // Avoid divide by zero errors.

		return round($get_total_user / $days_spend, 2);
	}
}

// This function handle's the dashicons in the overview page.
function wp_statistics_icons( $dashicons, $icon_name = null ) {

	global $wp_version;

	if ( null == $icon_name ) {
		$icon_name = $dashicons;
	}

	// Since versions of WordPress before 3.8 didn't have dashicons, don't use them in those versions.
	if ( version_compare($wp_version, '3.8-RC', '>=') || version_compare($wp_version, '3.8', '>=') ) {
		return '<span class="dashicons ' . $dashicons . '"></span>';
	} else {
		return '<img src="' . plugins_url('wp-statistics/assets/images/') . $icon_name . '.png"/>';
	}
}

// This function checks to see if all the PHP modules we need for GeoIP exists.
function wp_statistics_geoip_supported() {
	// Check to see if we can support the GeoIP code, requirements are:
	$enabled = true;

	// PHP 5.3
	if ( ! version_compare(phpversion(), WP_Statistics::$reg['geoip-php-version'], '>') ) {
		$enabled = false;
	}

	// PHP's cURL extension installed
	if ( ! function_exists('curl_init') ) {
		$enabled = false;
	}

	// PHP NOT running in safe mode
	if ( ini_get('safe_mode') ) {
		// Double check php version, 5.4 and above don't support safe mode but the ini value may still be set after an upgrade.
		if ( ! version_compare(phpversion(), '5.4', '<') ) {
			$enabled = false;
		}
	}

	return $enabled;
}

// This function creates the date range selector 'widget' used in the various statistics pages.
function wp_statistics_date_range_selector(
	$page,
	$current,
	$range = array(),
	$desc = array(),
	$extrafields = '',
	$pre_extra = '',
	$post_extra = ''
) {
	GLOBAL $WP_Statistics;

	wp_enqueue_script('jquery-ui-datepicker');
	wp_register_style(
		'jquery-ui-smoothness-css',
		WP_Statistics::$reg['plugin-url'] . 'assets/css/jquery-ui-smoothness.min.css'
	);
	wp_enqueue_style('jquery-ui-smoothness-css');

	if ( count($range) == 0 ) {
		$range = array( 10, 20, 30, 60, 90, 180, 270, 365 );
		$desc  = array(
			__('10 Days', 'wp-statistics'),
			__('20 Days', 'wp-statistics'),
			__('30 Days', 'wp-statistics'),
			__('2 Months', 'wp-statistics'),
			__('3 Months', 'wp-statistics'),
			__('6 Months', 'wp-statistics'),
			__('9 Months', 'wp-statistics'),
			__('1 Year', 'wp-statistics'),
		);
	}

	if ( count($desc) == 0 ) {
		$desc = $range;
	}

	$rcount = count($range);

	$bold = true;

	// Check to see if there's a range in the URL, if so set it, otherwise use the default.
	if ( array_key_exists('rangestart', $_GET) ) {
		$rangestart = $_GET['rangestart'];
	} else {
		$rangestart = $WP_Statistics->Current_Date('m/d/Y', '-' . $current);
	}
	if ( array_key_exists('rangeend', $_GET) ) {
		$rangeend = $_GET['rangeend'];
	} else {
		$rangeend = $WP_Statistics->Current_Date('m/d/Y');
	}

	// Convert the text dates to unix timestamps and do some basic sanity checking.
	$rangestart_utime = $WP_Statistics->strtotimetz($rangestart);
	if ( false === $rangestart_utime ) {
		$rangestart_utime = time();
	}
	$rangeend_utime = $WP_Statistics->strtotimetz($rangeend);
	if ( false === $rangeend_utime || $rangeend_utime < $rangestart_utime ) {
		$rangeend_utime = time();
	}

	// Now get the number of days in the range.
	$daysToDisplay = (int) ( ( $rangeend_utime - $rangestart_utime ) / 24 / 60 / 60 );
	$today         = $WP_Statistics->Current_Date('m/d/Y');

	// Re-create the range start/end strings from our utime's to make sure we get ride of any cruft and have them in the format we want.
	$rangestart = $WP_Statistics->Local_Date('m/d/Y', $rangestart_utime);
	$rangeend   = $WP_Statistics->Local_Date('m/d/Y', $rangeend_utime);

	// If the rangeend isn't today OR it is but not one of the standard range values, then it's a custom selected value and we need to flag it as such.
	if ( $rangeend != $today || ( $rangeend == $today && ! in_array($current, $range) ) ) {
		$current = -1;
	} else {
		// If on the other hand we are a standard range, let's reset the custom range selector to match it.
		$rangestart = $WP_Statistics->Current_Date('m/d/Y', '-' . $current);
		$rangeend   = $WP_Statistics->Current_Date('m/d/Y');
	}

	echo '<form method="get"><ul class="subsubsub wp-statistics-sub-fullwidth">' . "\r\n";

	// Output any extra HTML we've been passed after the form element but before the date selector.
	echo $pre_extra;

	for ( $i = 0; $i < $rcount; $i++ ) {
		echo '		<li class="all"><a ';

		if ( $current == $range[ $i ] ) {
			echo 'class="current" ';
			$bold = false;
		}

		// Don't bother adding he date range to the standard links as they're not needed any may confuse the custom range selector.
		echo 'href="?page=' .
		     $page .
		     '&hitdays=' .
		     $range[ $i ] .
		     esc_url($extrafields) .
		     '">' .
		     $desc[ $i ] .
		     '</a></li>';

		if ( $i < $rcount - 1 ) {
			echo ' | ';
		}

		echo "\r\n";
	}

	echo ' | ';

	echo '<input type="hidden" name="hitdays" value="-1"><input type="hidden" name="page" value="' . $page . '">';

	parse_str($extrafields, $parse);

	foreach ( $parse as $key => $value ) {
		echo '<input type="hidden" name="' . $key . '" value="' . esc_url($value) . '">';
	}

	if ( $bold ) {
		echo ' <b>' . __('Time Frame', 'wp-statistics') . ':</b> ';
	} else {
		echo ' ' . __('Time Frame', 'wp-statistics') . ': ';
	}

	echo '<input type="text" size="10" name="rangestart" id="datestartpicker" value="' .
	     $rangestart .
	     '" placeholder="' .
	     __('MM/DD/YYYY', 'wp-statistics') .
	     '"> ' .
	     __('to', 'wp-statistics') .
	     ' <input type="text" size="10" name="rangeend" id="dateendpicker" value="' .
	     $rangeend .
	     '" placeholder="' .
	     __('MM/DD/YYYY', 'wp-statistics') .
	     '"> <input type="submit" value="' .
	     __('Go', 'wp-statistics') .
	     '" class="button-primary">' .
	     "\r\n";

	// Output any extra HTML we've been passed after the date selector but before the submit button.
	echo $post_extra;

	echo '</form>' . "\r\n";

	echo '<script>jQuery(function() { jQuery( "#datestartpicker" ).datepicker(); jQuery( "#dateendpicker" ).datepicker(); });</script>' .
	     "\r\n";
}

// This function is used to calculate the number of days and thier respective unix timestamps.
function wp_statistics_date_range_calculator( $days, $start, $end ) {
	GLOBAL $WP_Statistics;

	$daysToDisplay = $days;
	$rangestart    = $start;
	$rangeend      = $end;

	if ( $daysToDisplay == -1 ) {
		$rangestart_utime = $WP_Statistics->strtotimetz($rangestart);
		$rangeend_utime   = $WP_Statistics->strtotimetz($rangeend);
		$daysToDisplay    = (int) ( ( $rangeend_utime - $rangestart_utime ) / 24 / 60 / 60 );

		if ( $rangestart_utime == false || $rangeend_utime == false ) {
			$daysToDisplay    = 20;
			$rangeend_utime   = $WP_Statistics->timetz();
			$rangestart_utime = $rangeend_utime - ( $daysToDisplay * 24 * 60 * 60 );
		}
	} else {
		$rangeend_utime   = $WP_Statistics->timetz();
		$rangestart_utime = $rangeend_utime - ( $daysToDisplay * 24 * 60 * 60 );
	}

	return array( $daysToDisplay, $rangestart_utime, $rangeend_utime );
}

// This function will empty a table based on the table name.
function wp_statitiscs_empty_table( $table_name = false ) {
	global $wpdb;

	if ( $table_name ) {
		$result = $wpdb->query('DELETE FROM ' . $table_name);

		if ( $result ) {
			return sprintf(
				__('%s table data deleted successfully.', 'wp-statistics'),
				'<code>' . $table_name . '</code>'
			);
		}
	}

	return sprintf(__('Error, %s not emptied!', 'wp-statistics'), $table_name);
}

// This function creates a small JavaScript snipit that will load the contents of a overview or dashboard widget.
function wp_statistics_generate_widget_load_javascript( $widget, $container_id = null ) {
	if ( null == $container_id ) {
		$container_id = str_replace('.', '_', $widget . '_postbox');
	}
	?>
	<script type="text/javascript">
		jQuery(document).ready(function () {
			wp_statistics_get_widget_contents('<?php echo $widget; ?>', '<?php echo $container_id; ?>');
		});
	</script>
	<?php
}

/**
 * Generate RGBA colors
 *
 * @param        $num
 * @param string $opacity
 *
 * @return string
 */
function wp_statistics_generate_rgba_color( $num, $opacity = '1' ) {
	$hash = md5('color' . $num);

	return sprintf(
		"'rgba(%s, %s, %s, %s)'",
		hexdec(substr($hash, 0, 2)),
		hexdec(substr($hash, 2, 2)),
		hexdec(substr($hash, 4, 2)),
		$opacity
	);
}

/**
 * This function will validate that a capability exists,
 * if not it will default to returning the 'manage_options' capability.
 *
 * @param string $capability Capability
 *
 * @return string 'manage_options'
 */
function wp_statistics_validate_capability( $capability ) {

	global $wp_roles;

	$role_list = $wp_roles->get_names();

	if ( ! is_object($wp_roles) || ! is_array($wp_roles->roles) ) {
		return 'manage_options';
	}

	foreach ( $wp_roles->roles as $role ) {

		$cap_list = $role['capabilities'];

		foreach ( $cap_list as $key => $cap ) {
			if ( $capability == $key ) {
				return $capability;
			}
		}
	}

	return 'manage_options';
}

/**
 * Notices displayed near the top of admin pages.
 *
 * @param $type
 * @param $message
 */
function wp_statistics_admin_notice_result( $type, $message ) {

	switch ( $type ) {
		case 'error':
			$class = 'notice notice-error';
			break;

		case 'success':
			$class = 'notice notice-success';
			break;
	}

	printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), esc_html( $message ) );
}