1544 lines
55 KiB
PHP
1544 lines
55 KiB
PHP
<?php
|
|
/**
|
|
* Abstract migration class.
|
|
*
|
|
* @package wsal
|
|
* @subpackage utils
|
|
* @copyright 2026 Melapress
|
|
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3 or higher
|
|
* @link https://wordpress.org/plugins/wp-security-audit-log/
|
|
*/
|
|
|
|
namespace WSAL\Utils;
|
|
|
|
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
|
|
|
|
use WSAL\Helpers\WP_Helper;
|
|
use WSAL\Views\Notifications;
|
|
use WSAL\Controllers\Cron_Jobs;
|
|
use WSAL\Controllers\Connection;
|
|
use WSAL\Entities\Options_Entity;
|
|
use WSAL\Entities\Reports_Entity;
|
|
use WSAL\Helpers\Settings_Helper;
|
|
use WSAL\Entities\Metadata_Entity;
|
|
use WSAL\Entities\Occurrences_Entity;
|
|
use WSAL\Controllers\Plugin_Extensions;
|
|
use WSAL\Loggers\WSAL_Ext_MirrorLogger;
|
|
use WSAL\Helpers\Plugin_Settings_Helper;
|
|
use WSAL\Entities\Generated_Reports_Entity;
|
|
use WSAL\Entities\Custom_Notifications_Entity;
|
|
use WSAL\Reports\Controllers\Statistic_Reports;
|
|
|
|
/**
|
|
* Migration class
|
|
*/
|
|
if ( ! class_exists( '\WSAL\Utils\Migration' ) ) {
|
|
|
|
/**
|
|
* Put all you migration methods here
|
|
*
|
|
* @package WSAL\Utils
|
|
*
|
|
* @since 4.4.0
|
|
*/
|
|
class Migration extends Abstract_Migration {
|
|
|
|
/**
|
|
* The name of the option from which we should extract version
|
|
* Note: version is expected in version format - 1.0.0; 1; 1.0; 1.0.0.0
|
|
* Note: only numbers will be processed
|
|
*
|
|
* @var string
|
|
*
|
|
* @since 4.4.2.1
|
|
*/
|
|
protected static $version_option_name = WSAL_PREFIX . 'plugin_version';
|
|
|
|
/**
|
|
* The constant name where the plugin version is stored
|
|
* Note: version is expected in version format - 1.0.0; 1; 1.0; 1.0.0.0
|
|
* Note: only numbers will be processed
|
|
*
|
|
* @var string
|
|
*
|
|
* @since 4.4.2.1
|
|
*/
|
|
protected static $const_name_of_plugin_version = 'WSAL_VERSION';
|
|
|
|
/**
|
|
* Marks 442 update as started
|
|
*
|
|
* @var boolean
|
|
*
|
|
* @since 4.4.2.1
|
|
*/
|
|
protected static $_442_started = false;
|
|
|
|
/**
|
|
* Migration for version upto 4.4.2
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 4.4.0
|
|
*/
|
|
protected static function migrate_up_to_4420() {
|
|
|
|
self::$_442_started = true;
|
|
|
|
// If the legacy table exists, lets extract the options and remove it.
|
|
if ( Options_Entity::check_table_exists( Options_Entity::get_table_name() ) ) {
|
|
Options_Entity::transfer_options();
|
|
Options_Entity::drop_table();
|
|
// That will reread the connection, as from the import above that might be changed to external.
|
|
Options_Entity::destroy_connection();
|
|
}
|
|
|
|
global $wsal_class;
|
|
|
|
$wsal = $wsal_class;
|
|
$wsal::load_freemius();
|
|
$wsal::load_defaults();
|
|
|
|
$disabled_alerts = WP_Helper::get_global_option( 'disabled-alerts', false );
|
|
|
|
if ( ! \is_array( $disabled_alerts ) ) {
|
|
$disabled_alerts = \explode( ',', $disabled_alerts );
|
|
|
|
\array_walk( $disabled_alerts, 'trim' );
|
|
}
|
|
|
|
$always_disabled_alerts = Settings_Helper::get_default_always_disabled_alerts();
|
|
|
|
if ( ! \is_array( $always_disabled_alerts ) ) {
|
|
$always_disabled_alerts = \explode( ',', $always_disabled_alerts );
|
|
|
|
\array_walk( $always_disabled_alerts, 'trim' );
|
|
}
|
|
|
|
$disabled_alerts = \array_merge( $disabled_alerts, $always_disabled_alerts );
|
|
|
|
/**
|
|
* That is split only for clarity
|
|
*/
|
|
if ( false === $disabled_alerts ) {
|
|
Settings_Helper::set_disabled_alerts( $always_disabled_alerts );
|
|
} elseif ( $disabled_alerts !== $always_disabled_alerts ) {
|
|
Settings_Helper::set_disabled_alerts( $disabled_alerts );
|
|
}
|
|
|
|
self::remove_notice( 'wsal-notice-wsal-privacy-notice-3.2' );
|
|
|
|
WP_Helper::delete_transient( 'wsal-is-advert-dismissed' );
|
|
|
|
/**
|
|
* MainWP Child Stealth Mode Update
|
|
*
|
|
* This update only needs to run if the stealth mode option
|
|
* does not exist on free version.
|
|
*
|
|
* @since 3.2.3.3
|
|
*/
|
|
if ( ! Settings_Helper::get_boolean_option_value( 'mwp-child-stealth-mode', false ) ) {
|
|
Plugin_Settings_Helper::set_mainwp_child_stealth_mode();
|
|
}
|
|
|
|
WP_Helper::delete_global_option( WSAL_PREFIX . 'addon_available_notice_dismissed' );
|
|
|
|
// Removes old file scanning options.
|
|
global $wpdb;
|
|
$plugin_options = $wpdb->get_results( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'wsal_local_files_%'" );
|
|
if ( ! empty( $plugin_options ) ) {
|
|
foreach ( $plugin_options as $option ) {
|
|
WP_Helper::delete_global_option( $option->option_name );
|
|
}
|
|
}
|
|
|
|
// Remove 'system' entry from the front-end events array as it was removed along with 404 tracking.
|
|
$frontend_events = Settings_Helper::get_frontend_events();
|
|
if ( array_key_exists( 'system', $frontend_events ) ) {
|
|
unset( $frontend_events['system'] );
|
|
Settings_Helper::set_frontend_events( $frontend_events );
|
|
}
|
|
|
|
// Remove all settings related to 404 tracking.
|
|
$not_found_page_related_settings = array(
|
|
WSAL_PREFIX . 'log-404',
|
|
WSAL_PREFIX . 'purge-404-log',
|
|
WSAL_PREFIX . 'log-404-referrer',
|
|
WSAL_PREFIX . 'log-visitor-404',
|
|
WSAL_PREFIX . 'purge-visitor-404-log',
|
|
WSAL_PREFIX . 'log-visitor-404-referrer',
|
|
WSAL_PREFIX . 'excluded-urls',
|
|
);
|
|
foreach ( $not_found_page_related_settings as $setting_name ) {
|
|
WP_Helper::delete_global_option( $setting_name );
|
|
}
|
|
|
|
// Remove cron job for purging 404 logs.
|
|
Cron_Jobs::un_schedule_event( 'wsal_log_files_pruning' );
|
|
|
|
// Delete custom logging dir path from the settings.
|
|
WP_Helper::delete_global_option( 'custom-logging-dir' );
|
|
|
|
// Delete dev options from the settings.
|
|
WP_Helper::delete_global_option( 'dev-options' );
|
|
|
|
// phpcs:disable
|
|
// phpcs:enable
|
|
|
|
if ( \class_exists( '\WSAL_Extension_Manager' ) ) {
|
|
\WSAL_Extension_Manager::include_extension( 'external-db' );
|
|
|
|
// Delete cron jobs related to mirror scheduling.
|
|
|
|
// This was previously a constant in WSAL_Ext_Plugin, but we removed it in version 4.3.
|
|
$scheduled_hook_mirroring = 'wsal_run_mirroring';
|
|
|
|
$mirrors = Settings_Helper::get_all_mirrors();
|
|
if ( ! empty( $mirrors ) ) {
|
|
foreach ( $mirrors as $mirror ) {
|
|
// Check if mirror details are valid.
|
|
if ( ! empty( $mirror ) ) {
|
|
$mirror_args = array( $mirror['name'] );
|
|
if ( wp_next_scheduled( $scheduled_hook_mirroring, $mirror_args ) ) {
|
|
wp_clear_scheduled_hook( $scheduled_hook_mirroring, $mirror_args );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( wp_next_scheduled( $scheduled_hook_mirroring ) ) {
|
|
wp_clear_scheduled_hook( $scheduled_hook_mirroring );
|
|
}
|
|
}
|
|
|
|
// Remove nonessential settings related to mysql adapters.
|
|
$mysql_related_settings = array(
|
|
WSAL_PREFIX . 'adapter-type',
|
|
WSAL_PREFIX . 'adapter-user',
|
|
WSAL_PREFIX . 'adapter-password',
|
|
WSAL_PREFIX . 'adapter-name',
|
|
WSAL_PREFIX . 'adapter-hostname',
|
|
WSAL_PREFIX . 'adapter-url-base-prefix',
|
|
WSAL_PREFIX . 'adapter-base-prefix',
|
|
WSAL_PREFIX . 'adapter-ssl',
|
|
WSAL_PREFIX . 'adapter-client-certificate',
|
|
WSAL_PREFIX . 'adapter-ssl-ca',
|
|
WSAL_PREFIX . 'adapter-ssl-cert',
|
|
WSAL_PREFIX . 'adapter-ssl-key',
|
|
WSAL_PREFIX . 'archive-type',
|
|
WSAL_PREFIX . 'archive-user',
|
|
WSAL_PREFIX . 'archive-password',
|
|
WSAL_PREFIX . 'archive-name',
|
|
WSAL_PREFIX . 'archive-hostname',
|
|
WSAL_PREFIX . 'archive-url-base-prefix',
|
|
WSAL_PREFIX . 'archive-base-prefix',
|
|
WSAL_PREFIX . 'archive-ssl',
|
|
WSAL_PREFIX . 'archive-client-certificate',
|
|
WSAL_PREFIX . 'archive-ssl-ca',
|
|
WSAL_PREFIX . 'archive-ssl-cert',
|
|
WSAL_PREFIX . 'archive-ssl-key',
|
|
);
|
|
|
|
foreach ( $mysql_related_settings as $setting_name ) {
|
|
WP_Helper::delete_global_option( $setting_name );
|
|
}
|
|
|
|
// Remove options related to the external db buffer.
|
|
WP_Helper::delete_global_option( 'adapter-use-buffer' );
|
|
WP_Helper::delete_global_option( 'temp_alerts' );
|
|
|
|
// Remove cron job for flushing the buffered events.
|
|
if ( wp_next_scheduled( 'wsal_log_events_ext_db' ) ) {
|
|
wp_clear_scheduled_hook( 'wsal_log_events_ext_db' );
|
|
}
|
|
|
|
// If AWS SDK is not available and an AWS CLoudWatch connection is present, let's create
|
|
// a notice to nudge the user.
|
|
if ( ! \class_exists( '\Aws\CloudWatchLogs\CloudWatchLogsClient' ) && ( ! defined( 'WSAL_LOAD_AWS_SDK' ) || ! \WSAL_LOAD_AWS_SDK ) ) {
|
|
|
|
if ( \class_exists( '\WSAL\Extensions\ExternalDB\Mirrors\WSAL_Ext_Mirrors_AWSCloudWatchConnection' ) ) {
|
|
|
|
$connections = Connection::get_all_connections();
|
|
if ( ! empty( $connections ) ) {
|
|
foreach ( $connections as $connection ) {
|
|
if ( \WSAL\Extensions\ExternalDB\Mirrors\WSAL_Ext_Mirrors_AWSCloudWatchConnection::get_type() === $connection['type'] ) {
|
|
Settings_Helper::set_boolean_option_value( 'show-aws-sdk-config-nudge-4_3_2', true );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove options from autoloading.
|
|
$remove_from_autoload = array(
|
|
'wsal_adapter-connection',
|
|
'wsal_admin-bar-notif-updates',
|
|
'wsal_admin-blocking-plugins-support',
|
|
'wsal_bbpress_addon_available_notice_dismissed',
|
|
'wsal_connection-asd',
|
|
'wsal_connection-aws',
|
|
'wsal_connection-digital_ocean',
|
|
'wsal_connection-freemysqlhosting',
|
|
'wsal_connection-local_mysql_aaa',
|
|
'wsal_connection-local_mysql_eee',
|
|
'wsal_connection-local_mysql_xyz',
|
|
'wsal_connection-testik',
|
|
'wsal_custom-post-types',
|
|
'wsal_daily-summary-email',
|
|
'wsal_db_version',
|
|
'wsal_delete-data',
|
|
'wsal_disable-admin-bar-notif',
|
|
'wsal_disable-daily-summary',
|
|
'wsal_disable-widgets',
|
|
'wsal_disabled-alerts',
|
|
'wsal_dismissed-privacy-notice',
|
|
'wsal_display-name',
|
|
'wsal_events-nav-type',
|
|
'wsal_from-email',
|
|
'wsal_frontend-events',
|
|
'wsal_generated_reports',
|
|
'wsal_gravityforms_addon_available_notice_dismissed',
|
|
'wsal_hide-plugin',
|
|
'wsal_installed_plugin_addon_available',
|
|
'wsal_log-failed-login-limit',
|
|
'wsal_log-visitor-failed-login-limit',
|
|
'wsal_login_page_notification',
|
|
'wsal_login_page_notification_text',
|
|
'wsal_mirror-aws',
|
|
'wsal_mwp-child-stealth-mode',
|
|
'wsal_notification-35727674910782585943',
|
|
'wsal_notification-built-in-10',
|
|
'wsal_notification-built-in-37',
|
|
'wsal_notification-built-in-9',
|
|
'wsal_periodic-report-all',
|
|
'wsal_periodic-report-always-empty',
|
|
'wsal_periodic-report-bbb',
|
|
'wsal_periodic-reports-empty-emails-enabled',
|
|
'wsal_plugin-viewers',
|
|
'wsal_pruning-date',
|
|
'wsal_pruning-date-e',
|
|
'wsal_pruning-unit',
|
|
'wsal_reports-user-autocomplete',
|
|
'wsal_restrict-log-viewer',
|
|
'wsal_restrict-plugin-settings',
|
|
'wsal_setup-modal-dismissed',
|
|
'wsal_twilio-account-sid',
|
|
'wsal_twilio-auth-token',
|
|
'wsal_twilio-number',
|
|
'wsal_use-email',
|
|
'wsal_use-proxy-ip',
|
|
'wsal_version',
|
|
'wsal_woocommerce_addon_available_notice_dismissed',
|
|
'wsal_wp-seo_addon_available_notice_dismissed',
|
|
'wsal_wpforms_addon_available_notice_dismissed',
|
|
);
|
|
|
|
foreach ( $remove_from_autoload as $option ) {
|
|
$option_value = WP_Helper::get_global_option( $option, null );
|
|
|
|
if ( null !== $option_value ) {
|
|
WP_Helper::delete_global_option( $option );
|
|
WP_Helper::set_global_option( $option, $option_value, false );
|
|
}
|
|
}
|
|
|
|
// Set options to autoloading.
|
|
$add_to_autoload = array(
|
|
'wsal_adapter-connection',
|
|
'wsal_admin-bar-notif-updates',
|
|
'wsal_db_version',
|
|
'wsal_disable-admin-bar-notif',
|
|
'wsal_frontend-events',
|
|
'wsal_plugin-viewers',
|
|
'wsal_restrict-log-viewer',
|
|
'wsal_restrict-plugin-settings',
|
|
'wsal_setup-modal-dismissed',
|
|
'wsal_version',
|
|
);
|
|
|
|
foreach ( $add_to_autoload as $option ) {
|
|
$option_value = WP_Helper::get_global_option( $option, null );
|
|
if ( null !== $option_value ) {
|
|
WP_Helper::delete_global_option( $option );
|
|
WP_Helper::set_global_option( $option, $option_value, true );
|
|
}
|
|
}
|
|
|
|
// Change the name of the option storing excluded post meta fields.
|
|
$excluded_custom_fields = WP_Helper::get_global_option( 'excluded-custom', null );
|
|
if ( ! is_null( $excluded_custom_fields ) ) {
|
|
WP_Helper::set_global_option( 'excluded-post-meta', $excluded_custom_fields );
|
|
WP_Helper::delete_global_option( 'excluded-custom' );
|
|
}
|
|
|
|
$not_found_page_related_settings = array(
|
|
'wsal_scan-in-progress',
|
|
'wsal_last-scanned',
|
|
'wsal_is_initial_scan_0',
|
|
'wsal_is_initial_scan_1',
|
|
'wsal_is_initial_scan_2',
|
|
'wsal_is_initial_scan_3',
|
|
'wsal_is_initial_scan_4',
|
|
'wsal_is_initial_scan_5',
|
|
'wsal_is_initial_scan_6',
|
|
'wsal_last_scan_start',
|
|
'wsal_scanned_dirs',
|
|
);
|
|
foreach ( $not_found_page_related_settings as $setting_name ) {
|
|
WP_Helper::delete_global_option( $setting_name );
|
|
}
|
|
|
|
WP_Helper::delete_global_option( 'reports-user-autocomplete' );
|
|
|
|
// External DB settings.
|
|
foreach ( array( 'archive-connection', 'adapter-connection' ) as $connection_option_name ) {
|
|
$connection_name = WP_Helper::get_global_option( $connection_option_name, null );
|
|
if ( ! is_null( $connection_name ) ) {
|
|
$db_connection = Connection::load_connection_config( $connection_name );
|
|
if ( is_array( $db_connection ) && empty( $db_connection['hostname'] ) && empty( $db_connection['db_name'] ) ) {
|
|
if ( 'adapter-connection' === $connection_option_name ) {
|
|
Connection::remove_external_storage_config();
|
|
} elseif ( 'archive-connection' === $connection_option_name ) {
|
|
Connection::remove_archiving_config();
|
|
WP_Helper::delete_global_option( 'archiving-e' );
|
|
WP_Helper::delete_global_option( 'archiving-last-created' );
|
|
}
|
|
|
|
if ( defined( 'WSAL_CONN_PREFIX' ) ) {
|
|
// Function WSAL_Ext_Common::delete_connection is not used on purpose because it would try to
|
|
// trigger an event which would result in error while doing this clean-up.
|
|
WP_Helper::delete_global_option( WSAL_CONN_PREFIX . $connection_name );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Extension manager will be available only if the license is already active.
|
|
if ( \class_exists( '\WSAL_Extension_Manager' ) ) {
|
|
if ( ! \WSAL_Extension_Manager::is_messaging_available() || ! \WSAL_Extension_Manager::is_mirroring_available() ) {
|
|
// Check if SMS notifications or any external mirrors are setup + force plugin to show a notice.
|
|
$mirrors_in_use = false;
|
|
$mirrors = Settings_Helper::get_all_mirrors();
|
|
$mirrors_in_use = ! empty( $mirrors );
|
|
|
|
$notifications_in_use = false;
|
|
|
|
global $wpdb;
|
|
|
|
if ( ! \defined( 'WSAL_OPT_PREFIX' ) ) {
|
|
/**
|
|
* Holds the option prefix
|
|
*/
|
|
define( 'WSAL_OPT_PREFIX', 'notification-' );
|
|
}
|
|
|
|
$opt_prefix = WSAL_PREFIX . WSAL_OPT_PREFIX;
|
|
$prepared_query = $wpdb->prepare( // phpcs:ignore
|
|
"SELECT * FROM {$wpdb->base_prefix}options WHERE option_name LIKE %s;",
|
|
$opt_prefix . '%%'
|
|
);
|
|
|
|
$notifications = $wpdb->get_results( $prepared_query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
|
|
|
if ( ! $mirrors_in_use && ! empty( $notifications ) ) {
|
|
|
|
if ( ! empty( $notifications ) ) {
|
|
foreach ( $notifications as $notification ) {
|
|
$item = \maybe_unserialize( $notification->option_value );
|
|
|
|
// Skip if the unserialized value is not a valid notification object.
|
|
if ( ! is_object( $item ) || ! isset( $item->phone ) ) {
|
|
continue;
|
|
}
|
|
|
|
if ( is_string( $item->phone ) && strlen( $item->phone ) > 0 ) {
|
|
$notifications_in_use = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( $notifications_in_use || $mirrors_in_use ) {
|
|
Settings_Helper::set_boolean_option_value( 'show-helper-plugin-needed-nudge', true, false );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* User session table should be always in the local database.
|
|
*
|
|
* Premium or not does not matter. User can had premium but in time of the upgrade, their license could be expired,
|
|
* that does not mean that they will never switch back to the premium version.
|
|
*/
|
|
$table_exists = Occurrences_Entity::check_table_exists( $wpdb->base_prefix . 'wsal_sessions' );
|
|
if ( $table_exists ) {
|
|
$column_exists = Occurrences_Entity::check_column(
|
|
$wpdb->base_prefix . 'wsal_sessions',
|
|
'session_token',
|
|
'varchar( 255 )'
|
|
);
|
|
|
|
if ( ! $column_exists ) {
|
|
$alter_query = 'ALTER TABLE `' . $wpdb->base_prefix . 'wsal_sessions` CHANGE `session_token` `session_token` VARCHAR(128)
|
|
NOT NULL;';
|
|
|
|
$wpdb->query( $alter_query ); // phpcs:ignore
|
|
}
|
|
}
|
|
|
|
Occurrences_Entity::destroy_connection();
|
|
|
|
// First check if the table exists, if not then we can execute the migration process.
|
|
if ( ! Occurrences_Entity::check_table_exists() ) {
|
|
Occurrences_Entity::create_table();
|
|
// Remove metatdata table if one exists and recreate it.
|
|
Metadata_Entity::drop_table();
|
|
Metadata_Entity::create_table();
|
|
} else {
|
|
|
|
// If one of the new columns exists there is no need to alter the table.
|
|
$column_exists = Occurrences_Entity::check_column(
|
|
Occurrences_Entity::get_table_name(),
|
|
'client_ip',
|
|
'varchar( 255 )'
|
|
);
|
|
|
|
if ( ! $column_exists ) {
|
|
$upgrade_sql = Occurrences_Entity::get_upgrade_query();
|
|
Occurrences_Entity::get_connection()->query( $upgrade_sql );
|
|
|
|
$connection = WP_Helper::get_global_option( 'adapter-connection' );
|
|
if ( empty( $connection ) ) {
|
|
$connection = 'local';
|
|
}
|
|
|
|
// Create a background job to migrate the metadata.
|
|
$job_info = array(
|
|
'start_time' => current_time( 'timestamp' ), // phpcs:ignore
|
|
'processed_events_count' => 0,
|
|
'batch_size' => 50,
|
|
'connection' => $connection,
|
|
);
|
|
|
|
// Create and dispatch the background process itself.
|
|
$bg_process = new \WSAL\Migration\Metadata_Migration_440( $connection );
|
|
|
|
// Store the initial info to the db.
|
|
\WSAL\Migration\Metadata_Migration_440::store_migration_info( $job_info );
|
|
$bg_process->push_to_queue( $job_info );
|
|
$bg_process->save();
|
|
$bg_process->dispatch();
|
|
}
|
|
}
|
|
|
|
// Archive is in use.
|
|
$connection = WP_Helper::get_global_option( 'archive-connection' );
|
|
if ( ! empty( $connection ) ) {
|
|
Occurrences_Entity::set_connection(
|
|
Connection::get_connection( $connection )
|
|
);
|
|
|
|
// First check if the table exists, if not then we can execute the migration process.
|
|
if ( ! Occurrences_Entity::check_table_exists() ) {
|
|
Occurrences_Entity::create_table();
|
|
// Remove metatdata table if one exists and recreate it.
|
|
Metadata_Entity::drop_table();
|
|
Metadata_Entity::create_table();
|
|
} else {
|
|
|
|
// If one of the new columns exists there is no need to alter the table.
|
|
$column_exists = Occurrences_Entity::check_column(
|
|
Occurrences_Entity::get_table_name(),
|
|
'client_ip',
|
|
'varchar( 255 )'
|
|
);
|
|
if ( ! $column_exists ) {
|
|
$upgrade_sql = Occurrences_Entity::get_upgrade_query();
|
|
Occurrences_Entity::get_connection()->query( $upgrade_sql );
|
|
|
|
// Create a background job to migrate the metadata.
|
|
$job_info = array(
|
|
'start_time' => current_time( 'timestamp' ), // phpcs:ignore
|
|
'processed_events_count' => 0,
|
|
'batch_size' => 50,
|
|
'connection' => $connection,
|
|
);
|
|
|
|
// Create and dispatch the background process itself.
|
|
$bg_process = new \WSAL\Migration\Metadata_Migration_440( 'archive' );
|
|
|
|
// Store the initial info to the db.
|
|
\WSAL\Migration\Metadata_Migration_440::store_migration_info( $job_info );
|
|
$bg_process->push_to_queue( $job_info );
|
|
$bg_process->save();
|
|
$bg_process->dispatch();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 4.4.2.1
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 4.4.2.1
|
|
*/
|
|
protected static function migrate_up_to_4421() {
|
|
\WSAL\Helpers\WP_Helper::delete_global_option( 'migration-started' );
|
|
|
|
if ( ! self::$_442_started ) {
|
|
self::migrate_up_to_4420();
|
|
}
|
|
|
|
global $wpdb;
|
|
/**
|
|
* User session table should be always in the local database.
|
|
*
|
|
* Premium or not does not matter. User can had premium but in time of the upgrade, their license could be expired,
|
|
* that does not mean that they will never switch back to the premium version.
|
|
*/
|
|
$table_exists = Occurrences_Entity::check_table_exists( $wpdb->base_prefix . 'wsal_sessions' );
|
|
if ( $table_exists ) {
|
|
$column_exists = Occurrences_Entity::check_column(
|
|
$wpdb->base_prefix . 'wsal_sessions',
|
|
'sites',
|
|
'longtext'
|
|
);
|
|
$column_exists_id = Occurrences_Entity::check_column(
|
|
$wpdb->base_prefix . 'wsal_sessions',
|
|
'id',
|
|
'bigint'
|
|
);
|
|
|
|
if ( ! $column_exists || $column_exists_id ) {
|
|
$alter_query = 'DROP TABLE `' . $wpdb->base_prefix . 'wsal_sessions`;';
|
|
|
|
$wpdb->query( $alter_query ); // phpcs:ignore
|
|
|
|
if ( \class_exists( '\WSAL\Adapter\User_Sessions' ) ) {
|
|
\WSAL\Adapter\User_Sessions::create_table();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 4.4.3
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 4.4.3
|
|
*/
|
|
protected static function migrate_up_to_4430() {
|
|
|
|
// phpcs:disable
|
|
// phpcs:enable
|
|
|
|
if ( \class_exists( '\WSAL\Loggers\WSAL_Ext_MirrorLogger' ) && method_exists( '\WSAL\Helpers\Settings_Helper', 'get_working_dir_path_static' ) ) {
|
|
|
|
$working_dir_path = Settings_Helper::get_working_dir_path_static();
|
|
|
|
if ( file_exists( $working_dir_path . \WSAL\Loggers\WSAL_Ext_MirrorLogger::FILE_NAME_FAILED_LOGS . '.json' ) ) {
|
|
rename( $working_dir_path . WSAL_Ext_MirrorLogger::FILE_NAME_FAILED_LOGS . '.json', $working_dir_path . WSAL_Ext_MirrorLogger::FILE_NAME_FAILED_LOGS . '.php' );
|
|
|
|
$line = fgets(
|
|
fopen( $working_dir_path . WSAL_Ext_MirrorLogger::FILE_NAME_FAILED_LOGS . '.php', 'r' )
|
|
);
|
|
if ( false === strpos( $line, '<?php' ) ) {
|
|
$fp_source = fopen( $working_dir_path . WSAL_Ext_MirrorLogger::FILE_NAME_FAILED_LOGS . '.php', 'r' );
|
|
$fp_dest = fopen( $working_dir_path . WSAL_Ext_MirrorLogger::FILE_NAME_FAILED_LOGS . '.php.tmp', 'w' ); // better to generate a real temp filename.
|
|
fwrite( $fp_dest, '<?php' . "\n" );
|
|
while ( ! feof( $fp_source ) ) {
|
|
fwrite( $fp_dest, fread( $fp_source, 8192 ) );
|
|
}
|
|
fclose( $fp_source );
|
|
fclose( $fp_dest );
|
|
unlink( $working_dir_path . WSAL_Ext_MirrorLogger::FILE_NAME_FAILED_LOGS . '.php' );
|
|
rename( $working_dir_path . WSAL_Ext_MirrorLogger::FILE_NAME_FAILED_LOGS . '.php.tmp', $working_dir_path . WSAL_Ext_MirrorLogger::FILE_NAME_FAILED_LOGS . '.php' );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 4.5.0
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 4.5.0
|
|
*/
|
|
protected static function migrate_up_to_4500() {
|
|
Metadata_Entity::create_indexes();
|
|
Occurrences_Entity::create_indexes();
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 4.5.2
|
|
*
|
|
* Converts excluded users to array
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 4.5.2
|
|
*/
|
|
protected static function migrate_up_to_4520() {
|
|
$excluded_users = Settings_Helper::get_option_value( 'excluded-users', array() );
|
|
if ( is_string( $excluded_users ) ) {
|
|
$excluded_users = array_unique( array_filter( explode( ',', $excluded_users ) ) );
|
|
Settings_Helper::set_option_value( 'excluded-users', $excluded_users );
|
|
}
|
|
$excluded_roles = Settings_Helper::get_option_value( 'excluded-roles', array() );
|
|
if ( is_string( $excluded_roles ) ) {
|
|
$excluded_roles = array_unique( array_filter( explode( ',', $excluded_roles ) ) );
|
|
Settings_Helper::set_option_value( 'excluded-roles', $excluded_roles );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 4.6.0
|
|
*
|
|
* Removes some redundant options
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 4.6.0
|
|
*/
|
|
protected static function migrate_up_to_4600() {
|
|
WP_Helper::delete_global_option( 'wsal_version' );
|
|
WP_Helper::delete_global_option( 'disable-refresh' );
|
|
Plugin_Extensions::deactivate_plugins();
|
|
WP_Helper::set_global_option( 'extensions-merged-notice', true );
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 4.6.1
|
|
*
|
|
* Removes some redundant options
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 4.6.1
|
|
*/
|
|
protected static function migrate_up_to_4610() {
|
|
WP_Helper::delete_global_option( 'events-nav-type' );
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 5.0.0
|
|
*
|
|
* Removes some redundant options
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.0.0
|
|
*/
|
|
public static function migrate_up_to_5000() {
|
|
self::migrate_up_to_4610();
|
|
|
|
self::migrate_users();
|
|
|
|
if ( \class_exists( Generated_Reports_Entity::class ) ) {
|
|
/**
|
|
* Migrate generated reports - if there are any.
|
|
*/
|
|
$reports = Settings_Helper::get_option_value( 'generated_reports', array() );
|
|
if ( ! empty( $reports ) ) {
|
|
|
|
foreach ( $reports as $report_array ) {
|
|
|
|
$username = \get_userdata( $report_array['user'] )->user_login;
|
|
$filename = pathinfo( $report_array['file'], PATHINFO_FILENAME );
|
|
|
|
$report_filters = array();
|
|
|
|
if ( isset( $report_array['filters']['type_statistics'] ) && ! empty( $report_array['filters']['type_statistics'] ) ) {
|
|
$report_type = Statistic_Reports::get_statistical_report_from_legacy_type()[ (int) $report_array['filters']['type_statistics'] ];
|
|
|
|
$report_filters[ esc_html__( 'Report Type', 'wp-security-audit-log' ) ] = Statistic_Reports::get_statistical_report_title()[ $report_type ];
|
|
}
|
|
|
|
Generated_Reports_Entity::save(
|
|
array(
|
|
'generated_report_user_id' => (int) $report_array['user'],
|
|
'generated_report_username' => $username,
|
|
'generated_report_filters' => $report_array['filters'],
|
|
'generated_report_file' => $filename,
|
|
'generated_report_name' => $filename,
|
|
'created_on' => $report_array['time'],
|
|
'generated_report_format' => ( isset( $report_array['filters']['type_statistics'] ) && ! empty( $report_array['filters']['type_statistics'] ) ) ? 999 : 0,
|
|
'generated_report_filters_normalized' => $report_filters,
|
|
'generated_report_header_columns' => '',
|
|
'generated_report_where_clause' => '',
|
|
'generated_report_finished' => true,
|
|
'generated_report_to_date' => 0,
|
|
'generated_report_number_of_records' => -1,
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
$reports_white_labeling = array();
|
|
$reports_white_labeling['business_name'] = Settings_Helper::get_option_value( 'reports-business-name', null );
|
|
Settings_Helper::delete_option_value( 'reports-business-name' );
|
|
$reports_white_labeling['name_surname'] = Settings_Helper::get_option_value( 'reports-contact-name', null );
|
|
Settings_Helper::delete_option_value( 'reports-contact-name' );
|
|
$reports_white_labeling['email'] = Settings_Helper::get_option_value( 'reports-contact-email', null );
|
|
Settings_Helper::delete_option_value( 'reports-contact-email' );
|
|
$reports_white_labeling['phone_number'] = Settings_Helper::get_option_value( 'reports-contact-phone', null );
|
|
Settings_Helper::delete_option_value( 'reports-contact-phone' );
|
|
$reports_white_labeling['logo'] = Settings_Helper::get_option_value( 'reports-custom-logo', null );
|
|
Settings_Helper::delete_option_value( 'reports-custom-logo' );
|
|
$reports_white_labeling['logo_url'] = Settings_Helper::get_option_value( 'reports-custom-logo-link', null );
|
|
Settings_Helper::delete_option_value( 'reports-custom-logo-link' );
|
|
|
|
$reports_white_labeling = array_filter( $reports_white_labeling );
|
|
|
|
if ( ! empty( $reports_white_labeling ) ) {
|
|
Settings_Helper::set_option_value( 'report-white-label-settings', $reports_white_labeling );
|
|
}
|
|
|
|
$reports_column_settings = array();
|
|
$reports_column_settings['reports_auto_purge_older_than_days'] = (int) Settings_Helper::get_option_value( 'reports-pruning-threshold', 30 );
|
|
Settings_Helper::delete_option_value( 'reports-pruning-threshold' );
|
|
$reports_column_settings['reports_auto_purge_enabled'] = (bool) Settings_Helper::get_option_value( 'reports-pruning-enabled', true );
|
|
Settings_Helper::delete_option_value( 'reports-pruning-enabled' );
|
|
$reports_column_settings['reports_send_empty_summary_emails'] = (bool) Settings_Helper::get_option_value( 'periodic-reports-empty-emails-enabled', false );
|
|
Settings_Helper::delete_option_value( 'periodic-reports-empty-emails-enabled' );
|
|
|
|
$reports_column_settings = array_filter( $reports_column_settings );
|
|
|
|
if ( ! empty( $reports_column_settings ) ) {
|
|
Settings_Helper::set_option_value( 'report-generate-columns-settings', $reports_column_settings );
|
|
}
|
|
|
|
foreach ( self::get_all_periodic_reports() as $report ) {
|
|
if ( ! $report->owner ) {
|
|
$username = __( 'System', 'wp-security-audit-log' );
|
|
} else {
|
|
$userdata = \WP_User::get_data_by( 'id', $report->owner );
|
|
|
|
if ( ! $userdata ) {
|
|
$username = __( 'System', 'wp-security-audit-log' );
|
|
}
|
|
|
|
$username = $userdata->user_login;
|
|
|
|
}
|
|
|
|
$only_these_post_titles = array();
|
|
if ( isset( $report->post_ids ) ) {
|
|
foreach ( $report->post_ids as $id ) {
|
|
$only_these_post_titles[] = get_the_title( $id );
|
|
}
|
|
}
|
|
|
|
$except_these_post_titles = array();
|
|
if ( isset( $report->post_ids_excluded ) ) {
|
|
foreach ( $report->post_ids_excluded as $id ) {
|
|
$except_these_post_titles[] = get_the_title( $id );
|
|
}
|
|
}
|
|
|
|
$data = array(
|
|
'report_type_sites' => ( isset( $report->sites ) && ! empty( $report->sites ) ) ? 'only_these' : ( ( isset( $report->sites_excluded ) && ! empty( $report->sites_excluded ) ) ? 'all_except' : '' ),
|
|
'only_these_sites' => ( isset( $report->sites ) ) ? $report->sites : array(),
|
|
'except_these_sites' => ( isset( $report->sites_excluded ) ) ? $report->sites_excluded : array(),
|
|
|
|
'report_type_users' => ( isset( $report->users ) && ! empty( $report->users ) ) ? 'only_these' : ( ( isset( $report->users_excluded ) && ! empty( $report->users_excluded ) ) ? 'all_except' : '' ),
|
|
'only_these_users' => ( isset( $report->users ) ) ? $report->users : array(),
|
|
'except_these_users' => ( isset( $report->users_excluded ) ) ? $report->users_excluded : array(),
|
|
|
|
'report_type_roles' => ( isset( $report->roles ) && ! empty( $report->roles ) ) ? 'only_these' : ( ( isset( $report->roles_excluded ) && ! empty( $report->roles_excluded ) ) ? 'all_except' : '' ),
|
|
'only_these_roles' => ( isset( $report->roles ) ) ? $report->roles : array(),
|
|
'except_these_roles' => ( isset( $report->roles_excluded ) ) ? $report->roles_excluded : array(),
|
|
|
|
'report_type_ips' => ( isset( $report->ipAddresses ) && ! empty( $report->ipAddresses ) ) ? 'only_these' : ( ( isset( $report->ipAddresses_excluded ) && ! empty( $report->ipAddresses_excluded ) ) ? 'all_except' : '' ), // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
|
'only_these_ips' => ( isset( $report->ipAddresses ) ) ? $report->ipAddresses : array(), // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
|
'except_these_ips' => ( isset( $report->ipAddresses_excluded ) ) ? $report->ipAddresses_excluded : array(), // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
|
|
|
'report_type_objects' => ( isset( $report->objects ) && ! empty( $report->objects ) ) ? 'only_these' : ( ( isset( $report->objects_excluded ) && ! empty( $report->objects_excluded ) ) ? 'all_except' : '' ),
|
|
'only_these_objects' => ( isset( $report->objects ) ) ? $report->objects : array(),
|
|
'except_these_objects' => ( isset( $report->objects_excluded ) ) ? $report->objects_excluded : array(),
|
|
|
|
'report_type_event_types' => ( isset( $report->event_types ) && ! empty( $report->event_types ) ) ? 'only_these' : ( ( isset( $report->event_types_excluded ) && ! empty( $report->event_types_excluded ) ) ? 'all_except' : '' ),
|
|
'only_these_event_types' => ( isset( $report->event_types ) ) ? $report->event_types : array(),
|
|
'except_these_event_types' => ( isset( $report->event_types_excluded ) ) ? $report->event_types_excluded : array(),
|
|
|
|
'report_type_post_titles' => ( isset( $only_these_post_titles ) && ! empty( $only_these_post_titles ) ) ? 'only_these' : ( ( isset( $except_these_post_titles ) && ! empty( $except_these_post_titles ) ) ? 'all_except' : '' ),
|
|
'only_these_post_titles' => ( isset( $only_these_post_titles ) ) ? $only_these_post_titles : array(),
|
|
'except_these_post_titles' => ( isset( $except_these_post_titles ) ) ? $except_these_post_titles : array(),
|
|
|
|
'report_type_post_types' => ( isset( $report->post_types ) && ! empty( $report->post_types ) ) ? 'only_these' : ( ( isset( $report->post_types_excluded ) && ! empty( $report->post_types_excluded ) ) ? 'all_except' : '' ),
|
|
'only_these_post_types' => ( isset( $report->post_types ) ) ? $report->post_types : array(),
|
|
'except_these_post_types' => ( isset( $report->post_types_excluded ) ) ? $report->post_types_excluded : array(),
|
|
|
|
'report_type_post_statuses' => ( isset( $report->post_statuses ) && ! empty( $report->post_statuses ) ) ? 'only_these' : ( ( isset( $report->post_statuses_excluded ) && ! empty( $report->post_statuses_excluded ) ) ? 'all_except' : '' ),
|
|
'only_these_post_statuses' => ( isset( $report->post_statuses ) ) ? $report->post_statuses : array(),
|
|
'except_these_post_statuses' => ( isset( $report->post_statuses_excluded ) ) ? $report->post_statuses_excluded : array(),
|
|
|
|
'report_type_alert_ids' => ( isset( $report->alert_ids ) && ! empty( $report->alert_ids ) ) ? 'only_these' : ( ( isset( $report->alert_ids_excluded ) && ! empty( $report->alert_ids_excluded ) ) ? 'all_except' : '' ),
|
|
'only_these_alert_ids' => ( isset( $report->alert_ids ) ) ? $report->alert_ids : array(),
|
|
'except_these_alert_ids' => ( isset( $report->alert_ids_excluded ) ) ? $report->alert_ids_excluded : array(),
|
|
|
|
'report_type_alert_groups' => ( isset( $report->alert_groups ) && ! empty( $report->alert_groups ) ) ? 'only_these' : ( ( isset( $report->alert_groups_excluded ) && ! empty( $report->alert_groups_excluded ) ) ? 'all_except' : '' ),
|
|
'only_these_alert_groups' => ( isset( $report->alert_groups ) ) ? $report->alert_groups : array(),
|
|
'except_these_alert_groups' => ( isset( $report->alert_groups_excluded ) ) ? $report->alert_groups_excluded : array(),
|
|
|
|
'report_type_severities' => ( isset( $report->severities ) && ! empty( $report->severities ) ) ? 'only_these' : ( ( isset( $report->severities_excluded ) && ! empty( $report->severities_excluded ) ) ? 'all_except' : '' ),
|
|
'only_these_severities' => ( isset( $report->severities ) ) ? $report->severities : array(),
|
|
'except_these_severities' => ( isset( $report->severities_excluded ) ) ? $report->severities_excluded : array(),
|
|
|
|
'report_start_date' => '',
|
|
'report_end_date' => '',
|
|
'report_tag' => '',
|
|
'report_include_archive' => false,
|
|
'report_title' => ( isset( $report->custom_title ) ) ? $report->custom_title : '',
|
|
'report_comment' => ( isset( $report->comment ) ) ? $report->comment : '',
|
|
'report_metadata' => ( isset( $report->no_meta ) ) ? $report->no_meta : true,
|
|
);
|
|
|
|
if ( empty( $data['only_these_sites'] ) ) {
|
|
unset( $data['only_these_sites'] );
|
|
}
|
|
if ( empty( $data['except_these_sites'] ) ) {
|
|
unset( $data['except_these_sites'] );
|
|
}
|
|
|
|
if ( empty( $data['only_these_users'] ) ) {
|
|
unset( $data['only_these_users'] );
|
|
}
|
|
if ( empty( $data['except_these_users'] ) ) {
|
|
unset( $data['except_these_users'] );
|
|
}
|
|
|
|
if ( empty( $data['only_these_roles'] ) ) {
|
|
unset( $data['only_these_roles'] );
|
|
}
|
|
if ( empty( $data['except_these_roles'] ) ) {
|
|
unset( $data['except_these_roles'] );
|
|
}
|
|
|
|
if ( empty( $data['only_these_ips'] ) ) {
|
|
unset( $data['only_these_ips'] );
|
|
}
|
|
if ( empty( $data['except_these_ips'] ) ) {
|
|
unset( $data['except_these_ips'] );
|
|
}
|
|
|
|
if ( empty( $data['only_these_objects'] ) ) {
|
|
unset( $data['only_these_objects'] );
|
|
}
|
|
if ( empty( $data['except_these_objects'] ) ) {
|
|
unset( $data['except_these_objects'] );
|
|
}
|
|
|
|
if ( empty( $data['only_these_event_types'] ) ) {
|
|
unset( $data['only_these_event_types'] );
|
|
}
|
|
if ( empty( $data['except_these_event_types'] ) ) {
|
|
unset( $data['except_these_event_types'] );
|
|
}
|
|
|
|
if ( empty( $data['only_these_post_titles'] ) ) {
|
|
unset( $data['only_these_post_titles'] );
|
|
}
|
|
if ( empty( $data['except_these_post_titles'] ) ) {
|
|
unset( $data['except_these_post_titles'] );
|
|
}
|
|
|
|
if ( empty( $data['only_these_post_types'] ) ) {
|
|
unset( $data['only_these_post_types'] );
|
|
}
|
|
if ( empty( $data['except_these_post_types'] ) ) {
|
|
unset( $data['except_these_post_types'] );
|
|
}
|
|
|
|
if ( empty( $data['only_these_post_statuses'] ) ) {
|
|
unset( $data['only_these_post_statuses'] );
|
|
}
|
|
if ( empty( $data['except_these_post_statuses'] ) ) {
|
|
unset( $data['except_these_post_statuses'] );
|
|
}
|
|
|
|
if ( empty( $data['only_these_alert_ids'] ) ) {
|
|
unset( $data['only_these_alert_ids'] );
|
|
}
|
|
if ( empty( $data['except_these_alert_ids'] ) ) {
|
|
unset( $data['except_these_alert_ids'] );
|
|
}
|
|
|
|
if ( empty( $data['only_these_alert_groups'] ) ) {
|
|
unset( $data['only_these_alert_groups'] );
|
|
}
|
|
if ( empty( $data['except_these_alert_groups'] ) ) {
|
|
unset( $data['except_these_alert_groups'] );
|
|
}
|
|
|
|
if ( empty( $data['only_these_severities'] ) ) {
|
|
unset( $data['only_these_severities'] );
|
|
}
|
|
if ( empty( $data['except_these_severities'] ) ) {
|
|
unset( $data['except_these_severities'] );
|
|
}
|
|
|
|
Reports_Entity::save(
|
|
array(
|
|
'report_name' => $report->title,
|
|
'created_on' => $report->dateAdded, // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
|
'report_user_id' => $report->owner,
|
|
'report_username' => $username,
|
|
'report_frequency' => Reports_Entity::get_frequency_from_name( (string) $report->frequency ),
|
|
'report_format' => 0,
|
|
'report_email' => $report->email,
|
|
'report_data' => $data,
|
|
'report_tag' => '',
|
|
'report_disabled' => false,
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 5.1.1
|
|
*
|
|
* Removes some redundant options
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.1.1
|
|
*/
|
|
protected static function migrate_up_to_5110() {
|
|
Cron_Jobs::un_schedule_event( 'wsal_delete_logins' );
|
|
Cron_Jobs::un_schedule_event( 'wsal_cleanup' );
|
|
|
|
$disabled_alerts = WP_Helper::get_global_option( 'disabled-alerts', false );
|
|
|
|
if ( ! is_array( $disabled_alerts ) ) {
|
|
$disabled_alerts = \explode( ',', $disabled_alerts );
|
|
|
|
\array_walk( $disabled_alerts, 'trim' );
|
|
|
|
WP_Helper::update_global_option( 'disabled-alerts', $disabled_alerts );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 5.3.0
|
|
*
|
|
* Migrates notification settings
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.3.0
|
|
*/
|
|
public static function migrate_up_to_5300() {
|
|
Migrate_53::migrate_up_to_5300();
|
|
|
|
if ( 'free' === \WpSecurityAuditLog::get_plugin_version() ) {
|
|
$options = Settings_Helper::get_option_value( Notifications::BUILT_IN_NOTIFICATIONS_SETTINGS_NAME, array() );
|
|
|
|
$options['daily_summary_notification'] = false;
|
|
$options['weekly_summary_notification'] = false;
|
|
|
|
Settings_Helper::set_option_value( Notifications::BUILT_IN_NOTIFICATIONS_SETTINGS_NAME, $options );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 5.3.2
|
|
*
|
|
* Migrates notification settings
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.3.2
|
|
*/
|
|
public static function migrate_up_to_5320() {
|
|
// Code from here is moved to 5300 migration method.
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 5.3.3
|
|
*
|
|
* Migrates notification settings
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.3.3
|
|
*/
|
|
public static function migrate_up_to_5330() {
|
|
|
|
Cron_Jobs::remove_cron_option( 'wsal_daily_summary_report' );
|
|
}
|
|
/**
|
|
* Migration for version upto 5.3.4
|
|
*
|
|
* Migrates notification settings
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.3.4
|
|
*/
|
|
public static function migrate_up_to_5340() {
|
|
$disabled_alerts = (array) Settings_Helper::get_option_value( 'disabled-alerts', array() );
|
|
|
|
$disabled_alerts[] = 6066;
|
|
$disabled_alerts[] = 6067;
|
|
$disabled_alerts[] = 6068;
|
|
$disabled_alerts[] = 6069;
|
|
$disabled_alerts[] = 6070;
|
|
$disabled_alerts[] = 6071;
|
|
$disabled_alerts[] = 6072;
|
|
|
|
$disabled_alerts = \array_unique( $disabled_alerts );
|
|
|
|
Settings_Helper::set_disabled_alerts( $disabled_alerts );
|
|
|
|
if ( \class_exists( '\WSAL\Entities\Custom_Notifications_Entity' ) && \method_exists( Custom_Notifications_Entity::class, 'get_upgrade_query_slack_template' ) ) {
|
|
|
|
// If one of the new columns exists there is no need to alter the table.
|
|
$column_exists = Custom_Notifications_Entity::check_column(
|
|
Custom_Notifications_Entity::get_table_name(),
|
|
'notification_slack_template',
|
|
'longtext'
|
|
);
|
|
|
|
if ( ! $column_exists ) {
|
|
$upgrade_sql = Custom_Notifications_Entity::get_upgrade_query_slack_template();
|
|
Custom_Notifications_Entity::get_connection()->query( $upgrade_sql );
|
|
}
|
|
}
|
|
|
|
$settings = Notifications::get_global_notifications_setting();
|
|
|
|
if ( isset( $settings['notification_summary_number_of_events_included'] ) && $settings['notification_summary_number_of_events_included'] ) {
|
|
$settings['notification_events_included'] = true;
|
|
$settings['notification_summary_number_of_events_included'] = 10;
|
|
Notifications::set_global_notifications_setting( $settings );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 5.3.4.1
|
|
*
|
|
* Migrates notification settings
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.3.4.1
|
|
*/
|
|
public static function migrate_up_to_5341() {
|
|
self::remove_old_data();
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 5.4.0
|
|
*
|
|
* Migrates notification settings
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.4.0
|
|
*/
|
|
public static function migrate_up_to_5400() {
|
|
|
|
if ( \class_exists( '\WSAL\Entities\Custom_Notifications_Entity' ) && \method_exists( Custom_Notifications_Entity::class, 'get_upgrade_query_settings_field' ) ) {
|
|
// If one of the new columns exists there is no need to alter the table.
|
|
$column_exists = Custom_Notifications_Entity::check_column(
|
|
Custom_Notifications_Entity::get_table_name(),
|
|
'notification_settings',
|
|
'longtext'
|
|
);
|
|
|
|
if ( ! $column_exists ) {
|
|
$upgrade_sql = Custom_Notifications_Entity::get_upgrade_query_settings_field();
|
|
Custom_Notifications_Entity::get_connection()->query( $upgrade_sql );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 5.3.5.0
|
|
*
|
|
* Migrates notification settings
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.3.5
|
|
*/
|
|
public static function migrate_up_to_5350() {
|
|
self::remove_old_data();
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 5.4.2
|
|
*
|
|
* Migrates notification settings
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.4.2
|
|
*/
|
|
public static function migrate_up_to_5420() {
|
|
Settings_Helper::set_boolean_option_value( 'notification-modal-dismissed', true, false );
|
|
}
|
|
|
|
/**
|
|
* Migration for version upto 5.5.0
|
|
*
|
|
* Migrates mysql connections from the old format hostname:port to hostname and port separate fields.
|
|
*
|
|
* Note: The migration methods need to be in line with the @see WSAL\Utils\Abstract_Migration::$pad_length
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.5.0
|
|
*/
|
|
public static function migrate_up_to_5500() {
|
|
|
|
$all_connections = Connection::get_all_connections();
|
|
|
|
// Loop all connections.
|
|
foreach ( $all_connections as $connection ) {
|
|
if ( 'mysql' === $connection['type'] ) {
|
|
if ( isset( $connection['port'] ) && ! empty( $connection['port'] ) ) {
|
|
// Skip this connection if its port port is already set.
|
|
continue;
|
|
}
|
|
|
|
$parts = explode( ':', $connection['hostname'] );
|
|
$clean_hostname = $parts[0];
|
|
$get_port = isset( $parts[1] ) ? $parts[1] : '';
|
|
|
|
$new_connection = $connection;
|
|
|
|
// Add new port value.
|
|
$new_connection['port'] = ( ! empty( $get_port ) ) ? (int) $get_port : 3306;
|
|
$new_connection['hostname'] = $clean_hostname;
|
|
|
|
Connection::save_connection( $new_connection );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Migration for version 5.6.0
|
|
*
|
|
* Migrates WSAL options from wp_options (of main site) to wp_sitemeta for multisite installs only.
|
|
* Fixes the incorrect use of switch_to_blog(get_main_network_id()).
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.6.0
|
|
*/
|
|
protected static function migrate_up_to_5600() {
|
|
// Only run on multisite.
|
|
if ( ! WP_Helper::is_multisite() ) {
|
|
return;
|
|
}
|
|
|
|
global $wpdb;
|
|
|
|
// ! Get the get_main_network_id() function: the returning ID was used in WSAL <= 5.5.4 to store options in multisite installs instead of get_main_site_id() or similar.
|
|
$main_network_id = \get_main_network_id();
|
|
|
|
// Build the options table name for the main site.
|
|
if ( 1 === $main_network_id ) {
|
|
$options_table_name = $wpdb->prefix . 'options';
|
|
} else {
|
|
$options_table_name = $wpdb->prefix . $main_network_id . '_options';
|
|
}
|
|
|
|
/**
|
|
* Get all WSAL options from the old location using direct SQL and avoid helper methods during migration.
|
|
*/
|
|
$old_options = $wpdb->get_results(
|
|
$wpdb->prepare(
|
|
"SELECT option_name, option_value FROM $options_table_name WHERE option_name LIKE %s", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
|
'wsal_%'
|
|
),
|
|
ARRAY_A
|
|
);
|
|
|
|
// Migrate each option.
|
|
foreach ( $old_options as $option ) {
|
|
$option_name = $option['option_name'];
|
|
$option_value = \maybe_unserialize( $option['option_value'] );
|
|
|
|
// Skip the networkwide_tracker_cpts setting, it's already stored in the correct table.
|
|
if ( 'wsal_networkwide_tracker_cpts' === $option_name ) {
|
|
continue;
|
|
}
|
|
|
|
// Write to the new location: sitemeta.
|
|
\update_network_option( null, $option_name, $option_value );
|
|
}
|
|
|
|
// Mark migration as complete!
|
|
\update_network_option( null, 'wsal_multisite_options_migrated', true );
|
|
\update_network_option( null, 'wsal_multisite_options_migrated_date', \current_time( 'mysql' ) );
|
|
}
|
|
|
|
/**
|
|
* Migration for version 5.6.1
|
|
*
|
|
* Cleans up old survey banner option.
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.6.1
|
|
*/
|
|
protected static function migrate_up_to_5610() {
|
|
// Remove old survey option so the banner shows again under the new scheme, issue 5546.
|
|
Settings_Helper::delete_option_value( 'melapress-survey-2025' );
|
|
}
|
|
|
|
/**
|
|
* Remove some very old data from the database.
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.3.4.1
|
|
*/
|
|
public static function remove_old_data(): void {
|
|
WP_Helper::delete_global_option( 'admin-blocking-plugins-support' );
|
|
WP_Helper::delete_global_option( 'archiving-date-e' );
|
|
WP_Helper::delete_global_option( 'wsal_columns' );
|
|
WP_Helper::delete_global_option( 'filter-internal-ip' );
|
|
WP_Helper::delete_global_option( 'log-404-limit' );
|
|
WP_Helper::delete_global_option( 'log-visitor-404-limit' );
|
|
WP_Helper::delete_global_option( 'scan-file-changes' );
|
|
WP_Helper::delete_global_option( 'site_content' );
|
|
WP_Helper::delete_global_option( 'usersessions_policy_administrator' );
|
|
|
|
$connections = Connection::get_all_connections();
|
|
foreach ( $connections as $connection ) {
|
|
if ( $connection instanceof \stdClass ) {
|
|
$connection = (array) $connection;
|
|
|
|
Connection::save_connection( $connection );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Previous version of the plugin do not store username or user_id consistently, that method fixed that (in the best way possible) - if there is no user with that username 0 is stored as user_id, if user with that id does not exist anymore 'Deleted' is stored as username (check update_user_name_and_user_id method)
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 5.0.0
|
|
*/
|
|
public static function migrate_users() {
|
|
$updated_records = self::update_user_name_and_user_id( Occurrences_Entity::get_connection() );
|
|
|
|
$hooks_array = array(
|
|
'wsal_migrate_users' => array(
|
|
'time' => 'fiveminutes',
|
|
'hook' => array( __CLASS__, 'migrate_users' ),
|
|
'args' => array(),
|
|
),
|
|
);
|
|
|
|
if ( 0 === $updated_records ) {
|
|
Cron_Jobs::remove_cron_option( 'wsal_migrate_users' );
|
|
$wsal_db = null;
|
|
|
|
} else {
|
|
Cron_Jobs::store_cron_option( $hooks_array );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks and replace if empty user_id and username respectively.
|
|
*
|
|
* @param \wpdb $connection - The connection object to use.
|
|
*
|
|
* @return integer
|
|
*
|
|
* @since 5.0.0
|
|
*/
|
|
private static function update_user_name_and_user_id( $connection = null ): int {
|
|
|
|
$results = array();
|
|
|
|
$local_user_cache = array();
|
|
|
|
$sql = 'SELECT * FROM ' . Occurrences_Entity::get_table_name( $connection ) . " WHERE 1 AND username IS NOT NULL AND username NOT IN ('Plugin', 'Plugins', 'Website Visitor', 'System' ) AND user_id IS NULL ORDER BY created_on DESC LIMIT 100";
|
|
|
|
$records = Occurrences_Entity::load_query( $sql, $connection );
|
|
|
|
$results['no_user_ids'] = \count( $records );
|
|
|
|
if ( ! empty( $records ) ) {
|
|
foreach ( $records as $record ) {
|
|
if ( ! isset( $local_user_cache[ $record['username'] ] ) ) {
|
|
$user = \get_user_by( 'login', $record['username'] );
|
|
if ( \is_a( $user, '\WP_User' ) ) {
|
|
$local_user_cache[ $record['username'] ] = $user->ID;
|
|
} else {
|
|
// Try to extract the user data from the meta (probably user is not around anymore).
|
|
$meta_result = Metadata_Entity::load_by_name_and_occurrence_id( 'UserData', $record['id'] );
|
|
if ( isset( $meta_result['value'] ) ) {
|
|
$user = \maybe_unserialize( $meta_result['value'] );
|
|
if ( \is_array( $user ) ) {
|
|
$local_user_cache[ $record['username'] ] = $user['ID'];
|
|
}
|
|
if ( \is_object( $user ) ) {
|
|
$local_user_cache[ $record['username'] ] = $user->ID;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ( isset( $local_user_cache[ $record['username'] ] ) ) {
|
|
$record['user_id'] = $local_user_cache[ $record['username'] ];
|
|
$connection->replace(
|
|
Occurrences_Entity::get_table_name( $connection ),
|
|
$record,
|
|
array( '%d', '%d', '%d', '%f', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%s', '%s', '%d' )
|
|
);
|
|
} else {
|
|
$record['user_id'] = 0;
|
|
$connection->replace(
|
|
Occurrences_Entity::get_table_name( $connection ),
|
|
$record,
|
|
array( '%d', '%d', '%d', '%f', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%s', '%s', '%d' )
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
$sql = 'SELECT * FROM ' . Occurrences_Entity::get_table_name( $connection ) . ' WHERE 1 AND username IS NULL AND user_id IS NOT NULL ORDER BY created_on DESC LIMIT 100';
|
|
|
|
$records = Occurrences_Entity::load_query( $sql, $connection );
|
|
|
|
$results['no_user_names'] = \count( $records );
|
|
|
|
$local_user_cache = \array_flip( $local_user_cache );
|
|
|
|
if ( ! empty( $records ) ) {
|
|
foreach ( $records as $record ) {
|
|
if ( ! isset( $local_user_cache[ $record['user_id'] ] ) ) {
|
|
$user = \get_user_by( 'ID', $record['user_id'] );
|
|
if ( \is_a( $user, '\WP_User' ) ) {
|
|
$local_user_cache[ $record['user_id'] ] = $user->user_login;
|
|
} else {
|
|
// Try to extract the user data from the meta (probably user is not around anymore).
|
|
$meta_result = Metadata_Entity::load_by_name_and_occurrence_id( 'UserData', $record['id'] );
|
|
if ( isset( $meta_result['value'] ) ) {
|
|
$user = \maybe_unserialize( $meta_result['value'] );
|
|
if ( \is_array( $user ) ) {
|
|
$local_user_cache[ $record['user_id'] ] = $user['user_login'];
|
|
}
|
|
if ( \is_object( $user ) ) {
|
|
$local_user_cache[ $record['user_id'] ] = $user->user_login;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ( isset( $local_user_cache[ $record['user_id'] ] ) ) {
|
|
$record['username'] = $local_user_cache[ $record['user_id'] ];
|
|
$connection->replace(
|
|
Occurrences_Entity::get_table_name( $connection ),
|
|
$record,
|
|
array( '%d', '%d', '%d', '%f', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%s', '%s', '%d' )
|
|
);
|
|
} else {
|
|
$record['username'] = 'Deleted';
|
|
$connection->replace(
|
|
Occurrences_Entity::get_table_name( $connection ),
|
|
$record,
|
|
array( '%d', '%d', '%d', '%f', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%s', '%s', '%d' )
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
return ( (int) $results['no_user_ids'] + (int) $results['no_user_names'] );
|
|
}
|
|
|
|
/**
|
|
* Extracts all of the periodic reports
|
|
*
|
|
* @return array
|
|
*
|
|
* @since 5.0.0
|
|
*/
|
|
private static function get_all_periodic_reports(): array {
|
|
|
|
$result = array();
|
|
$reports = Settings_Helper::get_notifications_setting( WSAL_PREFIX . 'periodic-report-' );
|
|
if ( ! empty( $reports ) ) {
|
|
foreach ( $reports as $report ) {
|
|
$result[ $report->option_name ] = self::patch_legacy_report_object( unserialize( $report->option_value ) ); // @codingStandardsIgnoreLine
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Takes care of legacy reporting objects and collects their properties
|
|
*
|
|
* @param mixed $report - The report to be checked and its properties patched.
|
|
*
|
|
* @return mixed
|
|
*
|
|
* @since 5.0.0
|
|
*/
|
|
private static function patch_legacy_report_object( $report ) {
|
|
if ( property_exists( $report, 'viewState' ) && property_exists( $report, 'triggers' ) ) {
|
|
if ( in_array( 'codes', $report->viewState, true ) ) { // phpcs:ignore
|
|
// Specific event IDs were selected.
|
|
$index = array_search( 'codes', $report->viewState, true ); // phpcs:ignore
|
|
$codes = $report->triggers[ $index ]['alert_id'];
|
|
$report->alert_ids = $codes;
|
|
} elseif ( count( $report->viewState ) < 20 ) { // phpcs:ignore
|
|
// Specific groups were selected.
|
|
$report->alert_ids = $report->viewState; // phpcs:ignore
|
|
}
|
|
}
|
|
|
|
return $report;
|
|
}
|
|
}
|
|
}
|