/home/arranoyd/magicraft/wp-content/plugins/wp-power-stats/wp-power-stats.php
<?php
/*
Plugin Name: WP Power Stats
Plugin URI: http://www.websivu.com/wp-power-stats/
Description: Powerful real-time statistics of your visitors for your WordPress site.
Version: 2.2.3
Author: Igor Buyanov
Text Domain: power-stats
Author URI: http://www.websivu.com
License: GPL2
*/
if (!empty(PowerStats::$options)) return true;
class PowerStats
{
public static $version = '2.2.3';
public static $options = array();
public static $wpdb = '';
protected static $options_hash = '';
protected static $data = array();
protected static $data_js = array();
protected static $vendors = array();
const HTML_ENCODING_QUOTE_STYLE = ENT_QUOTES;
/**
* Initialize variables and actions
*/
public static function init()
{
// Load all the settings
self::$options = get_option('power_stats_options', array());
if (empty(self::$options)) {
self::$options = self::init_options();
// Save WP Power Stats options in the database
add_option('power_stats_options', self::$options, '', 'no');
} else {
self::$options = array_merge(self::init_options(), self::$options);
}
// Allow other plugins to edit the options
self::$options = apply_filters('power_stats_options', self::$options);
// Set DB connection
self::$wpdb = $GLOBALS['wpdb'];
// Hook a DB clean-up routine to the daily cron job
add_action('power_stats_purge', array(__CLASS__, 'power_stats_purge'));
// Set the options' hash for tracking changes in the options
self::$options_hash = md5(serialize(self::$options));
// Include and initialize vendor libraries
if (!class_exists('Browser') && !class_exists('UserAgent') && !class_exists('BrowserDetection')) require_once POWER_STATS_DIR . '/admin/vendor/browser-os/Browser.php';
if (!class_exists('Mobile_Detect')) require_once POWER_STATS_DIR . '/admin/vendor/mobile-detect/Mobile_Detect.php';
require_once POWER_STATS_DIR . '/admin/vendor/search-terms/SearchEngines.php';
require_once POWER_STATS_DIR . '/admin/vendor/search-terms/Countries.php';
require_once POWER_STATS_DIR . '/admin/vendor/tabgeo_country_v4/tabgeo_country_v4.php';
if ( isset($_SERVER['HTTP_USER_AGENT']) && !empty($_SERVER['HTTP_USER_AGENT']) ) self::$vendors['browser'] = new Browser($_SERVER['HTTP_USER_AGENT']);
self::$vendors['device'] = new Mobile_Detect();
// Add the server and client-side tracker
if (self::$options['tracker_active'] == 'yes' && (!is_admin() || (is_admin() && self::$options['ignore_admin_pages'] == 'no'))) {
// Add additional custom exclusion filters
$track_filter = apply_filters('power_stats_filter_pre_tracking', true);
$action_to_hook = is_admin() ? 'admin_init' : 'wp';
// Hook the tracker script
if ($track_filter) {
add_action($action_to_hook, array(__CLASS__, 'power_stats_enqueue_tracking_script'), 15);
if (self::$options['track_users'] == 'yes') add_action('login_enqueue_scripts', array(__CLASS__, 'power_stats_enqueue_tracking_script'), 10);
}
}
// Update the options before shutting down
add_action('shutdown', array(__CLASS__, 'power_stats_save_options'));
}
/**
* Initialize plugin options
*/
public static function init_options()
{
$options = array(
// Internal
'version' => self::$version,
'secret' => wp_hash( uniqid( time(), true ) ),
'show_admin_notice' => 1,
// General
'tracker_active' => 'yes',
'track_users' => 'yes',
'auto_purge' => 150,
'dashboard_widget' => 'no',
'replace_dashboard' => 'no',
// Exclusions
'ignore_bots' => 'yes',
'ignore_spam_visitors' => 'yes',
'ignore_admin_pages' => 'yes',
'ignore_ip' => '',
'ignore_browser' => '',
'ignore_country' => '',
'ignore_referrer' => '',
'ignore_user' => '',
'ignore_pages' => '',
'ignore_do_not_track' => 'no',
// Permissions
'view_roles' => '',
'admin_roles' => '',
// Advanced
'outbound_tracking' => 'yes',
'session_duration' => '1800',
'extend_session' => 'no',
);
return $options;
}
/**
* Saves the options in the database, if necessary
*/
public static function power_stats_save_options()
{
if (self::$options_hash == md5(serialize(self::$options))) return true;
return update_option('power_stats_options', PowerStats::$options);
}
/**
* Enqueue a javascript to track users' screen resolution and other browser-based information
*/
public static function power_stats_enqueue_tracking_script()
{
wp_register_script('wp_power_stats', plugins_url('/wp-power-stats.js', __FILE__), array(), null, true);
// Pass some information to Javascript
$params = array(
'ajaxurl' => admin_url('admin-ajax.php')
);
$encoded_ci = base64_encode(serialize(self::get_resource()));
$params['ci'] = $encoded_ci . '.' . md5($encoded_ci . self::$options['secret']);
if (self::$options['outbound_tracking'] == 'no') {
$params['outbound_tracking'] = 'false';
}
$params = apply_filters('power_stats_js_params', $params);
wp_enqueue_script('wp_power_stats');
wp_localize_script('wp_power_stats', 'PowerStatsParams', $params);
}
/**
* Remove old entries from the database
*/
public static function power_stats_purge()
{
$purge_interval = intval(self::$options['auto_purge']);
if ($purge_interval <= 0) return;
// Delete old entries
$days_ago = strtotime(date_i18n('Y-m-d H:i:s')." -$purge_interval days");
self::$wpdb->query("DELETE FROM {$GLOBALS['wpdb']->prefix}power_stats_visits WHERE `date` < FROM_UNIXTIME($days_ago)");
// Optimize table
self::$wpdb->query("OPTIMIZE TABLE {$GLOBALS['wpdb']->prefix}power_stats_visits");
exit; // Exit script after conjob run
}
/**
* Client-side tracking
*/
public static function power_stats_track()
{
if (self::$options['tracker_active'] == 'yes') {
// Get JavaScript data
self::$data_js['referer'] = urldecode($_POST['ref']);
list(self::$data_js['ci'], $nonce) = explode('.', $_POST['ci']);
if ($nonce !== md5(self::$data_js['ci'] . self::$options['secret'])) {
exit;
}
// Get back-end data
self::get_visitor_data();
// Send the ID back to Javascript to track future interactions
exit(self::$data['id'].'.'.md5(self::$data['id'].self::$options['secret']));
}
}
/**
* Core tracking functionality
*/
public static function get_visitor_data()
{
// Get date and time
self::$data['date'] = self::get_date();
self::$data['time'] = self::get_time();
// Get device
self::$data['device'] = self::get_device();
// Get client IP
self::$data['ip'] = self::get_ip();
// IP exclusion check
if (!empty(self::$data['ip']) && !empty(self::$options['ignore_ip'])) {
$ip_exclusions = explode("\n", self::$options['ignore_ip']);
foreach ($ip_exclusions as $ip_exclusion) {
$ip_exclusion = trim($ip_exclusion);
if (strlen($ip_exclusion) > 6) {
if (self::ip_match($ip_exclusion, self::$data['ip'])) {
return false;
}
}
}
}
// Get client's country
self::$data['country'] = self::get_country();
// Country exclusion
if (!empty(self::$options['ignore_country']) && is_string(self::$options['ignore_country']) && stripos(self::$options['ignore_country'], self::$data['country']) !== false) {
return false;
}
// Do not track header
if (!empty(self::$options['ignore_do_not_track']) && (self::$options['ignore_do_not_track'] === "yes") && isset($_SERVER['HTTP_DNT']) && $_SERVER['HTTP_DNT'] == 1) {
return false;
}
// Ignore prefetch requests
if ((isset($_SERVER['HTTP_X_MOZ']) && (strtolower($_SERVER['HTTP_X_MOZ']) == 'prefetch')) || (isset($_SERVER["HTTP_X_PURPOSE"]) && (strtolower($_SERVER['HTTP_X_PURPOSE']) == 'preview'))) {
return false;
}
// Get client's language
self::$data['language'] = self::get_language();
// Get client's referer
self::$data['referer'] = self::get_referer();
// Get client's browser name
self::$data['browser'] = self::get_browser();
// Get client's browser version
self::$data['browser_version'] = self::get_browser_version();
// Get client's user agent
self::$data['user_agent'] = self::get_user_agent();
// Get client's OS name
self::$data['os'] = self::get_os();
// Get search engine data
self::$data['search_engine'] = self::get_search_engine_data();
// Get search engine keywords
self::$data['keywords'] = (is_array(self::$data['search_engine'])) ? self::sanitize_data(self::$data['search_engine']['keywords']) : "";
// Bot exclusion
$needles = array('Googlebot','DoCoMo','YandexBot','bingbot','ia_archiver','AhrefsBot','Ezooms','GSLFbot','WBSearchBot','Twitterbot','TweetmemeBot','Twikle','PaperLiBot','Wotbox','UnwindFetchor','facebookexternalhit');
if (self::stripos_array(self::$data['user_agent'], $needles)) return false;
// User Agent Exclusion
foreach (self::string_to_array(self::$options['ignore_browser']) as $filter) {
$pattern = str_replace(array('\*', '\!'), array('(.*)', '.'), preg_quote($filter, '/'));
if (preg_match("~^$pattern$~i", self::$data['browser']['name'] . '/' . self::$data['browser']['version']) || preg_match("~^$pattern$~i", self::$data['browser']['name']) || preg_match("~^$pattern$~i", self::$data['browser']['user_agent'])) {
return false;
}
}
// Get client's language
self::$data['language'] = self::get_language();
// Get WordPress specific information
self::$data['user'] = self::get_user();
// User Exclusion
if (!empty($GLOBALS['current_user']->ID)) {
// Don't track logged-in users, if the corresponding option is enabled
if (self::$options['track_users'] == 'no') {
return false;
}
if (!empty(self::$options['ignore_user']) && is_string(self::$options['ignore_user']) && strpos(self::$options['ignore_user'], $GLOBALS['current_user']->data->user_login) !== false) {
return false;
}
self::$data['user'] = $GLOBALS['current_user']->data->user_login;
} elseif (isset($_COOKIE['comment_author_' . COOKIEHASH])) {
$spam_comment = self::$wpdb->get_row("SELECT comment_author, COUNT(*) comment_count FROM {$GLOBALS['wpdb']->prefix}comments WHERE INET_ATON(comment_author_IP) = '" . sprintf("%u", self::$data['ip']) . "' AND comment_approved = 'spam' GROUP BY comment_author LIMIT 0,1", ARRAY_A);
if (isset($spam_comment['comment_count']) && $spam_comment['comment_count'] > 0) {
if (self::$options['ignore_spam_visit'] == 'yes') {
return false;
} else {
self::$data['user'] = $spam_comment['comment_author'];
}
self::$data['is_spam_visit'] = true;
} else {
self::$data['user'] = $_COOKIE['comment_author_' . COOKIEHASH];
}
}
// Resource Information
self::$data['resource'] = (isset(self::$data_js['ci']) && is_array(self::$data_js)) ? unserialize(base64_decode(self::$data_js['ci'])) : self::get_resource();
// Page Exclusion
if (!empty(self::$data['resource'])) {
foreach (self::string_to_array(self::$options['ignore_pages']) as $filter) {
$pattern = str_replace(array('\*', '\!'), array('(.*)', '.'), preg_quote($filter, '/'));
if (preg_match("@^$pattern$@i", self::$data['resource'])) {
return false;
}
}
}
// Assign a visit id if set in the cookies
self::insert_data();
// Something went wrong during the insert
if ( empty( self::$data[ 'id' ] ) ) {
// Attempt to init the environment, probably the plugin has been just activated on a blog in a MU network
include_once(POWER_STATS_DIR . '/admin/wp-power-stats-admin.php');
PowerStatsAdmin::activate();
// Let's try again
self::insert_data();
}
// Check if this is a new visitor
$cookie_filter = apply_filters('power_stats_set_visit_cookie', true);
if ($cookie_filter) {
if (self::$data['id'] > 0 || self::$options['extend_session'] == 'yes') {
@setcookie('power_stats_tracking_code', self::$data['id'].'.'.md5(self::$data['id'].self::$options['secret']), time() + self::$options['session_duration'], COOKIEPATH);
}
}
}
/**
* Converts a series of comma separated values into an array
*/
public static function string_to_array($option = '')
{
$option = sanitize_text_field($option);
if (empty($option) || !is_string($option))
return array();
else
return array_map('trim', explode(',', $option));
}
/**
* Returns an array of values to be inserted into DB
*/
protected static function get_insert_data()
{
return array("ip" => self::$data['ip'], "date" => self::$data['date'], "time" => self::$data['time'], "country" => self::$data['country'], "device" => self::$data['device'], "referer" => self::$data['referer'], "browser" => self::$data['browser'], "browser_version" => self::$data['browser_version'], "os" => self::$data['os'], "user_agent" => self::$data['user_agent'], "language" => self::$data['language'], "user" => self::$data['user'], "is_search_engine" => self::is_search_engine());
}
/**
* Increment keyword count, if the keyword is not found, return an array with data to insert
* @return array - array with keywords to insert
*/
protected static function get_insert_search_data()
{
if (!empty(self::$data['keywords'])) {
$rows_updated = self::$wpdb->query(self::$wpdb->prepare("UPDATE ". $GLOBALS['wpdb']->prefix ."power_stats_searches SET `count` = count + 1 WHERE `terms` = '%s'", self::$data['keywords']));
if ($rows_updated === 0 && $rows_updated !== false) {
return array('terms' => self::$data['keywords'], 'count' => 1);
}
}
return array();
}
protected static function get_insert_referer_data()
{
if (!empty(self::$data['referer'])) {
$rows_updated = self::$wpdb->query(self::$wpdb->prepare("UPDATE ". $GLOBALS['wpdb']->prefix ."power_stats_referers SET `count` = `count` + 1 WHERE `referer` = '%s'", esc_url_raw(self::$data['referer'])));
if ($rows_updated === 0 && $rows_updated !== false) {
return array('referer' => self::$data['referer'], 'count' => 1);
}
}
return array();
}
protected static function get_insert_post_data()
{
if (!empty(self::$data['resource']) && !empty(self::$data['resource']['content_id'])) {
$rows_updated = self::$wpdb->query(self::$wpdb->prepare("UPDATE ". $GLOBALS['wpdb']->prefix ."power_stats_posts SET `hits` = `hits` + 1 WHERE `date` = '%s' AND `post_id` = '%d'", self::$data['date'], self::$data['resource']['content_id']));
if ($rows_updated === 0 && $rows_updated !== false) {
return array("post_id" => self::$data['resource']['content_id'], "date" => self::$data['date'], "hits" => 1);
}
}
return array();
}
protected static function get_insert_pageview_data()
{
$rows_updated = self::$wpdb->query(self::$wpdb->prepare("UPDATE ". $GLOBALS['wpdb']->prefix ."power_stats_pageviews SET `hits` = `hits` + 1 WHERE `date` = '%s'", self::$data['date']));
if ($rows_updated === 0 && $rows_updated !== false) {
return array("date" => self::$data['date'], "hits" => 1);
}
return array();
}
protected static function get_insert_os_data()
{
if (!empty(self::$data['os'])) {
$rows_updated = self::$wpdb->query(self::$wpdb->prepare("UPDATE ". $GLOBALS['wpdb']->prefix ."power_stats_os SET `count` = count + 1 WHERE `os` = '%s'", self::$data['os']));
if ($rows_updated === 0 && $rows_updated !== false) {
return array("os" => self::$data['os'], "count" => 1);
}
}
return array();
}
protected static function get_insert_browser_data()
{
if (!empty(self::$data['browser'])) {
$rows_updated = self::$wpdb->query(self::$wpdb->prepare("UPDATE ". $GLOBALS['wpdb']->prefix ."power_stats_browsers SET `count` = count + 1 WHERE `browser` = '%s'", self::$data['browser']));
if ($rows_updated === 0 && $rows_updated !== false) {
return array("browser" => self::$data['browser'], "count" => 1);
}
}
return array();
}
/**
* @return int
*/
protected static function get_visitor_id()
{
if (isset($_COOKIE['power_stats_tracking_code'])) {
list($identifier, $control_code) = explode('.', $_COOKIE['power_stats_tracking_code']);
// Make sure only authorized information is recorded
if ($control_code != md5($identifier . self::$options['secret'])) return 0;
return intval($identifier);
}
}
/**
* Inserts data in the DB and assigns the visitor id
*/
protected static function insert_data()
{
$visitor_cookie = self::get_visitor_id();
// Old visitor
if ($visitor_cookie > 0) {
self::$data['id'] = $visitor_cookie;
self::insert_row(self::get_insert_data(), $GLOBALS['wpdb']->prefix . 'power_stats_visits');
self::insert_row(self::get_insert_pageview_data(), $GLOBALS['wpdb']->prefix . 'power_stats_pageviews');
} else {
self::$data['id'] = self::insert_row(self::get_insert_data(), $GLOBALS['wpdb']->prefix . 'power_stats_visits', true);
self::insert_row(self::get_insert_pageview_data(), $GLOBALS['wpdb']->prefix . 'power_stats_pageviews');
self::insert_row(self::get_insert_search_data(), $GLOBALS['wpdb']->prefix . 'power_stats_searches');
self::insert_row(self::get_insert_referer_data(), $GLOBALS['wpdb']->prefix . 'power_stats_referers');
self::insert_row(self::get_insert_post_data(), $GLOBALS['wpdb']->prefix . 'power_stats_posts');
self::insert_row(self::get_insert_os_data(), $GLOBALS['wpdb']->prefix . 'power_stats_os');
self::insert_row(self::get_insert_browser_data(), $GLOBALS['wpdb']->prefix . 'power_stats_browsers');
}
if (!isset(self::$data['id']) || empty(self::$data['id'])) self::$data['id'] = 0;
}
/**
* Get an IP address from the server variables
* @return mixed|string
*/
protected static function get_ip()
{
$ip = "";
$header_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR');
foreach ($header_keys as $key) {
if (array_key_exists($key, $_SERVER) === true) {
foreach (explode(',', $_SERVER[$key]) as $ip) {
$ip = filter_var(trim($ip), FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
}
}
}
return $ip;
}
/**
* Checks if $ip_exclusion matches $ip
* @param $ip_exclusion
* @param $ip
* @return bool if ip_exclusion matches ip
*/
protected function ip_match($ip_exclusion, $ip)
{
$ip_arr = explode('/', $ip_exclusion);
if (!isset($ip_arr[1])) $ip_arr[1] = 32;
$network_long = ip2long($ip_arr[0]);
$x = ip2long($ip_arr[1]);
$mask = long2ip($x) == $ip_arr[1] ? $x : 0xffffffff << (32 - $ip_arr[1]);
$ip_long = ip2long($ip);
return ($ip_long & $mask) == ($network_long & $mask);
}
/**
* Get client's browser version
* @return string
*/
protected static function get_browser_version()
{
$version = self::sanitize_data(self::$vendors["browser"]->getVersion());
return (empty($version) || $version == 'unknown') ? '' : $version;
}
/**
* Get the user agent string
* @return mixed
*/
protected static function get_user_agent()
{
return self::$vendors["browser"]->getUserAgent();
}
protected static function get_os($unknown_is_empty = true) {
$user_agent = self::get_user_agent();
$os_list = array(
'windows' => 'Windows',
'mac' => 'Mac',
'linux|sun|bsd|beos' => 'Linux'
);
$matched = 0;
foreach($os_list as $match => $os) {
if (preg_match("/$match/i", $user_agent)) {
$matched = 1;
break;
}
}
return (($matched && !empty($os)) ? $os : (($unknown_is_empty) ? '' : 'Unknown'));
}
/**
* Sanitize input data. Remove SQL injection and tags.
* @param $data
* @return array|string
*/
protected static function sanitize_data($data) {
if (!empty($data)) {
return esc_sql( strip_tags( $data ));
} else {
return "";
}
}
/**
* Parse search engine data from the referer
* @return array|false
*/
protected static function get_search_engine_data() {
return self::sanitize_data(self::parse_search_engine(self::$data['referer']));
}
/**
* Get client device type
* @return string
*/
protected static function get_device()
{
if (self::$vendors["device"]->isTablet()) {
return "tablet";
} else if (self::$vendors["device"]->isMobile()) {
return "mobile";
} else {
return "desktop";
}
}
/**
* Get current time
* @return string time in UTC
*/
protected static function get_time() {
return current_time('mysql');
}
/**
* Get current date
* @return string date in UTC
*/
protected static function get_date() {
return substr(self::get_time(), 0, strpos(self::get_time(), " "));
}
/**
* Get the country by IP
* @return mixed|string
*/
protected static function get_country()
{
$ip = self::get_ip();
$country = (!empty($ip)) ? tabgeo_country_v4($ip) : "";
return $country;
}
/**
* Extracts the accepted language from browser headers
* @return mixed|string
*/
protected static function get_language() {
if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) {
// Get the language before the first delimiter, comma is the delimiter in Safari
preg_match("/([^,;]*)/", $_SERVER["HTTP_ACCEPT_LANGUAGE"], $array_languages);
// Fix some codes, the correct syntax is with minus (-) not underscore (_)
return self::sanitize_data(str_replace("_", "-", strtolower( $array_languages[0])));
}
return ''; // Unknown language
}
/**
* @return mixed|string
*/
protected static function get_referer() {
return (!empty(self::$data_js['referer'])) ? self::sanitize_data(self::$data_js['referer']) : "";
}
/**
* @return mixed|string
*/
protected static function get_browser() {
return self::$vendors["browser"]->getBrowser();
}
/**
* Get the username of currently logged in user
*/
protected static function get_user() {
return (isset($GLOBALS['current_user']->data->user_login)) ? self::sanitize_data($GLOBALS['current_user']->data->user_login) : "";
}
/**
* @return bool
*/
protected static function is_search_engine() {
return (is_array(self::$data['search_engine']) && isset(self::$data['search_engine']['name']) && self::$data['search_engine']['name'] !== "");
}
/**
* Extracts a keyword from a raw not encoded URL.
* Will only extract keyword if a known search engine has been detected.
* Returns the keyword:
* - in UTF8: automatically converted from other charsets when applicable
* - strtolowered: "QUErY test!" will return "query test!"
* - trimmed: extra spaces before and after are removed
*
* Lists of supported search engines can be found in /core/DataFiles/SearchEngines.php
* The function returns false when a keyword couldn't be found.
* eg. if the url is "http://www.google.com/partners.html" this will return false,
* as the google keyword parameter couldn't be found.
*
* @param string $referrerUrl URL referer URL, eg. $_SERVER['HTTP_REFERER']
* @return array|false false if a keyword couldn't be extracted,
* or array(
* 'name' => 'Google',
* 'keywords' => 'my searched keywords')
*/
protected static function parse_search_engine($referrerUrl) {
global $PowerStats_SearchEngines, $PowerStats_SearchEngines_NameToUrl;
$refererParsed = @parse_url($referrerUrl);
$refererHost = '';
if (isset($refererParsed['host'])) {
$refererHost = $refererParsed['host'];
}
if (empty($refererHost)) {
return false;
}
// some search engines (eg. Bing Images) use the same domain
// as an existing search engine (eg. Bing), we must also use the url path
$refererPath = '';
if (isset($refererParsed['path'])) {
$refererPath = $refererParsed['path'];
}
// no search query
if (!isset($refererParsed['query'])) {
$refererParsed['query'] = '';
}
$query = $refererParsed['query'];
// Google Referrers URLs sometimes have the fragment which contains the keyword
if (!empty($refererParsed['fragment'])) {
$query .= '&' . $refererParsed['fragment'];
}
$searchEngines = $PowerStats_SearchEngines;
$hostPattern = self::getLossyUrl($refererHost);
if (array_key_exists($refererHost . $refererPath, $searchEngines)) {
$refererHost = $refererHost . $refererPath;
} elseif (array_key_exists($hostPattern . $refererPath, $searchEngines)) {
$refererHost = $hostPattern . $refererPath;
} elseif (array_key_exists($hostPattern, $searchEngines)) {
$refererHost = $hostPattern;
} elseif (!array_key_exists($refererHost, $searchEngines)) {
if (!strncmp($query, 'cx=partner-pub-', 15)) {
// Google custom search engine
$refererHost = 'google.com/cse';
} elseif (!strncmp($refererPath, '/pemonitorhosted/ws/results/', 28)) {
// private-label search powered by InfoSpace Metasearch
$refererHost = 'wsdsold.infospace.com';
} elseif (strpos($refererHost, '.images.search.yahoo.com') != false) {
// Yahoo! Images
$refererHost = 'images.search.yahoo.com';
} elseif (strpos($refererHost, '.search.yahoo.com') != false) {
// Yahoo!
$refererHost = 'search.yahoo.com';
} else {
return false;
}
}
$searchEngineName = $searchEngines[$refererHost][0];
$variableNames = null;
if (isset($searchEngines[$refererHost][1])) {
$variableNames = $searchEngines[$refererHost][1];
}
if (!$variableNames) {
$searchEngineNames = $PowerStats_SearchEngines_NameToUrl;
$url = $searchEngineNames[$searchEngineName];
$variableNames = $searchEngines[$url][1];
}
if (!is_array($variableNames)) {
$variableNames = array($variableNames);
}
$key = null;
if ($searchEngineName === 'Google Images'
|| ($searchEngineName === 'Google' && strpos($referrerUrl, '/imgres') !== false)
) {
if (strpos($query, '&prev') !== false) {
$query = urldecode(trim(self::getParameterFromQueryString($query, 'prev')));
$query = str_replace('&', '&', strstr($query, '?'));
}
$searchEngineName = 'Google Images';
} else if ($searchEngineName === 'Google'
&& (strpos($query, '&as_') !== false || strpos($query, 'as_') === 0)
) {
$keys = array();
$key = self::getParameterFromQueryString($query, 'as_q');
if (!empty($key)) {
array_push($keys, $key);
}
$key = self::getParameterFromQueryString($query, 'as_oq');
if (!empty($key)) {
array_push($keys, str_replace('+', ' OR ', $key));
}
$key = self::getParameterFromQueryString($query, 'as_epq');
if (!empty($key)) {
array_push($keys, "\"$key\"");
}
$key = self::getParameterFromQueryString($query, 'as_eq');
if (!empty($key)) {
array_push($keys, "-$key");
}
$key = trim(urldecode(implode(' ', $keys)));
}
if ($searchEngineName === 'Google') {
// top bar menu
$tbm = self::getParameterFromQueryString($query, 'tbm');
switch ($tbm) {
case 'isch':
$searchEngineName = 'Google Images';
break;
case 'vid':
$searchEngineName = 'Google Video';
break;
case 'shop':
$searchEngineName = 'Google Shopping';
break;
}
}
if (empty($key)) {
foreach ($variableNames as $variableName) {
if ($variableName[0] == '/') {
// regular expression match
if (preg_match($variableName, $referrerUrl, $matches)) {
$key = trim(urldecode($matches[1]));
break;
}
} else {
// search for keywords now &vname=keyword
$key = self::getParameterFromQueryString($query, $variableName);
$key = trim(urldecode($key));
// Special case: Google & empty q parameter
if (empty($key)
&& $variableName == 'q'
&& (
// Google search with no keyword
($searchEngineName == 'Google'
&& ( // First, they started putting an empty q= parameter
strpos($query, '&q=') !== false
|| strpos($query, '?q=') !== false
// then they started sending the full host only (no path/query string)
|| (empty($query) && (empty($refererPath) || $refererPath == '/') && empty($refererParsed['fragment']))
)
)
// search engines with no keyword
|| $searchEngineName == 'Google Images'
|| $searchEngineName == 'DuckDuckGo')
) {
$key = false;
}
if (!empty($key)
|| $key === false
) {
break;
}
}
}
}
// $key === false is the special case "No keyword provided" which is a Search engine match
if ($key === null
|| $key === ''
) {
return false;
}
if (!empty($key)) {
if (function_exists('iconv')
&& isset($searchEngines[$refererHost][3])
) {
// accepts string, array, or comma-separated list string in preferred order
$charsets = $searchEngines[$refererHost][3];
if (!is_array($charsets)) {
$charsets = explode(',', $charsets);
}
if (!empty($charsets)) {
$charset = $charsets[0];
if (count($charsets) > 1
&& function_exists('mb_detect_encoding')
) {
$charset = mb_detect_encoding($key, $charsets);
if ($charset === false) {
$charset = $charsets[0];
}
}
$newkey = @iconv($charset, 'UTF-8//IGNORE', $key);
if (!empty($newkey)) {
$key = $newkey;
}
}
}
$key = self::mb_strtolower($key);
}
return array(
'name' => $searchEngineName,
'keywords' => $key,
);
}
/**
* Returns details about the resource being accessed
*/
protected static function get_resource()
{
$content_info = array('content_type' => 'unknown', 'category' => '');
// Mark 404 pages
if (is_404()) {
$content_info['content_type'] = '404';
} // Type
elseif (is_single()) {
if (($post_type = get_post_type()) != 'post') $post_type = 'cpt:' . $post_type;
$content_info['content_type'] = $post_type;
$content_info_array = array();
foreach (get_object_taxonomies($GLOBALS['post']) as $a_taxonomy) {
$terms = get_the_terms($GLOBALS['post']->ID, $a_taxonomy);
if (is_array($terms)) {
foreach ($terms as $a_term) $content_info_array[] = $a_term->term_id;
$content_info['category'] = implode(',', $content_info_array);
}
}
$content_info['content_id'] = $GLOBALS['post']->ID;
} elseif (is_page()) {
$content_info['content_type'] = 'page';
$content_info['content_id'] = $GLOBALS['post']->ID;
} elseif (is_attachment()) {
$content_info['content_type'] = 'attachment';
} elseif (is_singular()) {
$content_info['content_type'] = 'singular';
} elseif (is_post_type_archive()) {
$content_info['content_type'] = 'post_type_archive';
} elseif (is_tag()) {
$content_info['content_type'] = 'tag';
$list_tags = get_the_tags();
if (is_array($list_tags)) {
$tag_info = array_pop($list_tags);
if (!empty($tag_info)) $content_info['category'] = "$tag_info->term_id";
}
} elseif (is_tax()) {
$content_info['content_type'] = 'taxonomy';
} elseif (is_category()) {
$content_info['content_type'] = 'category';
$list_categories = get_the_category();
if (is_array($list_categories)) {
$cat_info = array_pop($list_categories);
if (!empty($cat_info)) $content_info['category'] = "$cat_info->term_id";
}
} elseif (is_date()) {
$content_info['content_type'] = 'date';
} elseif (is_author()) {
$content_info['content_type'] = 'author';
} elseif (is_archive()) {
$content_info['content_type'] = 'archive';
} elseif (is_search()) {
$content_info['content_type'] = 'search';
} elseif (is_feed()) {
$content_info['content_type'] = 'feed';
} elseif (is_home()) {
$content_info['content_type'] = 'home';
} elseif (in_array($GLOBALS['pagenow'], array('wp-login.php', 'wp-register.php'))) {
$content_info['content_type'] = 'login';
} elseif (is_admin()) {
$content_info['content_type'] = 'admin';
}
if (is_paged()) {
$content_info['content_type'] .= ',paged';
}
// Author
if (is_singular()) {
$content_info['author'] = get_the_author_meta('user_login', $GLOBALS['post']->post_author);
}
return $content_info;
}
/**
* Stores the information (array) in the appropriate table and returns the corresponding ID
*
* @param array $data
* @param string $table
* @param bool $showInsertedRowID
* @return bool|int
*/
protected static function insert_row($data = array(), $table = '', $showInsertedRowID = false)
{
if (empty($data) || empty($table)) return false;
self::$wpdb->query(self::$wpdb->prepare("INSERT IGNORE INTO $table (". implode(", ", array_keys($data)) .') VALUES ('. substr(str_repeat('%s,', count($data)), 0, -1) . ")", $data));
if ($showInsertedRowID) return intval(self::$wpdb->insert_id);
}
/**
* Returns list of valid country codes
*
* @see vendor/search-terms/Countries.php
*
* @param bool $includeInternalCodes
* @return array Array of (2 letter ISO codes => 3 letter continent code)
*/
public static function getCountriesList($includeInternalCodes = false) {
$countriesList = $GLOBALS['PowerStats_CountryList'];
$extras = $GLOBALS['PowerStats_CountryList_Extras'];
if ($includeInternalCodes) {
return array_merge($countriesList, $extras);
}
return $countriesList;
}
/**
* Reduce URL to more minimal form. 2 letter country codes are
* replaced by '{}', while other parts are simply removed.
*
* Examples:
* www.example.com -> example.com
* search.example.com -> example.com
* m.example.com -> example.com
* de.example.com -> {}.example.com
* example.de -> example.{}
* example.co.uk -> example.{}
*
* @param string $url
* @return string
*/
public static function getLossyUrl($url) {
static $countries;
if (!isset($countries)) {
$countries = implode('|', array_keys(self::getCountriesList(true)));
}
return preg_replace(
array(
'/^(w+[0-9]*|search)\./',
'/(^|\.)m\./',
'/(\.(com|org|net|co|it|edu))?\.(' . $countries . ')(\/|$)/',
'/(^|\.)(' . $countries . ')\./',
),
array(
'',
'$1',
'.{}$4',
'$1{}.',
),
$url);
}
/**
* Returns the value of a GET parameter $parameter in an URL query $urlQuery
*
* @param string $urlQuery result of parse_url()['query'] and htmlentitied (& is &) eg. module=test&action=toto or ?page=test
* @param string $parameter
* @return string|bool Parameter value if found (can be the empty string!), null if not found
*/
public static function getParameterFromQueryString($urlQuery, $parameter) {
$nameToValue = self::getArrayFromQueryString($urlQuery);
if (isset($nameToValue[$parameter])) {
return $nameToValue[$parameter];
}
return null;
}
/**
* Sanitize a single input value
*
* @param string $value
* @return string sanitized input
*/
public static function sanitizeInputValue($value) {
// $_GET and $_REQUEST already urldecode()'d
// decode
// note: before php 5.2.7, htmlspecialchars() double encodes &#x hex items
$value = html_entity_decode($value, self::HTML_ENCODING_QUOTE_STYLE, 'UTF-8');
// filter
$value = str_replace(array("\n", "\r", "\0"), '', $value);
// escape
$tmp = @htmlspecialchars($value, self::HTML_ENCODING_QUOTE_STYLE, 'UTF-8');
// note: php 5.2.5 and above, htmlspecialchars is destructive if input is not UTF-8
if ($value != '' && $tmp == '') {
// convert and escape
$value = utf8_encode($value);
$tmp = htmlspecialchars($value, self::HTML_ENCODING_QUOTE_STYLE, 'UTF-8');
}
return $tmp;
}
/**
* Returns an URL query string in an array format
*
* @param string $urlQuery
* @return array array( param1=> value1, param2=>value2)
*/
public static function getArrayFromQueryString($urlQuery) {
if (strlen($urlQuery) == 0) {
return array();
}
if ($urlQuery[0] == '?') {
$urlQuery = substr($urlQuery, 1);
}
$separator = '&';
$urlQuery = $separator . $urlQuery;
// $urlQuery = str_replace(array('%20'), ' ', $urlQuery);
$refererQuery = trim($urlQuery);
$values = explode($separator, $refererQuery);
$nameToValue = array();
foreach ($values as $value) {
$pos = strpos($value, '=');
if ($pos !== false) {
$name = substr($value, 0, $pos);
$value = substr($value, $pos + 1);
if ($value === false) {
$value = '';
}
} else {
$name = $value;
$value = false;
}
if (!empty($name)) {
$name = self::sanitizeInputValue($name);
}
if (!empty($value)) {
$value = self::sanitizeInputValue($value);
}
// if array without indexes
$count = 0;
$tmp = preg_replace('/(\[|%5b)(]|%5d)$/i', '', $name, -1, $count);
if (!empty($tmp) && $count) {
$name = $tmp;
if (isset($nameToValue[$name]) == false || is_array($nameToValue[$name]) == false) {
$nameToValue[$name] = array();
}
array_push($nameToValue[$name], $value);
} else if (!empty($name)) {
$nameToValue[$name] = $value;
}
}
return $nameToValue;
}
public static function stripos_array($haystack, $needles=array(), $offset=0) {
$chr = array();
foreach($needles as $needle) {
$res = stripos($haystack, $needle, $offset);
if ($res !== false) $chr[$needle] = $res;
}
if(empty($chr)) return false;
return min($chr);
}
/**
* multi-byte strtolower() - UTF-8
*
* @param string $string
* @return string
*/
public static function mb_strtolower($string) {
if (function_exists('mb_strtolower')) {
return mb_strtolower($string, 'UTF-8');
}
return strtolower($string);
}
/**
* Show dashboard widget
*/
public static function dashboard_widget() {
if (PowerStats::$options['dashboard_widget'] == "yes") {
require_once('dashboard-widget.php');
PowerStatsDashboardWidget::init();
}
}
}
/**
* Initialize widget
*/
function power_stats_init_widget() {
require_once('widget.php');
register_widget('PowerStatsWidget');
}
/**
* Initialize dashboard widget
*/
function power_stats_init_dashboard_widget() {
add_action('wp_dashboard_setup', array('PowerStats', 'dashboard_widget'));
}
if (function_exists('add_action')) {
if (!defined('POWER_STATS_DIR')) define('POWER_STATS_DIR', untrailingslashit(dirname(__FILE__)));
// Ajax listener
if (!empty($_POST['action']) && $_POST['action'] == 'power_stats_track') {
add_action('wp_ajax_power_stats_track', array('PowerStats', 'power_stats_track')); // user logged in
add_action('wp_ajax_nopriv_power_stats_track', array('PowerStats', 'power_stats_track')); // user not logged in
} else {
if (is_admin()) {
include_once(POWER_STATS_DIR . '/admin/wp-power-stats-admin.php');
add_action('plugins_loaded', array('PowerStatsAdmin', 'init'), 15);
add_action('wp_dashboard_setup', array('PowerStatsAdmin', 'replace_dashboard'));
register_activation_hook(__FILE__, array('PowerStatsAdmin', 'activate'));
register_deactivation_hook(__FILE__, array('PowerStatsAdmin', 'deactivate'));
add_filter('plugin_action_links_'.plugin_basename(__FILE__), array('PowerStatsAdmin', 'add_action_link'));
}
}
add_action('plugins_loaded', array('PowerStats', 'init'), 10);
add_action('widgets_init', 'power_stats_init_widget');
power_stats_init_dashboard_widget();
}