<?php

///////////////////////////////////////////////////////////////////////////////////////////////////////
// BotBanish 7.0.12
// Randem Systems: https://randemsystems.support
// BotBanish Plugin Istallation / Actvation / Deactivation / Deletion Audit
// Date: 01/14/2026
// Usage:
//
// Function: Shows when a plugin was Activated / Deactivated
//
//	Some Portions Borrowed from
//	Plugin Activation Tracker
//	by Galaxy Weblinks
//	https://www.galaxyweblinks.com
///////////////////////////////////////////////////////////////////////////////////////////////////////

class BotBanishFirewallPluginAudit {

	public	$option_name = 'botbanishfirewall_client_option_name';

	public  $audit_table_names = array(
									'plugin' => 'bbc_botbanishclient_audit_plugin',
									'theme' => 'bbc_botbanishclient_audit_theme',
									'core' => 'bbc_botbanishclient_audit_core',
								);


	public	$option_audit_names = array(
									'plugin' => 'botbanishfirewall_client_option_audit_plugin',
									'theme' => 'botbanishfirewall_client_option_audit_theme',
									'core' => 'botbanishfirewall_client_option_audit_core',
								);

	public $audit_msg_text = '';
	public $package = '';
	public $audit_options = array();


	public function __construct() {

		add_filter( 'manage_plugins_columns', array($this, 'BotBanishPluginsColumnsName'));
		add_filter( 'plugin_row_meta', array($this, 'BotBanishAddCustomPluginLinks'), 10, 2);

		add_action( 'activate_plugin', array($this, 'BotBanishAuditPluginChanged'));
		add_action( 'deactivate_plugin', array($this, 'BotBanishAuditPluginChanged'));
		add_action( 'delete_plugin', array($this, 'BotBanishAuditPluginChanged'));

		add_action( 'delete_theme', array($this, 'BotBanishAuditThemeChanged') );
		add_action( 'switch_theme', array($this, 'BotBanishAuditThemeChanged') );
		add_action( 'after_switch_theme', array($this, 'BotBanishAuditThemeChanged') );

		add_action( 'upgrader_process_complete', array($this, 'BotBanishAuditUpdated'), 10, 2 );
		add_action( 'upgrader_package_options', array($this, 'BotBanishAuditUpdatable') );

		add_action( 'admin_head-plugins.php', array($this, 'BotBanishColumnCssStyles'));
		add_action( 'manage_plugins_custom_column', array($this, 'BotBanishPluginColumns'), 10, 3);
		add_action( 'wp_footer', array($this, 'BotBanishCleanUpDays'));

		// On initial load we must create our table that will hold the plugin status information

		foreach ($this->audit_table_names as $table_name)
			$this->BotBanishCreateAuditTable($table_name);
	}

	public function __destruct() {

		remove_filter( 'manage_plugins_columns', array($this, 'BotBanishPluginsColumnsName'));
		remove_filter( 'plugin_row_meta', array($this, 'BotBanishAddCustomPluginLinks'), 10, 2);

		remove_action( 'activate_plugin', array($this, 'BotBanishAuditPluginChanged'));
		remove_action( 'deactivate_plugin', array($this, 'BotBanishAuditPluginChanged'));
		remove_action( 'delete_plugin', array($this, 'BotBanishAuditPluginChanged'));

		remove_action( 'delete_theme', array($this, 'BotBanishAuditThemeChanged') );
		remove_action( 'switch_theme', array($this, 'BotBanishAuditThemeChanged') );
		remove_action( 'after_switch_theme', array($this, 'BotBanishAuditThemeChanged') );

		remove_action( 'upgrader_process_complete', array($this, 'BotBanishAuditUpdated'), 10, 2 );
		remove_action( 'upgrader_package_options', array($this, 'BotBanishAuditUpdatable') );

		remove_action( 'admin_head-plugins.php', array($this, 'BotBanishColumnCssStyles'));
		remove_action( 'manage_plugins_custom_column', array($this, 'BotBanishPluginColumns'), 10, 3);
		remove_action( 'wp_footer', array($this, 'BotBanishCleanUpDays'));
	}


