Files
argus-wp-defence/includes/class-argus-plugin.php
T
ARGUSandClaude Sonnet 5 35efd3e485 ARGUS WordPress Defence 7.23.0
Real changes since 1.0.0, all live-verified before this release:

- Firewall: rule corpus expanded 19 -> 43 rules, real OWASP-CRS-equivalent
  coverage (XXE, SSRF, session fixation, Log4Shell/JNDI, scanner-tool
  detection, deeper SQL injection/XSS/PHP-injection).
- Fixed a real bug: a quarantined file's severity badge and its content
  analysis score could disagree with no explanation (e.g. a benign file
  showing CRITICAL next to Score 0); both are now derived consistently
  and shown together.
- ARGUS now always keeps itself updated, and can optionally do the same
  for every other installed plugin and theme (Settings, on by default) --
  uses WordPress's own native update system, nothing custom.
- Global Threat Intelligence is now opt-in, not automatic -- a single
  click on its own page, with an honest, specific description of exactly
  what's shared (an IP address, a reason code, a confidence score, a
  country). Previously connected automatically on activation.
- New first-run Welcome screen after activation: confirms what's already
  protecting the site, and surfaces the few real optional choices in one
  place.
- Dashboard: running version now visible in the header; new "IPs
  Tracked" and "ANIS Protections" metrics.
- Full WordPress.org Plugin Directory readiness audit performed against
  this codebase. Two real compliance issues found and fixed (see above:
  Global Threat Intelligence's default, and the self-update mechanism,
  which is excluded from this build entirely -- WordPress.org prohibits
  a plugin from using any update channel other than its own, even an
  inert one). This release is still self-distributed, not a WordPress.org
  submission -- that remains a future step.

Verified before publishing: this exact ZIP was installed, activated (14
admin pages loaded clean, zero PHP errors/warnings), and uninstalled
(zero leftover database tables or options) in a fresh, disposable
WordPress + MySQL environment.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-09 19:08:02 +00:00

143 lines
4.9 KiB
PHP

