base_prefix ) ? $wpdb->base_prefix : $wpdb->prefix; $table_name = $prefix . APWPM_TABLE_LOGS; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE {$table_name} ( id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, blog_id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0, user_id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0, user_login VARCHAR(60) NOT NULL DEFAULT '', user_role VARCHAR(60) NOT NULL DEFAULT '', action_type VARCHAR(60) NOT NULL DEFAULT '', object_type VARCHAR(60) NOT NULL DEFAULT '', object_id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0, object_title VARCHAR(255) NOT NULL DEFAULT '', description TEXT NULL, context LONGTEXT NULL, row_hash CHAR(64) NOT NULL DEFAULT '', prev_hash CHAR(64) NOT NULL DEFAULT '', severity VARCHAR(20) NOT NULL DEFAULT 'info', status VARCHAR(20) NOT NULL DEFAULT 'open', assignee_id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0, is_anomaly TINYINT(1) NOT NULL DEFAULT 0, rolled_back TINYINT(1) NOT NULL DEFAULT 0, rollback_of BIGINT(20) UNSIGNED NOT NULL DEFAULT 0, ip_address VARCHAR(45) NOT NULL DEFAULT '', country VARCHAR(8) NOT NULL DEFAULT '', city VARCHAR(80) NOT NULL DEFAULT '', user_agent VARCHAR(255) NOT NULL DEFAULT '', session_id VARCHAR(64) NOT NULL DEFAULT '', created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY blog_id (blog_id), KEY user_id (user_id), KEY action_type (action_type), KEY object_type (object_type), KEY object_id (object_id), KEY severity (severity), KEY status (status), KEY assignee (assignee_id), KEY country (country), KEY is_anomaly (is_anomaly), KEY rollback_of (rollback_of), KEY session_id (session_id), KEY created_at (created_at), FULLTEXT KEY ft_description (description) ) {$charset_collate};"; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta( $sql ); $comments_table = $prefix . 'apwpm_comments'; $sql = "CREATE TABLE {$comments_table} ( id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, log_id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0, user_id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0, user_login VARCHAR(60) NOT NULL DEFAULT '', body TEXT NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY log_id (log_id), KEY user_id (user_id) ) {$charset_collate};"; dbDelta( $sql ); $views_table = $prefix . 'apwpm_views'; $sql = "CREATE TABLE {$views_table} ( id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, user_id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0, name VARCHAR(120) NOT NULL DEFAULT '', filters LONGTEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY user_id (user_id) ) {$charset_collate};"; dbDelta( $sql ); $defaults = array( 'retention_days' => 90, 'log_logins' => 1, 'log_post_changes' => 1, 'log_plugin_changes' => 1, 'log_theme_changes' => 1, 'log_user_changes' => 1, 'log_option_changes' => 1, 'break_detection' => 1, 'error_threshold' => 5, 'error_window_min' => 10, 'notify_email' => get_option( 'admin_email' ), 'enable_alerts' => 1, 'enable_insights' => 1, 'enable_rollback' => 1, 'enable_error_log' => 0, 'enable_async' => 0, 'enable_hashchain' => 1, 'enable_sudo' => 1, 'enable_file_monitor' => 0, 'enable_ip_throttle' => 1, 'ip_throttle_limit' => 5, 'ip_throttle_window' => 5, 'enable_pii_redact' => 0, 'enable_immutable' => 0, 'enable_geo' => 0, 'enable_woocommerce' => 1, 'enable_forms' => 1, 'enable_seo' => 1, 'enable_webhooks' => 0, 'webhook_slack' => '', 'webhook_discord' => '', 'webhook_teams' => '', 'webhook_generic' => '', 'webhook_secret' => '', 'webhook_min_sev' => 'warning', 'enable_digest' => 0, 'digest_freq' => 'weekly', 'enable_mention_email' => 1, 'enable_live' => 1, 'retention_per_sev' => array(), ); if ( false === get_option( 'apwpm_settings' ) ) { add_option( 'apwpm_settings', $defaults ); } else { $current = (array) get_option( 'apwpm_settings', array() ); update_option( 'apwpm_settings', array_merge( $defaults, $current ) ); } if ( class_exists( 'APWPM_Migrator' ) ) { APWPM_Migrator::migrate(); } else { update_option( 'apwpm_db_version', APWPM_DB_VERSION ); } if ( ! wp_next_scheduled( 'apwpm_daily_cleanup' ) ) { wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', 'apwpm_daily_cleanup' ); } if ( ! wp_next_scheduled( 'apwpm_insights_scan' ) ) { wp_schedule_event( time() + 15 * MINUTE_IN_SECONDS, 'hourly', 'apwpm_insights_scan' ); } // Log the activation itself. if ( class_exists( 'APWPM_Logger' ) ) { APWPM_Logger::log( array( 'action_type' => 'plugin_activated', 'object_type' => 'plugin', 'object_title' => 'ActivityPilot for WP', 'description' => __( 'Plugin activated.', 'activitypilot' ), 'severity' => 'info', ) ); } } }