File "upgrade.php"

Full Path: /home/ozbarhaber/public_html/19052025___siteeee/Cookie/wassup/lib/upgrade.php
File size: 36.75 KB
MIME-type: text/x-php
Charset: utf-8

<?php
/**
 * Functions to create and update WassUp tables.
 *
 * @package WassUp Real-time Analytics
 * @subpackage upgrade.php module
 * @since version 1.8
 * @author Helene D. <http://helenesit.com>
 *
 * This module is loaded once by the 'wassup_install' hook function when plugin is installed/upgraded.
 */
//abort if this is direct uri request for file
if(!empty($_SERVER['SCRIPT_FILENAME']) && realpath($_SERVER['SCRIPT_FILENAME'])===realpath(preg_replace('/\\\\/','/',__FILE__))){
	//try track this uri request
	if(!headers_sent()){
		//triggers redirect to 404 error page so Wassup can track this attempt to access itself (original request_uri is lost)
		header('Location: /?p=404page&werr=wassup403'.'&wf='.basename(__FILE__));
		exit;
	}else{
		//'wp_die' may be undefined here
		die('<strong>Sorry. Unable to display requested page.</strong>');
	}
//abort if no WordPress
}elseif(!defined('ABSPATH') || empty($GLOBALS['wp_version'])){
	//show escaped bad request on exit
	die("Bad Request: ".htmlspecialchars(preg_replace('/(&#0*37;?|&amp;?#0*37;?|&#0*38;?#0*37;?|%)(?:[01][0-9A-F]|7F)/i','',$_SERVER['REQUEST_URI'])));
}
//-------------------------------------------------
function log_me($message) {
    if ( WP_DEBUG === true ) {
        if ( is_array($message) || is_object($message) ) {
            error_log( print_r($message, true) );
        } else {
            error_log( $message );
        }
    }
}

/**
 * Initialize and return Wassup multisite network settings
 * @since v1.9
 * @param boolean (for network-wide activation)
 * @return array
 */
function wassup_network_install($networkwide=false){
	global $wpdb;
	$network_settings=get_site_option('wassup_network_settings');
	$network_defaults=array('wassup_active'=>1);
	if($networkwide){
		$network_defaults=array(
			'wassup_active'=>1,
			'wassup_table'=>$wpdb->base_prefix."wassup",
			'wassup_menu'=>1,
		);
		//no network table for subdomain networks
		if(is_subdomain_install()) $network_defaults['wassup_table']="";
		if(!empty($network_settings)) {
			//check that previous network table exists
			if(!empty($network_settings['wassup_table']) && !wassupDb::table_exists($network_settings['wassup_table'])) $network_settings['wassup_table']=$network_defaults['wassup_table'];
			$network_settings=wp_parse_args($network_settings,$network_defaults);
		}else{
			$network_settings=$network_defaults;
		}
	}else{
		$network_settings=$network_defaults;
	}
	return $network_settings;
} //end wassup_network_install

/**
 * Initialize and return wassup_settings for a subsite
 * @since v1.9
 * @param array
 * @return array
 */
function wassup_subsite_install($network_settings=array()){
	global $wassup_options;
	$subsite_settings=array();
	if(is_multisite() && !is_subdomain_install()){
		$subsite_settings=get_blog_option($GLOBALS['current_blog']->blog_id,'wassup_settings');
		//duplicate the main site setting for all subsites
		if(empty($subsite_settings)){
			$subsite_settings = get_blog_option($GLOBALS['current_site']->blog_id,'wassup_settings');
			if(empty($subsite_settings)) $subsite_settings=$wassup_options->defaultSettings();
			//replace some subsite defaults with network settings
			if(empty($network_settings)) $network_settings=get_site_option('wassup_network_settings');
			if(!empty($network_settings['wassup_table'])){
				$subsite_settings['wassup_table']=$network_settings['wassup_table'];
			}
		}
	}
	return $subsite_settings;
} //end wassup_subsite_install

/**
 *  Updates wassup settings after table install/upgrade
 * - reset some wassup settings
 * - check for compatibility issues and add to alert_messages
 * - called by wassup_install and wassup_updateTable functions (if browser times out).
 * @since v1.9
 * @param string
 * @return void
 */