<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Argus_Plugin {
protected static $instance = null;
public static function instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
public function boot() {
Argus_DB::maybe_upgrade();
Argus_MU_Installer::ensure_current();
// Premium-build-only (see includes/class-argus-license.php's own
// header) -- covers sites that were already active before this
// existed, same idempotent-ensure pattern as Argus_MU_Installer above.
if ( class_exists( 'Argus_License' ) ) {
Argus_License::ensure_trial_started();
}
add_filter( 'cron_schedules', array( __CLASS__, 'register_cron_schedules' ) ); // phpcs:ignore WordPress.WP.CronInterval
Argus_Login_Guard::init();
Argus_API_Guard::init();
Argus_GeoIP_RIR::init();
Argus_Static_Cache::init();
Argus_Auto_Update::init();
Argus_Upload_Guard::init();
Argus_ANIS_Client::init();
Argus_Vuln_Intel::init();
add_action( 'init', array( 'Argus_WAF', 'inspect_and_enforce' ), 0 );
add_action( 'argus_wpd_hourly', array( __CLASS__, 'run_hourly' ) );
add_action( 'argus_wpd_daily', array( __CLASS__, 'run_daily' ) );
add_action( 'argus_wpd_five_minutes', array( 'Argus_ANIS_Client', 'maybe_retry_sync' ) );
add_action( 'argus_wpd_five_minutes', array( 'Argus_Vuln_Intel', 'maybe_retry' ) );
// Argus_Update_Client is deliberately excluded from the WordPress.org-
// distributed build (bin/build-release.sh) -- a plugin hosted on
// WordPress.org must rely solely on WordPress.org's own update
// channel, never a self-update-from-external-manifest mechanism, even
// an inert-by-default one. class_exists() guards it everywhere it's
// referenced so the rest of the plugin degrades cleanly when the file
// is absent, rather than the packaging step needing to also edit code.
if ( class_exists( 'Argus_Update_Client' ) ) {
add_action( 'argus_wpd_five_minutes', array( 'Argus_Update_Client', 'maybe_check' ) );
}
if ( class_exists( 'Argus_Integrity' ) ) {
add_action( 'upgrader_process_complete', array( 'Argus_Integrity', 'on_upgrader_complete' ), 10, 2 );
}
if ( is_admin() ) {
require_once ARGUS_WPD_DIR . 'admin/class-argus-admin.php';
Argus_Admin::init();
}
}
public static function run_hourly() {
Argus_Ban_Engine::sweep_expired();
Argus_Events::prune();
Argus_Policy_Engine::prune();
Argus_Login_Guard::prune_attempts();
$scan_started = time();
$integrity_ran = class_exists( 'Argus_Integrity' ) && Argus_Settings::get( 'integrity_scan_enabled', true );
$malware_ran = class_exists( 'Argus_Malware_Scanner' ) && Argus_Settings::get( 'malware_scan_enabled', true );
if ( $integrity_ran ) {
Argus_Integrity::incremental_scan();
}
if ( $malware_ran ) {
Argus_Malware_Scanner::incremental_scan();
}
if ( ( $integrity_ran || $malware_ran ) && class_exists( 'Argus_Scan_History' ) ) {
Argus_Scan_History::record( Argus_Scan_History::TYPE_SCHEDULED_INCREMENTAL, $scan_started );
}
if ( class_exists( 'Argus_Correlation' ) ) {
Argus_Correlation::run();
}
if ( class_exists( 'Argus_REST_Inventory' ) ) {
Argus_REST_Inventory::snapshot();
}
if ( class_exists( 'Argus_AJAX_Inventory' ) ) {
Argus_AJAX_Inventory::snapshot();
}
if ( class_exists( 'Argus_Cache_Log' ) ) {
Argus_Cache_Log::rollup_and_prune();
}
if ( class_exists( 'Argus_Cache_Warmer' ) && Argus_Settings::get( 'cache_warming_enabled', false ) ) {
Argus_Cache_Warmer::process_queue();
}
if ( class_exists( 'Argus_ANIS_Client' ) && Argus_ANIS_Client::is_connected() ) {
Argus_ANIS_Client::scheduled_sync();
}
if ( class_exists( 'Argus_Vuln_Intel' ) && Argus_Settings::get( 'vuln_intel_enabled', true ) ) {
Argus_Vuln_Intel::scheduled_check();
}
if ( class_exists( 'Argus_Backup' ) ) {
Argus_Backup::maybe_run_scheduled();
}
}
public static function register_cron_schedules( $schedules ) {
$schedules['argus_wpd_five_minutes'] = array(
'interval' => 5 * MINUTE_IN_SECONDS,
'display' => __( 'Every 5 Minutes (ARGUS Defence)', 'argus-wordpress-defence' ),
);
return $schedules;
}
public static function run_daily() {
if ( class_exists( 'Argus_Integrity' ) ) {
$scan_started = time();
Argus_Integrity::full_scan();
if ( class_exists( 'Argus_Scan_History' ) ) {
Argus_Scan_History::record( Argus_Scan_History::TYPE_SCHEDULED_FULL, $scan_started, Argus_Integrity::scan_status()['files_scanned'] );
}
}
if ( class_exists( 'Argus_GeoIP_RIR' ) && Argus_Settings::get( 'geoip_rir_enabled', true ) ) {
Argus_GeoIP_RIR::run_daily_refresh();
}
if ( class_exists( 'Argus_Cache_Discovery' ) && Argus_Settings::get( 'cache_discovery_enabled', true ) && Argus_Settings::get( 'static_cache_enabled', false ) ) {
Argus_Cache_Discovery::run_discovery();
}
if ( class_exists( 'Argus_ANIS_Client' ) && Argus_ANIS_Client::is_enabled() ) {
Argus_ANIS_Client::register();
}
}
}