	public function BotBanishAuditChanged($type, $name) {

		switch ($type) {

			case 'plugin':

				$this->BotBanishAuditPluginChanged($name);
				break;

			case 'theme':

				$this->BotBanishAuditThemeChanged($name);
				break;

			case 'core':

				$this->BotBanishAuditCoreChanged($name);
				break;

			case 'language':

				$this->BotBanishAuditLanguageChanged($name);
				break;

			case 'wp':

				$this->BotBanishAuditWPChanged($name);
				break;
		}
	}

	public function BotBanishAuditPluginChanged( $plugin )
	{
		$filters = array(
							'activate_plugin' => 'activated',
							'deactivate_plugin' => 'deactivated',
							'delete_plugin' => 'deleted',
							'upgrader_package_options' => 'update',
							'upgrader_process_complete' => 'update',
							'manage_plugins_custom_column' => 'installed',
						);

		$filter = current_filter();

		if (!isset($filters[$filter]))
			return;

		$auditType = array(
							'plugin' => $plugin,
							'status' => $filters[$filter],
							'msg' => $this->audit_msg_text,
						);

		$this->BotBanishRecordAuditStatus('plugin', $auditType);
	}

	public function BotBanishAuditThemeChanged($stylesheet) {

		$filters = array(
						'delete_theme' => 'delete',
						'switch_theme' => 'activate',
						'after_switch_theme' => 'switch',
						'upgrader_package_options' => 'update',
						'upgrader_process_complete' => isset($this->audit_options['hook_extra']['action']) ? $this->audit_options['hook_extra']['action'] : 'activate',
					);

		$filter = current_filter();

		if (!isset($filters[$filter]))
			return;

		$auditType = array(
							'theme' => $stylesheet,
							'status' => $filters[$filter],
							'msg' => $this->audit_msg_text,
						);

		$this->BotBanishRecordAuditStatus('theme', $auditType);
	}

	public function BotBanishAuditCoreChanged($core) {

		$filters = array(
						'upgrader_package_options' => 'update',
						'upgrader_process_complete' => 'update',
					);

		$filter = current_filter();

		if (!isset($filters[$filter]))
			return;

		global $wp_version;
		
		$auditType = array(
							'core' => $core,
							'status' => $filters[$filter],
							'msg' => isset($_POST['upgrade']) ? $wp_version . ' - ' . $_POST['upgrade'] : $wp_version,
						);

		$this->BotBanishRecordAuditStatus('core', $auditType);
	}

	public function BotBanishAuditLanguageChanged($core) {

	}

	public function BotBanishAuditWPChanged($core) {

	}

	//
	// Checks for updatable plugins
	//

	public function BotBanishAuditUpdatable($options) {

		$hook_extra = $options['hook_extra'];
		$this->audit_options = $options;
		$name = '';
		$type = '';

		if (isset($hook_extra['plugin'])) {

			$name = $hook_extra['plugin'];
			$type = 'plugin';

		} else {

			if (isset($hook_extra['theme'])) {

				$name = isset($_POST['slug']) ? $_POST['slug'] : $options['package'];
				$type = 'theme';

			} else {

				if (isset($hook_extra['core'])) {

					$name = $hook_extra['core'];
					$type = 'core';
				}
			}
		}

		$this->audit_msg_text = 'Started';
		
		switch ($type) {

			case 'plugin':

				$this->BotBanishAuditPluginChanged($name);

				break;

			case 'theme':

				$this->BotBanishAuditThemeChanged($name);

				break;

			case 'core':

				$this->BotBanishAuditCoreChanged($name);

				break;
		}
		
		return $options;
	}

	//
	// Fires after plugin update attempt.
	//