function wassup_settings_install($wassup_table=""){
	global $wp_version,$wassup_options;

	if(empty($wassup_table) || !wassupDb::table_exists($wassup_table)) $wassup_table=$wassup_options->wassup_table;
	if(empty($wassup_table)){
		if(is_network_admin()) $wassup_table=$wpdb->base_prefix."wassup";
		else $wassup_table=$wpdb->prefix."wassup";
	}
	//Reset some wassup settings
	//reset 'dbengine' MySQL setting with each upgrade...because host server settings can change
	$wassup_options->wassup_dbengine = $wassup_options->defaultSettings('wassup_dbengine');
	//reschedule optimization after table upgrade
	$wassup_options->wassup_optimize=$wassup_options->defaultSettings('wassup_optimize');
	//update settings for 'spamcheck'
	if (empty($wassup_options->wassup_spamcheck)) {
		$wassup_options->wassup_spamcheck = "0";
		//#set wassup_spamcheck=1 if either wassup_refspam=1 or wassup_spam=1
		if($wassup_options->wassup_spam == "1" || $wassup_options->wassup_refspam =="1") $wassup_options->wassup_spamcheck="1";
	}
	$wassup_options->whash =$wassup_options->get_wp_hash();

	//do compatibility checks after upgrade/activation
	$compat_notice="";
	if (empty($wassup_options->wassup_alert_message) || stristr($wassup_options->wassup_alert_message,'error')===false){
		if(!is_multisite() || is_network_admin() || is_main_site()){
			//compatibility test for mysql @since v1.9
			if(wassup_compatCheck('mysqldb')==false){
				$compat_notice=__("COMPATIBILITY WARNING: non-MySQL database type detected!","wassup")." ".__("WassUp uses complex MySQL queries that may not run on a different database type.","wassup");
			}elseif(wassup_compatCheck("WP_CACHE")==true){
				$compat_notice = __("WassUp cannot generate accurate statistics with page caching enabled.","wassup")." ".__("If your cache plugin stores whole Wordpress pages/posts as static HTML, then WassUp won't run properly. Please deactivate your cache plugin and remove \"WP_CACHE\" from \"wp_config.php\" or switch to a different statistics plugin.","wassup");
			}else{
				//show warning when 'WP_MEMORY_LIMIT' < 64MB @since v1.9
				$mem=wassup_compatCheck("WP_MEMORY_LIMIT");
				if($mem !==true){
					if(version_compare($wp_version,'3.8','>')) $recmem="64M";
					else $recmem="40M";
					$compat_notice=sprintf(__("WARNING: Insufficient memory: %s found! A minimum allocation of %s is recommended for WassUp and Wordpress.","wassup"),$mem."M",$recmem);
					if(version_compare($wp_version,'4.0','<')) $compat_link='[https://codex.wordpress.org/Editing_wp-config.php#Increasing_memory_allocated_to_PHP]';
					else $compat_link='[codex document "Editing wp-config.php"](https://codex.wordpress.org/Editing_wp-config.php#Increasing_memory_allocated_to_PHP)';
					$compat_notice .="  ".sprintf(__("See %s for information about increasing Wordpress memory.","wassup"),$compat_link);
				}
			}
			if(!empty($compat_notice)) $wassup_options->wassup_alert_message=$compat_notice;
			//for upgrade to v1.9+: flag for old wassup widget 
			if(empty($compat_notice) && !empty($wassup_options->wassup_version) && version_compare($wassup_options->wassup_version,'1.9','<')){
				$old_widget="wassup_widget";
				$admin_message=" ".__("IMPORTANT: Wassup Widget has changed and must be re-installed.","wassup");
				if(version_compare($wp_version,'2.8','<')){
					if(is_active_widget($old_widget)) $wassup_options->wassup_alert_message .=$admin_message;
				}elseif(is_active_widget(false,false,$old_widget)){
					$wassup_options->wassup_alert_message .=$admin_message;
				}
			}
		} //!is_multisite
	} //end if wassup_alert_message
	$wassup_options->wassup_table= $wassup_table;
	$wassup_options->wassup_upgraded= time();
} //end wassup_settings_install

/**
 * Table install manager function that calls either 'wassup_createTable' or 'wassup_updateTable' depending on whether this is a new install or an upgrade.
 * @param none
 * @return boolean
 */ 
function wassup_tableInstaller($wassup_table=""){
	global $wpdb, $wassup_options;

	//set wassup table names
	if(empty($wassup_table))$wassup_table=$wassup_options->wassup_table;
	if(empty($wassup_table)){
		if(is_network_admin()) $wassup_table=$wpdb->base_prefix."wassup";
		else $wassup_table=$wpdb->prefix."wassup";
		$wassup_options->wassup_table=$wassup_table;
	}
	$wassup_tmp_table = $wassup_table."_tmp";
	$wassup_meta_table = $wassup_table."_meta";
	$wcharset=true;
	$wsuccess=false;
	//CREATE/UPGRADE table
	if(wassupDb::table_exists($wassup_table)){
		//extend php script execution time to 10.1 minutes to prevent the 'script timeout' error that can cause activation failure when wp_wassup table is very large. @since v1.9
		//Note: browser timeout (blank screen, no error) can still occur when table upgrade takes a long time.
		$stimeout=ini_get("max_execution_time");
		if(is_numeric($stimeout) && $stimeout>0 && (int)$stimeout < 610){
			$disabled_funcs=ini_get('disable_functions');
			if((empty($disabled_funcs) || strpos($disabled_funcs,'set_time_limit')===false) && !ini_get('safe_mode')){
				@set_time_limit(610);
			}
		}
		$wcharset=false;
		$wsuccess=wassup_updateTable($wassup_table);
	}else{
		$wassup_options->wassup_table=$wassup_table;
		if(wassup_createTable()){	//1st attempt
			$wcharset=true;
		}
		//2nd attempt: no character set in table
		if(!wassupDb::table_exists($wassup_table)){ 
			$wcharset=false;
			wassup_createTable($wassup_table,$wcharset);
		}
	}
	//check that install was successful, issue warnings
	if($wsuccess || wassupDb::table_exists($wassup_table)){
		$wsuccess=true;
		$wcharset=true;
		//double-check that temp and meta were created
		if(!wassupDb::table_exists($wassup_tmp_table)){
			wassup_createTable($wassup_tmp_table,$wcharset);
		}
		if(!wassupDb::table_exists($wassup_meta_table)){
			wassup_createTable($wassup_meta_table,$wcharset);
			if(!wassupDb::table_exists($wassup_meta_table) && $wcharset){
				$wcharset=false;
				wassup_createTable($wassup_meta_table,$wcharset);
			}
		}
		//store wassup main table name in Wassup settings
		$wassup_options->wassup_table=$wassup_table;
	}
	return($wsuccess);
} //#end function wassup_tableInstaller

/**
 * Create or upgrade wassup tables:
 * - build new 'wp_wassup' table using 'dbDelta'
 * - add a first record to new 'wp_wassup' table.
 * - build/upgrade 'wp_wassup_meta' table structure using 'dbDelta'
 * @param (2) string,boolean
 * @return boolean
 */
