$default ) { $defs[ $name ] = $default['name']; } if ( isset( $settings['severity_colors'] ) && isset( $settings['severity_show'] ) ) { $settings['severities'] = \array_merge_recursive( $settings['severity_colors'], $settings['severity_show'], $defs ); unset( $settings['severity_colors'] ); unset( $settings['severity_show'] ); } if ( isset( $settings['severity_colors'] ) ) { $settings['severities'] = \array_merge_recursive( $settings['severity_colors'], $defs ); unset( $settings['severity_colors'] ); } if ( isset( $settings['severity_show'] ) ) { $settings['severities'] = \array_merge_recursive( $settings['severity_show'], $defs ); unset( $settings['severity_show'] ); } Settings::store_options( $settings ); Settings::set_current_options( $settings ); } /** * Migrates the plugin up-to version 1.8.2 * * @return void * * @since 1.8.2 */ public static function migrate_up_to_182() { $settings = Settings::get_current_options(); if ( ! isset( $settings['live_notifications_admin_bar'] ) ) { $settings['live_notifications_admin_bar'] = true; } Settings::store_options( $settings ); Settings::set_current_options( $settings ); } /** * Migrates the plugin up-to version 1.8.4 * * @return void * * @since 1.8.4 */ public static function migrate_up_to_184() { $settings = Settings::get_current_options(); if ( ! isset( $settings['environment_type_admin_bar'] ) ) { $settings['environment_type_admin_bar'] = true; } $settings['severities']['user'] = array( 'name' => __( 'User', '0-day-analytics' ), 'color' => '#0d4c24', 'display' => true, ); Settings::store_options( $settings ); Settings::set_current_options( $settings ); } /** * Migrates the plugin up-to version 1.9.6 * * @return void * * @since 1.9.6 */ public static function migrate_up_to_196() { $settings = Settings::get_current_options(); if ( isset( $settings['severities']['user'] ) && isset( $settings['severities']['user']['color'] ) && '#0d4c24' === $settings['severities']['user']['color'] ) { $settings['severities']['user']['color'] = '#85b395'; } if ( isset( $settings['severities']['info'] ) && isset( $settings['severities']['info']['color'] ) && '#0000ff' === $settings['severities']['info']['color'] ) { $settings['severities']['info']['color'] = '#aeaeec'; } if ( isset( $settings['severities']['fatal'] ) && isset( $settings['severities']['fatal']['color'] ) && '#b92a2a' === $settings['severities']['fatal']['color'] ) { $settings['severities']['fatal']['color'] = '#f09595'; } if ( isset( $settings['severities']['parse'] ) && isset( $settings['severities']['parse']['color'] ) && '#b9762a' === $settings['severities']['parse']['color'] ) { $settings['severities']['parse']['color'] = '#e3bb8d'; } Settings::store_options( $settings ); Settings::set_current_options( $settings ); } /** * Migrates the plugin up-to version 2.8.1 * * @return void * * @since 2.8.1 */ public static function migrate_up_to_281() { $settings = Settings::get_current_options(); $defaults = Settings::get_default_options()['severities']; foreach ( $defaults as $name => $default ) { if ( ! isset( $settings['severities'][ $name ] ) ) { $settings['severities'][ $name ] = $default; } } Settings::store_options( $settings ); Settings::set_current_options( $settings ); } /** * Migrates the plugin up-to version 3.0.1 * * @return void * * @since 3.0.1 */ public static function migrate_up_to_301() { if ( \class_exists( '\ADVAN\Entities\WP_Mail_Entity' ) ) { if ( Common_Table::check_table_exists( WP_Mail_Entity::get_table_name() ) && ! Common_Table::check_column( 'email_from', 'text', WP_Mail_Entity::get_table_name() ) ) { WP_Mail_Entity::alter_table_301(); } } } /** * Migrates the plugin up-to version 3.6.3 * * @return void * * @since 3.6.3 */ public static function migrate_up_to_363() { if ( \class_exists( '\ADVAN\Entities\WP_Mail_Entity' ) ) { if ( Common_Table::check_table_exists( WP_Mail_Entity::get_table_name() ) && ! Common_Table::check_column( 'blog_id', 'int', WP_Mail_Entity::get_table_name() ) ) { WP_Mail_Entity::alter_table_363(); } } } /** * Migrates the plugin up-to version 3.9.2 * * @return void * * @since 3.9.2 */ public static function migrate_up_to_392() { if ( \class_exists( '\ADVAN\Entities\Requests_Log_Entity' ) ) { if ( Common_Table::check_table_exists( Requests_Log_Entity::get_table_name() ) && ! Common_Table::check_column( 'plugin', 'varchar(200)', Requests_Log_Entity::get_table_name() ) ) { Requests_Log_Entity::alter_table_393(); } if ( Common_Table::check_table_exists( Requests_Log_Entity::get_table_name() ) && ! Common_Table::check_column( 'domain', 'varchar(255)', Requests_Log_Entity::get_table_name() ) ) { Requests_Log_Entity::alter_table_3931(); } } } /** * Migrates the plugin up-to version 4.2.0 (adds plugin_slug column to mail log). * * @return void * * @since 4.2.0 */ public static function migrate_up_to_420() { if ( \class_exists( '\\ADVAN\\Entities\\WP_Mail_Entity' ) ) { if ( Common_Table::check_table_exists( WP_Mail_Entity::get_table_name() ) && ! Common_Table::check_column( 'plugin_slug', 'varchar(255)', WP_Mail_Entity::get_table_name() ) ) { \ADVAN\Entities\WP_Mail_Entity::alter_table_411(); } } } /** * Migrates the plugin up-to version 4.3.0 * * Removes the now-redundant `version` key that used to be stored inside the * main settings array. This key duplicated the separately stored plugin * version and is no longer necessary. * * @return void * * @since 4.3.0 */ public static function migrate_up_to_430() { $settings = Settings::get_current_options(); if ( isset( $settings['version'] ) ) { unset( $settings['version'] ); Settings::store_options( $settings ); Settings::set_current_options( $settings ); } } /** * Migrates the plugin up-to version 4.6.0 (adds request_id column to hooks capture). * * @return void * * @since 4.6.0 */ public static function migrate_up_to_460() { if ( \class_exists( '\\ADVAN\\Entities\\Hooks_Capture_Entity' ) ) { if ( Common_Table::check_table_exists( \ADVAN\Entities\Hooks_Capture_Entity::get_table_name() ) && ! Common_Table::check_column( 'request_id', 'varchar(50)', \ADVAN\Entities\Hooks_Capture_Entity::get_table_name() ) ) { \ADVAN\Entities\Hooks_Capture_Entity::alter_table_460(); } } } /** * Migrates the plugin up-to version 4.7.0 (adds performance indexes to fatals table). * * @return void * * @since 4.7.0 */ public static function migrate_up_to_470() { if ( \class_exists( '\\ADVAN\\Entities\\WP_Fatals_Entity' ) ) { if ( Common_Table::check_table_exists( WP_Fatals_Entity::get_table_name() ) ) { WP_Fatals_Entity::alter_table_470(); } } } /** * Migrates the plugin up-to version 4.8.0 (adds enhanced mail tracking columns). * Adds columns for CC/BCC recipients, Reply-To, email sizes, attachment metadata, * delivery time, email categorization, and resend capability. * * @return void * * @since 4.8.0 */ public static function migrate_up_to_480() { if ( \class_exists( '\\ADVAN\\Entities\\WP_Mail_Entity' ) ) { if ( Common_Table::check_table_exists( WP_Mail_Entity::get_table_name() ) ) { WP_Mail_Entity::alter_table_471(); } } if ( \class_exists( '\\ADVAN\\Entities\\Requests_Log_Entity' ) ) { if ( Common_Table::check_table_exists( Requests_Log_Entity::get_table_name() ) ) { Requests_Log_Entity::alter_table_480(); } } if ( \class_exists( '\\ADVAN\\Entities\\WP_Fatals_Entity' ) ) { if ( Common_Table::check_table_exists( WP_Fatals_Entity::get_table_name() ) ) { WP_Fatals_Entity::alter_table_470(); } } } /** * Migrates the plugin up-to version 5.1.0 (adds code_hmac column to snippets). * Adds the HMAC integrity column and back-fills values for all existing snippets. * Also rebuilds the hooks cache file and stores its integrity hash for users * upgrading from older versions that had hooks monitoring enabled. * * @return void * * @since 5.1.0 */ public static function migrate_up_to_510() { if ( \class_exists( '\\ADVAN\\Entities\\Snippet_Entity' ) ) { if ( Common_Table::check_table_exists( Snippet_Entity::get_table_name() ) && ! Common_Table::check_column( 'code_hmac', 'varchar(64)', Snippet_Entity::get_table_name() ) ) { Snippet_Entity::alter_table_510(); } elseif ( Common_Table::check_table_exists( Snippet_Entity::get_table_name() ) ) { // Column already exists but rows may still need back-filling. Snippet_Entity::backfill_code_hmac(); } } } /** * Migrates the plugin up-to version 5.2.0 (adds direction column to requests log). * Adds a direction column to distinguish internal vs external requests and * back-fills existing rows based on domain comparison with the site domain. * Sets the anlytics module to enabled by default since the new direction data will enable more insightful analytics out of the box. * Also adds the auth_cookie_bad_session_token hook to hooks management and * clears the hooks cache so it gets picked up immediately. * * @return void * * @since 5.2.0 */ public static function migrate_up_to_520() { $settings = Settings::get_current_options(); $settings['traffic_analytics_module_enabled'] = true; Settings::store_options( $settings ); Settings::set_current_options( $settings ); if ( \class_exists( '\\ADVAN\\Entities\\Requests_Log_Entity' ) ) { if ( Common_Table::check_table_exists( Requests_Log_Entity::get_table_name() ) ) { // Trim to newest 10K rows before altering to avoid long-running migrations. self::trim_requests_log_table(); if ( ! Common_Table::check_column( 'direction', 'varchar(10)', Requests_Log_Entity::get_table_name() ) ) { Requests_Log_Entity::alter_table_520(); } // Backfill direction for existing rows that have an empty direction. Requests_Log_Entity::backfill_direction(); } } // Add auth_cookie_bad_session_token hook for session expiry detection. self::add_session_token_hook(); } /** * Trim the requests log table to the newest 10,000 rows if it exceeds that count. * * This prevents ALTER TABLE and backfill operations from running for an * excessively long time on sites with hundreds of thousands of rows. * * @return void * * @since 5.2.0 */ private static function trim_requests_log_table() { $table_name = Requests_Log_Entity::get_table_name(); $count = Requests_Log_Entity::count(); if ( $count <= 10000 ) { return; } // Find the ID threshold: keep rows with id >= this value. $cutoff_id = (int) Requests_Log_Entity::get_var( "SELECT id FROM `{$table_name}` ORDER BY id DESC LIMIT 1 OFFSET 9999" // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared ); if ( $cutoff_id > 0 ) { Requests_Log_Entity::delete_query( "DELETE FROM `{$table_name}` WHERE id < %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared array( $cutoff_id ) ); } } /** * Add auth_cookie_bad_session_token hook to hooks management if not present, * and clear the hooks cache so it becomes active immediately. * * @return void * * @since 5.2.0 */ private static function add_session_token_hook() { if ( ! \class_exists( '\\ADVAN\\Entities\\Hooks_Management_Entity' ) ) { return; } if ( ! Common_Table::check_table_exists( \ADVAN\Entities\Hooks_Management_Entity::get_table_name() ) ) { return; } // Check if it already exists. $exists = \ADVAN\Entities\Hooks_Management_Entity::count( 'hook_name = %s AND hook_type = %s', array( 'auth_cookie_bad_session_token', 'action' ) ); if ( ! $exists ) { \ADVAN\Entities\Hooks_Management_Entity::insert( array( 'hook_name' => 'auth_cookie_bad_session_token', 'hook_type' => 'action', 'priority' => 10, 'enabled' => 1, 'capture_args' => 1, 'capture_output' => 0, 'hook_label' => __( 'Auth cookie bad session token', '0-day-analytics' ), 'description' => __( 'Fires when an auth cookie has a bad session token (session expired)', '0-day-analytics' ), 'category' => 'auth', 'hook_parameters' => \wp_json_encode( array( array( 'name' => 'cookie_elements', 'type' => 'array', 'extraction_code' => '', ), ) ), 'date_added' => microtime( true ), 'date_modified' => microtime( true ), ) ); } // Clear the hooks cache so the new hook is picked up. if ( \class_exists( '\\ADVAN\\Controllers\\Hooks_Capture' ) ) { \ADVAN\Controllers\Hooks_Capture::clear_cache(); } } } }