	public function BotBanishAuditUpdated($UpgraderType, $options) {

		$Upgrader = get_class($UpgraderType);
		
		switch ($Upgrader) {

			case 'Plugin_Upgrader':

				if (!method_exists($UpgraderType, 'skin->get_error_messages'))
					break;
				
				$this->audit_msg_text = $UpgraderType->skin->get_error_messages();
				if (empty($this->audit_msg_text)) $this->audit_msg_text = 'Completed';

				if (isset($options['plugins']) && is_array($options['plugins'])) {
					
					foreach ($options['plugins'] as $plugin)
						$this->BotBanishAuditChanged('plugin', $plugin);
				}
				
				break;

			case 'Theme_Upgrader':

				$theme = $UpgraderType->new_theme_data;
				$this->audit_msg_text = $theme['Version'] . ' - ' . $theme['Author'];

				if (isset($options['themes']) && is_array($options['themes'])) {
					
					foreach ($options['themes'] as $plugin)
						$this->BotBanishAuditChanged('theme', $theme['Name']);
				}
				
				break;

			case 'Core_Upgrader':

				$this->audit_msg_text = 'Completed';
				$this->BotBanishAuditChanged('core', 'wordpress');

				break;

			case 'Language_Pack_Upgrader':

				$this->audit_msg_text = 'Completed';
				$this->BotBanishAuditChanged('language', $language);
					
				break;

			case 'WP_Upgrader':

				$this->audit_msg_text = 'Completed';
				$this->BotBanishAuditChanged('wp', $wp);

				break;
		}
	}

	public function BotBanishRecordAuditStatus($type, $auditType) {

		global $wpdb;

		$ip = function_exists('BotBanishGetIP') ? BotBanishGetIP() : $_SERVER['REMOTE_ADDR'];;
		$user_id = get_current_user_id();

		$table_name = $this->audit_table_names[$type];
		$option_name = $this->option_audit_names[$type];
		$options  = get_option($option_name);
		if (!is_array($options)) $options = array();

		$status = $auditType['status'];
		$msg = $auditType['msg'];
			
		switch ($type) {

			case 'plugin':

				$optionType = $auditType['plugin'];
				break;

			case 'theme':

				$optionType = $auditType['theme'];
				break;

			case 'core':

				$optionType = $auditType['core'];
				break;

			case 'language':

				$optionType = $auditType['language'];
				break;

			case 'wp':

				$optionType = $auditType['wp'];
				break;
		}

		$installed = isset($options[ $optionType ]['installed']) ? $options[ $optionType ]['installed'] : $this->BotBanishGetInstalledDate($type, $optionType);

		$options[ $optionType ] = array(
			'installed' => $installed,
			'status' 	=> $status,
			'timestamp' => current_time( 'timestamp' ),
			'ip_adddress' => $ip,
			'name' => $optionType,
			'user_id' => $user_id,
			'msg' => $msg,
		);
				
		update_option( $option_name, $options );
		$this->BotBanishCreateAuditTable($table_name);
		$wpdb->insert($table_name, $options[ $optionType ]);
		$this->audit_msg_text = '';

//		return $installed;
	}


	/**
	 * Sets up the column headings.
	 *
	 * @since 1.0
	 * @uses   $status Indicates on which plugin screen we are currently
	 * @param  array $columns All of the columns for the plugins page
	 * @return array The same array with our new column
	 */

	public function BotBanishPluginsColumnsName( $columns ) {

		global $status;

		// If we're either on the Must Use or Drop-ins tabs, there's no reason to show the column

		if ( ! in_array( $status, array( 'mustuse', 'dropins' ) ) ){

			$columns['install_date'] = __( 'Installed', 'gwlate' );

			if ( ! in_array( $status, array( 'recently_activated', 'active' ) ) ) {

				$columns['last_activated_date'] = __( 'Activated', 'gwlate' );
				$columns['activated_ip_address_columns'] = __( 'IP', 'gwlate' );
				$columns['activated_user_id_columns'] = __( 'User', 'gwlate' );
			}

			if ( ! in_array( $status, array( 'recently_activated', 'inactive' ) ) ) {

				$columns['last_deactivated_date'] = __( 'Deactivated', 'gwlate' );
				$columns['deactivated_ip_address_columns'] = __( 'IP', 'gwlate' );
				$columns['deactivated_user_id_columns'] = __( 'User', 'gwlate' );
			}
		}
		
		return $columns;
	}