function wassup_createTable($wtable="",$withcharset=true) {
	global $wpdb, $current_user, $wassup_options, $wdebug_mode;

	if (empty($wassup_options->wassup_table)) {
		if(is_network_admin()) $wassup_table=$wpdb->base_prefix . "wassup";
		else $wassup_table = $wpdb->prefix . "wassup";
		$wassup_options->wassup_table=$wassup_table;
	}else{
		$wassup_table =$wassup_options->wassup_table;
	}
	$wassup_tmp_table = $wassup_table."_tmp";
	$wassup_meta_table = $wassup_table."_meta";
	if(empty($wtable)) $wtable_name = $wassup_table;
	else $wtable_name = $wtable;
	$is_new_table = false;

	//use Wordpress' "dbDelta" to create table structure
	//Note that since v1.8.3: Wordpress' "dbdelta" function is no longer used to upgrade pre-existing tables in Wassup because it fails on wassup's table structure in Wordpress 3.1+ (throws MySQL ALTER TABLE error).
	if(!function_exists('dbDelta')){
		if(file_exists(ABSPATH.'wp-admin/includes/upgrade.php')) require_once(ABSPATH.'wp-admin/includes/upgrade.php');
		elseif(file_exists(ABSPATH.'wp-admin/upgrade-functions.php')) require_once(ABSPATH.'wp-admin/upgrade-functions.php');
		else exit(1);
	}
	//...Set default character set and collation (on new table)
	$charset_collate = '';
   	//Add charset on new table only
	if (wassupDb::table_exists($wtable_name)) {
		$is_new_table = false;
		$withcharset = false;
	} else {
		$is_new_table = true;
	}
	//#don't do charset/collation when < MySQL 4.1 or when DB_CHARSET is undefined
	//Note: it is possible that table default charset !== WP database charset on preexisting MySQL database and tables (from WP2.3 or less) because old charsets persist after upgrades
	$mysqlversion=$wpdb->get_var("SELECT version() as version");
	if ($withcharset && version_compare($mysqlversion,'4.1.0','>') && defined('DB_CHARSET') && !empty($wpdb->charset)) {
		$charset_collate = 'DEFAULT CHARACTER SET '.$wpdb->charset;
		//add collate only when charset is specified
		if (!empty($wpdb->collate)) $charset_collate .= ' COLLATE '.$wpdb->collate;
	}
	//table builds should not be interrupted, so run in background in case of browser timeout
	ignore_user_abort(1);

	//wassup table structure
	if ($wtable_name == $wassup_table || $wtable_name == $wassup_tmp_table) {
		$sql_createtable=sprintf("CREATE TABLE `%s` (
  `id` mediumint(9) unsigned NOT NULL auto_increment,
  `wassup_id` varchar(60) NOT NULL,
  `timestamp` varchar(20) NOT NULL,
  `ip` varchar(50) default NULL,
  `hostname` varchar(150) default NULL,
  `urlrequested` text,
  `agent` varchar(255) default NULL,
  `referrer` text,
  `search` varchar(255) default NULL,
  `searchpage` int(11) unsigned default '0',
  `os` varchar(15) default NULL,
  `browser` varchar(50) default NULL,
  `language` varchar(5) default NULL,
  `screen_res` varchar(15) default NULL,
  `searchengine` varchar(25) default NULL,
  `spider` varchar(50) default NULL,
  `feed` varchar(50) default NULL,
  `username` varchar(50) default NULL,
  `comment_author` varchar(50) default NULL,
  `spam` varchar(5) default '0',
  `url_wpid` varchar(50) default '0',
  `subsite_id` mediumint(9) unsigned default 0,
  UNIQUE KEY `id` (`id`),
  KEY `idx_wassup` (`wassup_id`(32)),
  KEY `ip` (`ip`),
  KEY `timestamp` (`timestamp`)) %s;",$wtable_name,$charset_collate);
	//Note: index (username,ip) was removed because of problems with non-romanic language display
	//since v1.8: Increased 'ip' col width to 50 for ipv6 support
	//since v1.9: New index on 'ip' col
	//since v1.9: New col 'subsite_id' added for multisite support
	//since v1.9: Dropped 'os' and 'browser' indices.
	//since v1.9: Dropped combined index '(wassup_id, timestamp)' and replaced with single index on 'wassup_id' to reduce overall table size

	//...Include a first record if new table (not temp table)
	$sql_firstrecord = '';
	if ($wtable_name == $wassup_table && $is_new_table) {
		if (!class_exists('UADetector'))
			include_once (WASSUPDIR.'/lib/uadetector.class.php');
		$ua = new UADetector;
		if (empty($current_user->user_login)) get_currentuserinfo();
		$logged_user = (!empty($current_user->user_login)? $current_user->user_login: "");
		$screen_res="";
		$sessionhash=$wassup_options->whash;
		if(isset($_COOKIE['wassup_screen_res'.$sessionhash])){
			$screen_res=esc_attr(trim($_COOKIE['wassup_screen_res'.$sessionhash]));
			if($screen_res == "x") $screen_res="";
		}
		$currentLocale = get_locale();
		$locale = preg_replace('/^[a-z]{2}_/','',strtolower($currentLocale));
		$subsite_id=0;
		if(!empty($GLOBALS['current_blog']->blog_id)) $subsite_id=$GLOBALS['current_blog']->blog_id;
		$sql_firstrecord = sprintf("INSERT INTO `$wassup_table` (`wassup_id`, `timestamp`, `ip`, `hostname`, `urlrequested`, `agent`, `referrer`, `search`, `searchpage`, `os`, `browser`, `language`, `screen_res`, `searchengine`, `spider`, `feed`, `username`, `comment_author`, `spam`,`url_wpid`, `subsite_id`) VALUES ('%032s','%s','%s','%s','%s','%s','%s','','','%s','%s','%s','%s','','','','%s','','0','0','%s')",
			1, current_time('timestamp'),
			'127.0.0.1', 'localhost', 
			'[404] '.__('Welcome to WassUP','wassup'), 
			$ua->agent . ' WassUp/'.WASSUPVERSION.' (http://www.wpwp.org)', 
			'http://www.wpwp.org', $ua->os, 
			trim($ua->name.' '.$ua->majorVersion($ua->version)),
			$locale,$screen_res,$logged_user,$subsite_id);
	} // end if wassup && is_new_table

	//...create/upgrade wassup table

	//Don't use Wordpress' "dbdelta" function on pre-existing "wp_wassup" table because "dbDelta" fails to upgrade wp_wassup's large table structure in Wordpress 3.1+ (throws MySQL ALTER TABLE error). @since v1.8.3
	$result=false;
	if ($wtable_name != $wassup_table) {
		$result = dbDelta($sql_createtable);
	} elseif (!empty($sql_firstrecord)) {
		$result = dbDelta(array($sql_createtable,$sql_firstrecord));
	} 
	//try create table with wpdb::query if dbDelta failed. @since v1.9
	if(!wassupDb::table_exists($wtable_name)){
		$result=$wpdb->query("$sql_createtable");
		if(!wassupDb::table_exists($wtable_name)){
			$error_msg="\n<br/>".sprintf(__("An error occurred during the install of table %s.","wassup"),$wtable_name)."\n<br/>";
			if(!empty($result) && is_wp_error($result)){
				$errno=$result->get_error_code();
				if((int)$errno > 0){
					$error_msg.=" Error# $errno: ".$result->get_error_message()."\n";
				}
			}
			echo $error_msg;
			exit(1);
		}elseif(!empty($sql_firstrecord)){
			$result=$wpdb->query("$sql_firstrecord");
		}
	}else{
		if ($wtable == "" && version_compare($mysqlversion,'4.1.0','>')) {
			//'CREATE TABLE LIKE' syntax not supported in MySQL 4.1 or less
			$result = dbDelta("CREATE TABLE $wassup_tmp_table LIKE {$wassup_table}");
		}
	}
	} //end if wassup_table
	//"wassup_meta" table to extend wassup. Used as a temporary data cache and to capture additional visitor data. @since v1.8
	if ($wtable == "") $wtable_name = $wassup_meta_table;
	if ($wtable_name == $wassup_meta_table) {

	// Wassup Meta Table Structure:
	// `wassup_key` can be either a foreign key for wp_wassup (contains data from an indexed column) or can be text, ex: for geoip it would contain the wp_wassup key, `ip`.
	// `meta_key` is an abbreviation descriptive of the value stored, ex: 'geoip','chart'.
	// `meta_value` is the value stored. Can be text, number or a serialized array.
	// `meta_expire` is a timestamp that is an expiration date in unix timestamp format...for temporary/cache-only records.
	$sql_create_meta = sprintf("CREATE TABLE `%s` (
  `meta_id` integer(15) unsigned auto_increment,
  `wassup_key` varchar(150) NOT NULL,
  `meta_key` varchar(80) NOT NULL,
  `meta_value` longtext,
  `meta_expire` integer(10) unsigned default '0',
  UNIQUE KEY meta_id (`meta_id`),
  INDEX (`wassup_key`),
  KEY `meta_key` (`meta_key`)) %s;",$wassup_meta_table,$charset_collate);
		$result = dbDelta($sql_create_meta);	//create table

		//try create table with wpdb::query if dbDelta failed
		if(!wassupDb::table_exists($wtable_name)){
			$result=$wpdb->query("$sql_createtable");
			if(!wassupDb::table_exists($wtable_name)){
				$error_msg="\n<br/>".sprintf(__("An error occurred during the install of table %s.","wassup"),$wtable_name)."\n<br/>";
				if(!empty($result) && is_wp_error($result)){
					$errno=$result->get_error_code();
					if((int)$errno > 0){
						$error_msg.=" Error# $errno: ".$result->get_error_message()."\n";
					}
				}
				if($wdebug_mode){
					echo $error_msg;
					exit(1);
				}
			}
		}
	} //end if wassup_meta_table 
	return true;
} //end function wassup_createTable

