wpvulnerability/class-wpvulnerability-config-cli.php
2026-06-02 13:41:43 +00:00

284 lines
9.2 KiB
PHP

<?php
/**
* WP-CLI configuration commands for WPVulnerability.
*
* Provides commands to configure WPVulnerability behaviour.
*
* @package WPVulnerability
*/
defined( 'ABSPATH' ) || exit;
if ( defined( 'WP_CLI' ) && WP_CLI ) { // @phpstan-ignore booleanAnd.rightAlwaysFalse (WP_CLI is false in bootstrap but true at runtime)
/**
* WPVulnerability configuration commands.
*/
class WPVulnerability_Config_CLI extends WP_CLI_Command {
/**
* Abort with an error if the current WordPress user lacks admin capabilities.
*
* All config commands modify plugin options and therefore require the same
* privilege as the admin settings page (manage_options / manage_network_options).
* Commands must be run with --user=<admin_login> when no privileged WordPress
* user is loaded in the current WP-CLI session.
*
* @since 5.0.0
* @return void
*/
private function require_admin() {
$capability = is_multisite() ? 'manage_network_options' : 'manage_options';
if ( ! current_user_can( $capability ) ) {
\WP_CLI::error(
__( 'This command requires a WordPress administrator. Run with --user=<admin_login>.', 'wpvulnerability' )
);
}
}
/**
* Hide a component from analysis output.
*
* ## OPTIONS
*
* <component>
* : Component to hide. Valid options: core, plugins, themes, php, apache, nginx, mariadb, mysql, imagemagick, curl, memcached, redis, sqlite.
*
* [<status>]
* : Set to "off" to show the component again. Defaults to "on".
*
* ## EXAMPLES
*
* wp wpvulnerability config hide core
* wp wpvulnerability config hide plugins off
*
* @when after_wp_load
*
* @param array<int, string> $args Positional arguments.
* @param array<string, mixed> $assoc_args Associative arguments.
* @return void
*/
public function hide( $args, $assoc_args ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
$this->require_admin();
if ( ! isset( $args[0] ) ) {
\WP_CLI::error( 'Missing component.' );
}
$component = strtolower( (string) $args[0] );
$valid = array( 'core', 'plugins', 'themes', 'php', 'apache', 'nginx', 'mariadb', 'mysql', 'imagemagick', 'curl', 'memcached', 'redis', 'sqlite' );
if ( ! in_array( $component, $valid, true ) ) {
\WP_CLI::error( "'$component' is not a valid component.\nAvailable components: " . implode( ', ', $valid ) );
}
$status = isset( $args[1] ) ? strtolower( (string) $args[1] ) : 'on';
$value = in_array( $status, array( '0', 'off', 'false' ), true ) ? 0 : 1;
$option_raw = is_multisite() ? get_site_option( 'wpvulnerability-analyze', array() ) : get_option( 'wpvulnerability-analyze', array() );
$option = is_array( $option_raw ) ? $option_raw : array();
$option[ $component ] = $value;
if ( is_multisite() ) {
update_site_option( 'wpvulnerability-analyze', $option );
} else {
update_option( 'wpvulnerability-analyze', $option );
}
$message = $value ? 'now hidden' : 'no longer hidden';
\WP_CLI::success( sprintf( "Component '%s' is %s.", $component, $message ) );
}
/**
* Configure notification email addresses.
*
* ## OPTIONS
*
* <email>
* : Comma-separated list of email addresses.
*
* ## EXAMPLES
*
* wp wpvulnerability config email example@example.com
* wp wpvulnerability config email "one@example.com,two@example.com"
*
* @when after_wp_load
*
* @param array<int, string> $args Positional arguments.
* @param array<string, mixed> $assoc_args Associative arguments.
* @return void
*/
public function email( $args, $assoc_args ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
$this->require_admin();
if ( ! isset( $args[0] ) ) {
\WP_CLI::error( 'Missing email address.' );
}
$emails_raw = explode( ',', (string) $args[0] );
$sanitized_emails = array();
foreach ( $emails_raw as $email ) {
$email = sanitize_email( trim( (string) $email ) );
if ( ! is_email( $email ) ) {
\WP_CLI::error( sprintf( "'%s' is not a valid email address.", $email ) );
}
$sanitized_emails[] = $email;
}
$option_raw = is_multisite() ? get_site_option( 'wpvulnerability-config', array() ) : get_option( 'wpvulnerability-config', array() );
$option = is_array( $option_raw ) ? $option_raw : array();
$option['emails'] = implode( ',', $sanitized_emails );
if ( is_multisite() ) {
update_site_option( 'wpvulnerability-config', $option );
} else {
update_option( 'wpvulnerability-config', $option );
}
\WP_CLI::success( sprintf( "Notification email(s) set to '%s'.", $option['emails'] ) );
}
/**
* Configure cache expiration in hours.
*
* ## OPTIONS
*
* <hours>
* : Cache duration in hours. Valid options: 1, 6, 12, 24.
*
* ## EXAMPLES
*
* wp wpvulnerability config cache 6
*
* @when after_wp_load
*
* @param array<int, string> $args Positional arguments.
* @param array<string, mixed> $assoc_args Associative arguments.
* @return void
*/
public function cache( $args, $assoc_args ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
$this->require_admin();
if ( ! isset( $args[0] ) ) {
\WP_CLI::error( 'Missing cache value.' );
}
$cache = (int) $args[0];
$valid = array( 1, 6, 12, 24 );
if ( ! in_array( $cache, $valid, true ) ) {
\WP_CLI::error( sprintf( "'%s' is not a valid cache value." . PHP_EOL . 'Available values: %s', $cache, implode( ',', $valid ) ) );
}
$option_raw = is_multisite() ? get_site_option( 'wpvulnerability-config', array() ) : get_option( 'wpvulnerability-config', array() );
$option = is_array( $option_raw ) ? $option_raw : array();
$option['cache'] = $cache;
if ( is_multisite() ) {
update_site_option( 'wpvulnerability-config', $option );
} else {
update_option( 'wpvulnerability-config', $option );
}
\WP_CLI::success( sprintf( 'Cache expiration set to %d hour(s).', $cache ) );
}
/**
* Configure log retention in days.
*
* ## OPTIONS
*
* <days>
* : Number of days to retain logs. Valid options: 0, 1, 7, 14, 28. Use 0 to disable retention.
*
* ## EXAMPLES
*
* wp wpvulnerability config log-retention 14
*
* @when after_wp_load
*
* @param array<int, string> $args Positional arguments.
* @param array<string, mixed> $assoc_args Associative arguments.
* @return void
*/
public function log_retention( $args, $assoc_args ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
$this->require_admin();
if ( ! isset( $args[0] ) ) {
\WP_CLI::error( 'Missing log retention value.' );
}
$retention = (int) $args[0];
$valid = wpvulnerability_get_log_retention_values();
if ( ! in_array( $retention, $valid, true ) ) {
\WP_CLI::error( sprintf( "'%s' is not a valid log retention value." . PHP_EOL . 'Available values: %s', $retention, implode( ', ', $valid ) ) );
}
$option_raw = is_multisite() ? get_site_option( 'wpvulnerability-config', array() ) : get_option( 'wpvulnerability-config', array() );
$option = is_array( $option_raw ) ? $option_raw : array();
$option['log_retention'] = $retention;
if ( is_multisite() ) {
update_site_option( 'wpvulnerability-config', $option );
} else {
update_option( 'wpvulnerability-config', $option );
}
if ( 0 === $retention ) {
\WP_CLI::success( 'Log retention disabled.' );
return;
}
\WP_CLI::success( sprintf( 'Log retention set to %d day(s).', $retention ) );
}
/**
* Configure notification period.
*
* ## OPTIONS
*
* <period>
* : Notification period. Valid options: daily, weekly, never.
*
* ## EXAMPLES
*
* wp wpvulnerability config period weekly
*
* @when after_wp_load
*
* @param array<int, string> $args Positional arguments.
* @param array<string, mixed> $assoc_args Associative arguments.
* @return void
*/
public function period( $args, $assoc_args ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
$this->require_admin();
if ( ! isset( $args[0] ) ) {
\WP_CLI::error( 'Missing period.' );
}
$period = strtolower( (string) $args[0] );
$valid = array( 'daily', 'weekly', 'never' );
if ( ! in_array( $period, $valid, true ) ) {
\WP_CLI::error( sprintf( "'%s' is not a valid period." . PHP_EOL . 'Available periods: %s', $period, implode( ', ', $valid ) ) );
}
$option_raw = is_multisite() ? get_site_option( 'wpvulnerability-config', array() ) : get_option( 'wpvulnerability-config', array() );
$option = is_array( $option_raw ) ? $option_raw : array();
$option['period'] = $period;
if ( is_multisite() ) {
update_site_option( 'wpvulnerability-config', $option );
} else {
update_option( 'wpvulnerability-config', $option );
}
if ( function_exists( 'wpvulnerability_schedule_notification_event' ) ) {
wpvulnerability_schedule_notification_event( $option );
}
\WP_CLI::success( sprintf( 'Notification period set to \'%s\'.', $period ) );
}
}
WP_CLI::add_command( 'wpvulnerability config', 'WPVulnerability_Config_CLI' );
}