	/**
	 * Outputs the dates when plugins. Repeats for all plugins.
	 *
	 * @since  1.0
	 * @param  string $column_name The column key
	 * @param  string $plugin_file The path to the current plugin in the loop
	 * @param  array $plugin_data Extra plugin data
	 */

	public function BotBanishPluginColumns( $column_name, $plugin_file, $plugin_data ) {

		global $wpdb;
		
		$table_name = $this->audit_table_names['plugin'];

		switch ($column_name) {

			case 'install_date':

				$last_updated_row = $wpdb->get_row("SELECT installed FROM `" . $table_name . "` WHERE status = 'installed' and name = '" . $plugin_file . "' ORDER by timestamp DESC LIMIT 1");

				if (!empty($last_updated_row))

					echo $this->BotBanishDisplayDate($last_updated_row->installed);
				else
					echo $this->BotBanishDisplayDate($this->BotBanishAuditPluginChanged($plugin_file));

				break;

			case 'last_activated_date':

				$last_updated_row = $wpdb->get_row("SELECT timestamp FROM `" . $table_name . "` WHERE (status = 'activated' or status = 'update') and name = '" . $plugin_file . "' ORDER by timestamp DESC LIMIT 1");

				if (!empty($last_updated_row))
					echo $this->BotBanishDisplayDate($last_updated_row->timestamp);

				break;

			case 'last_deactivated_date':

				$last_updated_row = $wpdb->get_row("SELECT timestamp FROM `" . $table_name . "` WHERE status = 'deactivated' and name = '".$plugin_file."' ORDER by id DESC LIMIT 1");

				if (!empty($last_updated_row))
					echo $this->BotBanishDisplayDate($last_updated_row->timestamp);

				break;

			case 'activated_ip_address_columns':

				$last_updated_row = $wpdb->get_row("SELECT ip_adddress FROM `" . $table_name . "` WHERE (status = 'activated' or status = 'update') and name = '".$plugin_file."' ORDER by id DESC LIMIT 1");

				if (!empty($last_updated_row))
					echo $last_updated_row->ip_adddress;

				break;

			case 'deactivated_ip_address_columns':

				$last_updated_row = $wpdb->get_row("SELECT ip_adddress FROM `" . $table_name . "` WHERE status = 'deactivated' and name = '".$plugin_file."' ORDER by id DESC LIMIT 1");

				if (!empty($last_updated_row))
					echo $last_updated_row->ip_adddress;

				break;

			case 'activated_user_id_columns':

				$last_updated_row = $wpdb->get_row("SELECT user_id FROM `" . $table_name . "` WHERE (status = 'activated' or status = 'updated') and name = '".$plugin_file."' ORDER by id DESC LIMIT 1");

				if (!empty($last_updated_row))
				{
					$user = get_user_by( 'id', $last_updated_row->user_id );
					if (is_object($user))
						echo  $user->display_name;
				}

				break;

			case 'deactivated_user_id_columns':

				$last_updated_row = $wpdb->get_row("SELECT user_id FROM `" . $table_name . "` WHERE status = 'deactivated' and name = '".$plugin_file."' ORDER by id DESC LIMIT 1");

				if (!empty($last_updated_row))
				{
					$user = get_user_by( 'id', $last_updated_row->user_id );
					if (is_object($user))
						echo  $user->display_name;
				}

				break;
		}
	}

	//
	// Returns the date the plugin was installed.
	//

	function BotBanishGetInstalledDate($type, $name) {

		switch ($type) {

			case 'plugin':

				$plugin_dir = ABSPATH . 'wp-content/plugins/';
				clearstatcache();
				$stat = stat($plugin_dir . $name);
				$date = $stat['mtime'];
				break;

			case 'theme':
			case 'core':
			case 'language':
			case 'wp':
			
				$date = time();

				break;
		}

		return $date;

	}