/**
 * Upgrade Wassup's table structure and data:
 * - update wassup tables structure and indices
 * - drop and recreate 'wassup_tmp' table
 * - drop and rebuild all indices on wassup tables except 'id' (also optimizes)
 * - retroactively upgrade wp_wassup table data for new agent types
 * @param none
 * @return boolean
 */
function wassup_updateTable($wtable=""){
	global $wpdb,$wp_version,$wassup_options,$wdebug_mode;
	if(!empty($wtable) && wassupDb::table_exists($wtable)){
		$wassup_table=$wtable;
		$wassup_options->wassup_table=$wtable;
	}else{
		if(empty($wassup_options->wassup_table)){
			if(is_network_admin()) $wassup_table=$wpdb->base_prefix . "wassup";
			else $wassup_table = $wpdb->prefix . "wassup";
			$wassup_options->wassup_table=$wassup_table;
		}else{
			$wassup_table=$wassup_options->wassup_table;
		}
		//abort if bad wassup table name
		if(!wassupDb::table_exists($wassup_table)){
			echo __FUNCTION__." ERROR: $wassup_table does NOT exist!";
			exit(1);
		}
	}
	$wassup_tmp_table = $wassup_table."_tmp";
	$wassup_meta_table = $wassup_table."_meta";
	//Extend php script execution time to 10.5 minutes to prevent the 'script timeout' error that can cause activation failure when wp_wassup table is very large. @since v1.9
	$stimer_start=time();
	$stimeout=ini_get("max_execution_time");
	if(is_numeric($stimeout)){
		if($stimeout>0 && (int)$stimeout < 630){
			$disabled_funcs=ini_get('disable_functions');
			if((empty($disabled_funcs) || strpos($disabled_funcs,'set_time_limit')===false) && !ini_get('safe_mode')){
				$result=@set_time_limit(630);
				if($result) $stimeout=630;
			}
		}elseif($stimeout==0){ //unlimited/server maximum
			$stimeout=630;
		}else{
			$stimeout=0;
		}
	}else{
		$stimeout=0;
	}
	if(empty($stimeout)) $stimeout=58; //use default timeout minus 2 secs
	//get wait timeout length and size of wassup_table in mysql
	$mtimeout=$wpdb->get_var("SELECT @@session.wait_timeout FROM dual");
	$rows=$wpdb->get_var("SELECT COUNT(*) FROM `$wassup_table`");	//fix for activation error in MariaDb @since v1.9.4.5
	$error_msg="";
	$error_count=0;
	//wassup_version must be valid version#, so reset if needed
	$from_version=$wassup_options->wassup_version;
	if(empty($from_version) || !is_numeric($from_version) || version_compare($from_version,WASSUPVERSION,">")){
		$from_version=0;
	}
	$mysqlversion=$wpdb->get_var("SELECT version() as version");
	$sql="";
	//Do the upgrades
	$dbtasks=array();
	$dbtask_keys=array();
	//create wp-cron action for background updates 
	//Note that 'LOW_PRIORITY' is strictly for separate cron/ajax processes only..otherwise it will cause long waits when site is busy
	$low_priority="";
	if(version_compare($wp_version,'3.0','>')){
		$low_priority="LOW_PRIORITY";
		add_action('wassup_upgrade_dbtasks',array('wassupDb','scheduled_dbtask'),10,1);
		//scheduled api upgrade unnecessary here...removed @since v1.9.4.5
	}
	//Since Wordpress 3.1, 'wassup_createTable' no longer upgrades "wp_wassup" table structure because of an ALTER TABLE error in the "dbDelta" function. @since v1.8.3
	//Do table structure upgrades
	//skip some upgrade checks when script timeout is small number @since v1.9.1
	if($stimeout >180){
	// Upgrade from version < v1.8.4:
	// -add 'spam' field to table - v1.3.9
	// -increase 'wassup_id' field size - v1.5.1
	// -increase size of 'searchengine' + 'spider' fields - v1.7
	// -add field 'url_wpid' column for post_id tracking - v1.8.3
	// -increase size of 'ip' field for IPv6 addresses - v1.8.3
	if((!empty($from_version) && version_compare($from_version,"1.8.4","<"))){
		//add 'spam' field to table
		$col=$wpdb->get_row(sprintf("SHOW COLUMNS FROM `%s` LIKE 'spam'",$wassup_table));
		if(empty($col)){
			$result=$wpdb->query(sprintf("ALTER TABLE `%s` ADD COLUMN `spam` VARCHAR(5) DEFAULT '0'",$wassup_table));
		}
		//increase 'wassup_id' field size
		$col=$wpdb->get_row(sprintf("SHOW COLUMNS FROM `%s` LIKE 'wassup_id'",$wassup_table));
		if(!empty($col->Type) && $col->Type !="varchar(60)"){
			$result=$wpdb->query(sprintf("ALTER TABLE `%s` MODIFY `wassup_id` varchar(60) NOT NULL",$wassup_table));
		}
		//increase size of 'searchengine' and 'spider' fields
		$col=$wpdb->get_row(sprintf("SHOW COLUMNS FROM `%s` LIKE 'searchengine'",$wassup_table));
		if(!empty($col->Type) && $col->Type !="varchar(25)"){
			$result=$wpdb->query(sprintf("ALTER TABLE `%s` MODIFY `searchengine` varchar(25) DEFAULT NULL",$wassup_table));
		}
		$col=$wpdb->get_row(sprintf("SHOW COLUMNS FROM `%s` LIKE 'spider'",$wassup_table));
		if(!empty($col->Type) && $col->Type !="varchar(50)"){
			$wpdb->query(sprintf("ALTER TABLE `%s` MODIFY `spider` varchar(50) DEFAULT NULL",$wassup_table));
		}
		//add field 'url_wpid' column for post_id tracking 
		$col=$wpdb->get_var(sprintf("SHOW COLUMNS FROM `%s` LIKE 'url_wpid'",$wassup_table));
		if(empty($col)){
			$result=$wpdb->query(sprintf("ALTER TABLE `%s` ADD COLUMN `url_wpid` varchar(50) DEFAULT NULL",$wassup_table));
		}
		//increase size of 'ip' field for IPv6 addresses
		$col=$wpdb->get_row(sprintf("SHOW COLUMNS FROM `%s` LIKE 'ip'",$wassup_table));
		if(!empty($col->Type) && $col->Type !="varchar(50)"){
			$result=$wpdb->query(sprintf("ALTER TABLE `%s` MODIFY `ip` varchar(50) DEFAULT NULL",$wassup_table));
		}
	}
	}//end if stimeout >180
	$result=false;
	$error_msg="";
	// Upgrade from v1.8.7:
	// -add new field, `subsite_id` for multisite compatibility
	// -drop indices on 'os', 'browser', and (wassup_id,timestamp)
	// -add index on 'ip' column indices on 'os', 'browser', and (wassup_id,timestamp)
	//if(empty($from_version) || version_compare($from_version,'1.8.7','<=')){
		//add table column, 'subsite_id' for multisite
		$col=$wpdb->get_var(sprintf("SHOW COLUMNS FROM `%s` LIKE 'subsite_id'",$wassup_table));
		if(empty($col)){
			$result=$wpdb->query("ALTER TABLE `$wassup_table` ADD COLUMN `subsite_id` mediumint(9) UNSIGNED DEFAULT 0");
		}
		//drop indices on 'os','browser', and (wassup_id+timestamp) columns
		$wkeys=$wpdb->get_results("SHOW INDEX FROM `$wassup_table` WHERE Column_name='browser' OR Column_name='os' OR (Column_name='timestamp' AND Key_name LIKE 'idx_wassup%')");
		if(!empty($wkeys)){
			if(is_array($wkeys) && !empty($wkeys[0]->Key_name)){
				foreach($wkeys AS $dropkey){
					$keyresult=$wpdb->query(sprintf("DROP INDEX `%s` ON `$wassup_table`",$dropkey->Key_name));
				}
			}
		}
		//add new index on ip...add to index rebuild queue
		$wkey=$wpdb->get_results(sprintf("SHOW INDEX FROM `%s` WHERE Column_name='ip'",$wassup_table));
		if(empty($wkey)){
			//add to index rebuild queue
			$dbtask_keys['ip']=sprintf("ALTER TABLE `%s` ADD INDEX `ip` (`ip`)",$wassup_table);
		}
	//}
	// Upgrade from v1.9:
	// -remove all Wassup 1.9 scheduled actions from wp-cron
	if(!empty($from_version) && $from_version=="1.9"){
		remove_action('wassup_scheduled_optimize',array('wassupDb','scheduled_dbtask'));
		remove_action('wassup_scheduled_dbtasks',array('wassupDb','scheduled_dbtask'));
		remove_action('wassup_scheduled_cleanup','wassup_temp_cleanup');
		remove_action('wassup_scheduled_purge','wassup_auto_cleanup');
		wp_clear_scheduled_hook('wassup_scheduled_optimize');
		wp_clear_scheduled_hook('wassup_scheduled_purge');
		wp_clear_scheduled_hook('wassup_scheduled_cleanup');
	}
	//log errors
	if($wdebug_mode && !empty($result) && is_wp_error($result)){
		$errno=$result->get_error_code();
		if(!empty($errno)){
			$error_msg .="\n".__FUNCTION__.' ERROR: "subsite_id" column was NOT created';
			$error_msg .="\t SQL error# $errno: ".$result->get_error_message();
		}
	}
	// For all upgrades:
	// - drop wassup_tmp table
	// - clear all cached records from wassup_meta table, or
	// - create wassup_meta table, if missing
	// - drop and rebuild all indices except 'id' and 'meta_id'
	// - recreate wassup_tmp table
	// note that wassup_meta_table and wassup_tmp_table are also added by 'wassup_Tableinstaller' function after script ends, if needed
	// Drop wassup_tmp table
	if(version_compare($wp_version,"2.8","<")){
		$result=mysql_query(sprintf("DROP TABLE IF EXISTS `%s`",$wassup_tmp_table));
	}else{
		 $result=$wpdb->query(sprintf("DROP TABLE IF EXISTS `%s`",$wassup_tmp_table));
		if($wdebug_mode && !empty($result) && is_wp_error($result)){
			$errno=$result->get_error_code();
			if(!empty($errno)){
				$error_msg .="\n".__FUNCTION__.' ERROR: problem dropping wassup_tmp table';
				$error_msg .="\t SQL error# $errno: ".$result->get_error_message();
			}
		}
	}
	if(!empty($error_msg)){
		echo $error_msg;
		exit(1);
	}
	//index rebuild could take a long time, so finish process in background in case of a browser timeout
	ignore_user_abort(1);
	$indices_tables=array($wassup_table); //for index rebuild below
	// Create wassup_meta table, if missing
	if(!wassupDb::table_exists($wassup_meta_table)){
		wassup_createTable($wassup_meta_table,true);
	}else{
		//or clear cached records from wassup_meta...
		$sql=sprintf("DELETE FROM %s WHERE `meta_expire`>0",$wassup_meta_table);
		$result=$wpdb->query($sql);
		if($wdebug_mode && !empty($result) && is_wp_error($result)){
			$errno=$result->get_error_code();
			if(!empty($errno)){
				$error_msg .="\n".__FUNCTION__.' ERROR: clear cache/wassup_meta table problem';
				$error_msg .="\t SQL error# $errno: ".$result->get_error_message();
			}
			echo $error_msg;
			exit(1);
		}
		$indices_tables[]=$wassup_meta_table;
	}
	// Drop wassup tables indices
	if($stimeout >90 || $rows < 25000){
	foreach ($indices_tables AS $wtbl){
		//get list of all wassup indices except id
		$wkeys=$wpdb->get_col(sprintf("SHOW INDEX FROM `%s` WHERE Key_name NOT LIKE '%%id'",$wtbl),2);
		if(!empty($wkeys) && is_array($wkeys)){
			//note: "show index" lists keys multiple time for indices on more than 1 column
			foreach(array_unique($wkeys) AS $idx){
				$result=$wpdb->query(sprintf("DROP INDEX `%s` ON `%s`",$idx,$wtbl));
				//queue the indices rebuild
				//..don't rebuild duplicate keys or idx_wassup
				if(preg_match('/^[a-z][a-z\-_]+\d+$/i',$idx)==0 && $idx != "idx_wassup"){
					$dbtask_keys[$idx]=sprintf("ALTER TABLE `%s` ADD INDEX `%s` (`%s`)",$wtbl,$idx,$idx); //index name included to prevent duplicate keys being created
				}
			} //end foreach(2)
		} //end if !wkeys
	}
	} //end if stimeout
	// Rebuild indices
	//increase mysql session timeout to 10 minutes for index rebuild
	if(is_numeric($mtimeout) && $mtimeout< 600) $result=$wpdb->query("SET wait_timeout=600");
	$result=false;
	//rebuild wassup_id index first, in case of script timeout @since v1.9.1
	$wkey=$wpdb->get_results(sprintf("SHOW INDEX FROM `%s` WHERE Column_name='wassup_id'",$wassup_table));
	if(empty($wkey)) $result=$wpdb->query(sprintf("ALTER TABLE `%s` ADD KEY idx_wassup (wassup_id(32))",$wassup_table));
	if($wdebug_mode && !empty($result) && is_wp_error($result)){
		$error_msg .="\n".__FUNCTION__.' ERROR: create wassup_id index on '.$wassup_table.' problem';
		$errno=$result->get_error_code();
		if(!empty($errno)) $error_msg .="\t SQL error# $errno: ".$result->get_error_message();
		echo $error_msg;
		exit(1);
	}
	//rebuild other indices
	if(!empty($dbtask_keys)){
		foreach ($dbtask_keys AS $sql_create_idx) {
			$result=$wpdb->query($sql_create_idx);
			if($wdebug_mode && !empty($result) && is_wp_error($result)){
				$error_msg .="\n".__FUNCTION__.' ERROR: create index problem';
				$errno=$result->get_error_code();
				if(!empty($errno)) $error_msg .="\t SQL error# $errno: ".$result->get_error_message();
			}
		}
		$dbtask_keys=array();
	}
	// Re-create wassup_tmp table
	wassup_createTable($wassup_tmp_table,true);

	//Do retroactive data updates by version#
	//Retroactive data updates are run separately from table structure upgrades (via wp_cron). @since v1.9
	//For upgrade from < v1.8:
	// -retroactively fix incorrect OS "win2008" (="win7") in table
	if(version_compare($from_version,"1.8","<")){
		$upd_timestamp=strtotime("1 January 2009");
		//queue the table data fixes
		$dbtasks[]=sprintf("UPDATE $low_priority `$wassup_table` SET `os`='win7' WHERE `timestamp`>'%d' AND `os`='win2008'",$upd_timestamp);
		$dbtasks[]=sprintf("UPDATE $low_priority `$wassup_table` SET `os`='win7 x64' WHERE `timestamp`>'%d' AND `os`='win2008 x64'",$upd_timestamp);
	}
	//For upgrade from <= v1.9:
	// -retroactively update data to replace the old "NA" text in `os` and `browser` fields with null
	// -retroactively update search engine data to use "_notprovided_" instead of null as keywords from Google secure search
	// -retroactively fix os and browser data for win8, win10, and ie11
	if(version_compare($from_version,"1.9","<=")){
		//retroactively update data to replace old "NA" text
		$dbtasks[]=sprintf("UPDATE $low_priority `$wassup_table` SET `os`='' WHERE `timestamp`<'%d' AND (`os`='NA' OR `os`='N/A')",strtotime("1 January 2007"));
		$dbtasks[]=sprintf("UPDATE $low_priority `$wassup_table` SET `browser`='' WHERE `timestamp`<'%d' AND (`browser`='NA' OR `browser`='N/A')",strtotime("1 January 2007"));
		//retroactively insert "_notprovided_" keyword in empty search field from Google Secure Search after Dec 2012
		$dbtasks[]=sprintf("UPDATE $low_priority `$wassup_table` SET `search`='_notprovided_',`searchengine`='Google' WHERE `timestamp`>='%d' AND `search`='' AND `searchengine`='' AND `referrer`!='' AND (`referrer` LIKE 'https://www.google.%%' OR `referrer` LIKE 'https://%%_.google.com')",strtotime("1 December 2012"));
		//fix misnamed newer os and browsers versions
		$dbtasks[]=sprintf("UPDATE $low_priority `$wassup_table` SET `os`='Win8' WHERE `timestamp`>='%d' AND (`os`='WinNT 6.3' OR `os`='WinNT 6.2')",strtotime("1 January 2013"));
		$dbtasks[]=sprintf("UPDATE $low_priority `$wassup_table` SET `os`='Win8 x64' WHERE `timestamp`>='%d' AND (`os`='WinNT 6.3 x64' OR `os`='WinNT 6.2 x64')",strtotime("1 January 2013"));
		$dbtasks[]=sprintf("UPDATE $low_priority $wassup_table SET `browser`='IE 11' WHERE `timestamp`>='%d' AND `browser`='' AND (`os` LIKE 'WinNT 6.3%%' OR `os` LIKE 'Win8%%') AND `agent` LIKE '%%; rv:11.0%%'",strtotime("1 January 2013"));
		$dbtasks[]=sprintf("UPDATE $low_priority `$wassup_table` SET `os`='Win10' WHERE `timestamp`>='%d' AND (`os`='WinNT 10' OR `os`='WinNT 10.0')",strtotime("1 January 2015"));
		$dbtasks[]=sprintf("UPDATE $low_priority `$wassup_table` SET `os`='Win10 x64' WHERE `timestamp`>='%d' AND (`os`='WinNT 10 x64' OR `os`='WinNT 10.0 x64')",strtotime("1 January 2015"));
		$dbtasks[]=sprintf("UPDATE $low_priority `$wassup_table` SET `browser`='IE 11' WHERE `timestamp`>='%d' AND `browser`='' AND (`os` LIKE 'Win10%%' OR `os` LIKE 'WinNT 10%%') AND `agent` LIKE '%% Edge%%'",strtotime("1 January 2015"));
	} //end if 1.9

	//For all upgrades: 
	// removed scheduled lookup of new api key @since v1.9.4.5`
	//Queue the retroactive updates
	//schedule retroactive updates via cron so it dosen't slow down activation
	if(count($dbtasks)>0){
		$arg=array('dbtasks'=>$dbtasks);
		if(!empty($low_priority)){
			wp_schedule_single_event(time()+300,'wassup_upgrade_dbtasks',$arg);
		}else{
			wassupDb::scheduled_dbtask($arg);
		}
	}

	//Lastly, check for browser timeout..may not work because of output redirection in Wordpress during plugin install, so also use timer.
	//'echo chr(0);' to send null to browser to check if it is still alive - doesn't work
	//...after 1 minute (normal http request keepAlive time) or browser abort, run 'wassup_settings_install' and save settings
	if(connection_aborted() || (time() - $stimer_start) > 57){
		$wassup_options->wassup_alert_message="Wassup ".WASSUPVERSION.": ".__("Database created/upgraded successfully","wassup");
		wassup_settings_install($wassup_table);
		$wassup_options->wassup_upgraded=time();
		$wassup_options->wassup_version=WASSUPVERSION;
		//$wassup_options->wassup_active=1;
		$wassup_options->saveSettings();
	}
	return true;
} //end function wassup_updateTable

/**
 * Check for wassup tables structure problems.
 * @since v1.9
 */
function wassup_upgradeCheck($wtable=""){
	global $wpdb,$wassup_options;
	if(empty($wassup_options->wassup_table)){
		if(is_network_admin()) $wassup_table=$wpdb->base_prefix . "wassup";
		else $wassup_table = $wpdb->prefix . "wassup";
		$wassup_options->wassup_table=$wassup_table;
	}else{
		$wassup_table =$wassup_options->wassup_table;
	}
	$wassup_meta_table=$wassup_table . "_meta";
	$wassup_tmp_table=$wassup_table . "_tmp";
	$upg_ok=true;
	$msg="";
	//check for tables and structural updates to wassup tables
	if(!empty($wtable) && $wtable != $wassup_table){
		if(!table_exists($wtable)) $upg_ok=false;
	}else{
		if(wassupDb::table_exists($wassup_table)){
			//check if 'subsite_id' column exists
			if(is_multisite()){
				$col=$wpdb->get_row("SHOW COLUMNS FROM `$wassup_table` LIKE 'subsite_id'");
				if(empty($col) || is_wp_error($col)) $upg_ok=false;
			}
		}else{
			$upg_ok=false;
		}
		//check for wassup_meta and wassup_tmp tables
		if($upg_ok && empty($table)){
			if(!wassupDb::table_exists($wassup_meta_table)) $upg_ok=false;
			elseif(!wassupDb::table_exists($wassup_tmp_table)) $upg_ok=false;
		}
	}
	return $upg_ok;
} //end wassup_upgradeCheck