	function BotBanishDisplayDate( $timestamp ) {

		$options = get_option( $this->option_name );
		$is_relative = isset($options['_botbanishtext_botbanish_plugin_audit_display_datetime']) && $options['_botbanishtext_botbanish_plugin_audit_display_datetime'] ? true : false;

		if ( $is_relative ) {

			return sprintf( esc_html__( '%s ago', 'gwlate' ), human_time_diff( $timestamp, current_time( 'timestamp' ) ) );

		} else {

			$date_time_format = apply_filters( 'BotBanish_date_time_format', sprintf( '%s - %s', get_option('date_format'), get_option('time_format') ) );
			return date_i18n( $date_time_format, $timestamp );
		}
	}

	/**
	 * Set our column's width so it's more readable.
	 *
	 * @since  1.0
	 */
	public function BotBanishColumnCssStyles() {
			?>
			<style>
				#last_deactivated_date,
				.last_deactivated_date,
				.deactivated_ip_address_columns,
				.deactivated_user_id_columns { color:red !important; }

				#last_activated_date,
				.last_activated_date,
				.activated_ip_address_columns,
				.activated_user_id_columns { color:green !important; }

				#install_date { color:black !important; }

				#last_activated_date { color:green width: 110px !important; }
				#activated_ip_address_columns { color:green !important; }
				#activated_user_id_columns { color:green !important; }

				#last_deactivated_date { color:red width: 110px !important; }
				#deactivated_ip_address_columns { color:red !important; }
				#deactivated_user_id_columns { color:red !important; }
			</style>
		<?php
	}

	/**
	 * You can use these filters to add custom links to your plugin row in the plugin list.
	 * @param $links, $file
	 * @return $links [array]
	 */

	public function BotBanishAddCustomPluginLinks($links, $file) {

		if (stripos($file, 'BotBanish.php') !== false) {

			$links[] = '<a href="https://randemsystems.support/botbanish-for-wordpress" target="_blank">Documentation</a>';
			$links[] = '<a href="https://randemsystems.support/" target="_blank">Contact Support</a>';
		}

		return $links;
	}

	// Cleans old entries from dtable

	public function BotBanishCleanUpDays( )
	{
		global $wpdb, $option_name;
		$options = get_option( $option_name );
		$days = $options['_botbanishtext_botbanish_plugin_audit_days'];

		if (empty($days))
			$days = 60;

		$d2 = date('c', strtotime('-'.$days.'days'));
		$timestamp = strtotime($d2);
		$wpdb->query("DELETE FROM " . $this->audit_table_names['plugin'] . " WHERE timestamp < '".$timestamp."'");
	}

	//
	//	If the status table has somehow dissappeared, we will automatically recreate it
	//

	public function BotBanishCreateAuditTable($table_name) {

		global $wpdb;

		$sql = 'SELECT `TABLE_NAME` FROM information_schema.TABLES WHERE (`TABLE_SCHEMA` = "' . DB_NAME . '") AND (`TABLE_NAME` LIKE "%' . $table_name . '%")';
		$tables = $wpdb->query($sql);

		if (!empty($tables)) return;
			
		$sql = '
				CREATE TABLE IF NOT EXISTS ' . $table_name . ' (
				  `id` int UNSIGNED NOT NULL,
				  `name` varchar(250) NOT NULL,
				  `installed` varchar(50) NOT NULL,
				  `timestamp` varchar(50) NOT NULL,
				  `ip_adddress` varchar(50) NOT NULL,
				  `user_id` varchar(50) NOT NULL,
				  `status` varchar(256) NOT NULL,
				  `msg` varchar(250) NOT NULL
				) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;';

		$wpdb->query($sql);

		$sql = '
			ALTER TABLE ' . $table_name . '
			  ADD PRIMARY KEY (`id`);';

		$wpdb->query($sql);

		$sql = '
			ALTER TABLE ' . $table_name . '
			  MODIFY `id` mediumint UNSIGNED NOT NULL AUTO_INCREMENT;';

		$wpdb->query($sql);
	}
}

 if ( is_admin() )
	$BotBanishFirewallPluginAudit = new BotBanishFirewallPluginAudit();
?>