/**
 * Check for Wordpress configuration problems that might affect WassUp running properly.
 * @param string
 * @return boolean
 * @since v1.8
 */
function wassup_compatCheck($item_to_check) {
	global $wpdb,$wp_version;
	$result = false;
	//wp-footer: test for "wp_footer()" function in 'footer.php'
	if ($item_to_check == "wp_footer") {
		$result=true;
		$footer_file =  STYLESHEETPATH."/footer.php";
		if (!file_exists($footer_file)) $footer_file = TEMPLATEPATH."/footer.php";
		if (file_exists($footer_file)) {
			$footer = file_get_contents($footer_file);
			//Note: if "wp_footer()" is commented-out in template code, it will still match as true in test below
			if (stristr($footer,'wp_footer(')!==false || stristr($footer,'wp_footer (')!==false) $result=true;
			else $result=false;
		} else {
			$result=false;
		}
	//check for WP_CACHE constant added by caching plugins
	} elseif ($item_to_check == "WP_CACHE") {
		$result=false;
		if (defined('WP_CACHE') && WP_CACHE!==false && trim(WP_CACHE)!=="") {
			$result=true;
		}
	//check for MySQL database @since v1.9
	} elseif($item_to_check=="mysqldb") {
		$result=true;
		if(version_compare($wp_version,'3.3','>')&& empty($wpdb->is_mysql)) $result=false;
	//check for adequate Wordpress Memory @since v1.9
	} elseif ($item_to_check == "WP_MEMORY_LIMIT") {
		$result=true;
		if(defined('WP_MEMORY_LIMIT')) $wp_memory=WP_MEMORY_LIMIT;
		else $wp_memory=@ini_get('memory_limit');
		$mem=0;
		if(preg_match('/^(\-?\d+)(\s?\w)?/',$wp_memory,$match)>0){
			$mem = (int)$match[1]; 
			if (!empty($match[2]) && strtolower($match[2])=='g') $mem = (int)$match[1]*1024;
		}
		if($mem >0){
			if($mem < 32){
				$result=$mem;
			}elseif($mem < 40){
				if(version_compare($wp_version,"3.5",">=")) $result=$mem;
			}elseif($mem < 64){
				if(version_compare($wp_version,"3.8",">=")) $result=$mem;
			}
		}
	} else {
		$result=true; //default
	}
	return $result;
} //end wassup_compatCheck
?>