HEX
Server: Apache
System: Linux vps-3158868-x.dattaweb.com 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64
User: emerlux (1185)
PHP: 8.3.1
Disabled: system, shell, exec, system_exec, shell_exec, mysql_pconnect, passthru, popen, proc_open, proc_close, proc_nice, proc_terminate, proc_get_status, escapeshellarg, escapeshellcmd, eval
Upload Files
File: /home/emerlux/public_html/wp-content/plugins/wpvulnerability/wpvulnerability-adminms.php
<?php
/**
 * Process functions
 *
 * @package WPVulnerability
 *
 * @version 2.0.0
 */

defined( 'ABSPATH' ) || die( 'No script kiddies please!' );

/**
 * Load the settings to be available always.
 *
 * @version 2.0.0
 *
 * @return array|false An array containing the WPVulnerability settings if they exist, or false if they don't.
 */
$wpvulnerability_settings = get_site_option( 'wpvulnerability-config' );
$wpvulnerability_analyze  = get_site_option( 'wpvulnerability-analyze' );

/**
 * Enqueues the WPVulnerability admin CSS file on WPVulnerability admin pages.
 *
 * @version 2.0.0
 *
 * @return void
 */
function wpvulnerability_admin_enqueue_scripts() {
		// Enqueue the admin stylesheet.
		wp_enqueue_style(
			'wpvulnerability-admin',
			WPVULNERABILITY_PLUGIN_URL . 'assets/admin.css',
			array(),
			WPVULNERABILITY_PLUGIN_VERSION
		);

		wp_enqueue_script(
			'wpvulnerability-admin-js',
			WPVULNERABILITY_PLUGIN_URL . 'assets/admin.js',
			array( 'jquery' ),
			WPVULNERABILITY_PLUGIN_VERSION,
			true
		);
}
add_action( 'admin_enqueue_scripts', 'wpvulnerability_admin_enqueue_scripts' );

/**
 * Create the WP-Admin options page
 * This function generates the HTML output for the WPVulnerability settings page in the WP-Admin.
 *
 * @since 2.0.0
 *
 * @return void
 */
function wpvulnerability_create_admin_page() {

	/**
	 * Processes the form submission for the WPVulnerability plugin settings in a multisite network admin context.
	 *
	 * Checks if the current request is a submission from the WPVulnerability settings page.
	 * Verifies the security nonce to prevent CSRF attacks. If the verification fails or if the request
	 * is not from a network admin or the admin dashboard, the function will halt execution and display an error.
	 * Otherwise, it sanitizes and updates the plugin settings, reschedules any relevant wp-cron events,
	 * and registers a settings error to notify the user that the information has been updated.
	 *
	 * @since 3.0.0
	*/
	if ( isset( $_GET['page'] ) && 'wpvulnerability-options' === $_GET['page'] && ! empty( $_POST ) ) {

		if ( check_admin_referer( 'wpvulnerability_nonce', 'wpauto_nonce' ) ) {

			if ( isset( $_POST['wpvulnerability_submit'] ) && isset( $_POST['wpvulnerability-config'] ) ) {

																$wpvulnerability_sanitized_values['emails'] = null;
																$wpvulnerability_sanitized_values['period'] = 'weekly';
																$wpvulnerability_sanitized_values['day']    = 'monday';
																$wpvulnerability_sanitized_values['hour']   = 0;
																$wpvulnerability_sanitized_values['minute'] = 0;
																$wpvulnerability_sanitized_values['cache']  = 12;
																																$wpvulnerability_sanitized_values['notify'] = array(
																																	'email' => 'n',
																																	'slack' => 'n',
																																	'teams' => 'n',
																																);
																																if ( isset( $post_config['notify'] ) && is_array( $post_config['notify'] ) ) {
																																	$notify                                     = array_map( 'sanitize_text_field', wp_unslash( $post_config['notify'] ) );
																																	$wpvulnerability_sanitized_values['notify'] = wpvulnerability_normalize_notify_settings( $notify );
																																}
																																$wpvulnerability_sanitized_values['slack_webhook'] = '';
																																$wpvulnerability_sanitized_values['teams_webhook'] = '';

																																$wpvulnerability_input['emails'] = array();
																																if ( isset( $_POST['wpvulnerability-config']['emails'] ) ) {
																																	$wpvulnerability_config_emails    = wp_kses( wp_unslash( (string) $_POST['wpvulnerability-config']['emails'] ), 'strip' );
																																	$wpvulnerability_input_email_text = explode( ',', $wpvulnerability_config_emails );
																																	foreach ( $wpvulnerability_input_email_text as $wpvulnerability_input_email ) {
																																		$wpvulnerability_input_email = sanitize_email( trim( $wpvulnerability_input_email ) );
																																		if ( is_email( $wpvulnerability_input_email ) ) {
																																			$wpvulnerability_input['emails'][] = $wpvulnerability_input_email;
																																		}
																																		unset( $wpvulnerability_input_email );
																																	}
																																	unset( $wpvulnerability_input_email_text, $wpvulnerability_config_emails );
																																}
																																if ( count( $wpvulnerability_input['emails'] ) ) {
																																	$wpvulnerability_sanitized_values['emails'] = implode( ',', $wpvulnerability_input['emails'] );
																																} else {
																																	$wpvulnerability_sanitized_values['emails'] = null;
																																}

																																$wpvulnerability_input['period'] = null;
																																if ( isset( $_POST['wpvulnerability-config']['period'] ) ) {
																																		$wpvulnerability_input['period'] = wp_kses( wp_unslash( (string) $_POST['wpvulnerability-config']['period'] ), 'strip' );
																																}
																																switch ( $wpvulnerability_input['period'] ) {
																																	case 'never':
																																		$wpvulnerability_sanitized_values['period'] = 'never';
																																		break;
																																	case 'daily':
																																			$wpvulnerability_sanitized_values['period'] = 'daily';
																																		break;
																																	case 'weekly':
																																			$wpvulnerability_sanitized_values['period'] = 'weekly';
																																		break;
																																	default:
																																			$wpvulnerability_sanitized_values['period'] = 'weekly';
																																		break;
																																}

																																if ( isset( $_POST['wpvulnerability-config']['day'] ) ) {
																																				$day                                     = strtolower( wp_kses( wp_unslash( (string) $_POST['wpvulnerability-config']['day'] ), 'strip' ) );
																																				$valid_days                              = array( 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday' );
																																				$wpvulnerability_sanitized_values['day'] = in_array( $day, $valid_days, true ) ? $day : 'monday';
																																}

																																if ( isset( $_POST['wpvulnerability-config']['hour'] ) ) {
																																				$hour                                     = (int) $_POST['wpvulnerability-config']['hour'];
																																				$wpvulnerability_sanitized_values['hour'] = max( 0, min( 23, $hour ) );
																																}

																																if ( isset( $_POST['wpvulnerability-config']['minute'] ) ) {
																																				$minute                                     = (int) $_POST['wpvulnerability-config']['minute'];
																																				$wpvulnerability_sanitized_values['minute'] = max( 0, min( 59, $minute ) );
																																}

																																if ( isset( $_POST['wpvulnerability-config']['cache'] ) ) {
																																				$cache                                     = (int) $_POST['wpvulnerability-config']['cache'];
																																				$wpvulnerability_sanitized_values['cache'] = in_array( $cache, array( 1, 6, 12, 24 ), true ) ? $cache : 12;
																																}

																																$post_config = filter_input( INPUT_POST, 'wpvulnerability-config', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
																																if ( isset( $post_config['notify'] ) && is_array( $post_config['notify'] ) ) {
																																	$notify                                     = array_map( 'sanitize_text_field', wp_unslash( $post_config['notify'] ) );
																																	$wpvulnerability_sanitized_values['notify'] = wpvulnerability_normalize_notify_settings( $notify );
																																}

																																if ( isset( $_POST['wpvulnerability-config']['slack_webhook'] ) ) {
																																		$slack = wp_kses( wp_unslash( (string) $_POST['wpvulnerability-config']['slack_webhook'] ), 'strip' );
																																		$wpvulnerability_sanitized_values['slack_webhook'] = esc_url_raw( $slack );
																																}

																																if ( isset( $_POST['wpvulnerability-config']['teams_webhook'] ) ) {
																																		$teams = wp_kses( wp_unslash( (string) $_POST['wpvulnerability-config']['teams_webhook'] ), 'strip' );
																																		$wpvulnerability_sanitized_values['teams_webhook'] = esc_url_raw( $teams );
																																}

																																unset( $wpvulnerability_input );

																																update_site_option(
																																	'wpvulnerability-config',
																																	array(
																																		'emails'        => $wpvulnerability_sanitized_values['emails'],
																																		'period'        => $wpvulnerability_sanitized_values['period'],
																																		'day'           => $wpvulnerability_sanitized_values['day'],
																																		'hour'          => $wpvulnerability_sanitized_values['hour'],
																																		'minute'        => $wpvulnerability_sanitized_values['minute'],
																																		'notify'        => $wpvulnerability_sanitized_values['notify'],
																																		'slack_webhook' => $wpvulnerability_sanitized_values['slack_webhook'],
																																		'teams_webhook' => $wpvulnerability_sanitized_values['teams_webhook'],
																																		'cache'         => $wpvulnerability_sanitized_values['cache'],
																																	)
																																);
								wpvulnerability_schedule_notification_event( $wpvulnerability_sanitized_values );

				unset( $wpvulnerability_sanitized_values );

				add_settings_error(
					'wpvulnerability-messages',
					'wpvulnerability-updated',
					__( 'Settings saved.', 'wpvulnerability' ),
					'success'
				);

			}

			if ( isset( $_POST['wpvulnerability_submit'] ) && isset( $_POST['wpvulnerability-analyze'] ) ) {

				$wpvulnerability_sanitized_values = array(
					'core'        => 0,
					'plugins'     => 0,
					'themes'      => 0,
					'php'         => 0,
					'apache'      => 0,
					'nginx'       => 0,
					'mariadb'     => 0,
					'mysql'       => 0,
					'imagemagick' => 0,
					'curl'        => 0,
					'memcached'   => 0,
					'redis'       => 0,
					'sqlite'      => 0,
				);

				$wpvulnerability_values = array_map( 'sanitize_text_field', wp_unslash( $_POST['wpvulnerability-analyze'] ) );

				foreach ( $wpvulnerability_values as $data ) {
					switch ( $data ) {
						case 'core':
							$wpvulnerability_sanitized_values['core'] = 1;
							break;
						case 'plugins':
							$wpvulnerability_sanitized_values['plugins'] = 1;
							break;
						case 'themes':
							$wpvulnerability_sanitized_values['themes'] = 1;
							break;
						case 'php':
							$wpvulnerability_sanitized_values['php'] = 1;
							break;
						case 'apache':
							$wpvulnerability_sanitized_values['apache'] = 1;
							break;
						case 'nginx':
							$wpvulnerability_sanitized_values['nginx'] = 1;
							break;
						case 'mariadb':
							$wpvulnerability_sanitized_values['mariadb'] = 1;
							break;
						case 'mysql':
							$wpvulnerability_sanitized_values['mysql'] = 1;
							break;
						case 'imagemagick':
							$wpvulnerability_sanitized_values['imagemagick'] = 1;
							break;
						case 'curl':
							$wpvulnerability_sanitized_values['curl'] = 1;
							break;
						case 'memcached':
							$wpvulnerability_sanitized_values['memcached'] = 1;
							break;
						case 'redis':
							$wpvulnerability_sanitized_values['redis'] = 1;
							break;
						case 'sqlite':
							$wpvulnerability_sanitized_values['sqlite'] = 1;
							break;
					}
				}

				update_site_option(
					'wpvulnerability-analyze',
					array(
						'core'        => $wpvulnerability_sanitized_values['core'],
						'plugins'     => $wpvulnerability_sanitized_values['plugins'],
						'themes'      => $wpvulnerability_sanitized_values['themes'],
						'php'         => $wpvulnerability_sanitized_values['php'],
						'apache'      => $wpvulnerability_sanitized_values['apache'],
						'nginx'       => $wpvulnerability_sanitized_values['nginx'],
						'mariadb'     => $wpvulnerability_sanitized_values['mariadb'],
						'mysql'       => $wpvulnerability_sanitized_values['mysql'],
						'imagemagick' => $wpvulnerability_sanitized_values['imagemagick'],
						'curl'        => $wpvulnerability_sanitized_values['curl'],
						'memcached'   => $wpvulnerability_sanitized_values['memcached'],
						'redis'       => $wpvulnerability_sanitized_values['redis'],
						'sqlite'      => $wpvulnerability_sanitized_values['sqlite'],
					)
				);

				unset( $wpvulnerability_sanitized_values );

				add_settings_error(
					'wpvulnerability-messages',
					'wpvulnerability-updated',
					__( 'Settings saved.', 'wpvulnerability' ),
					'success'
				);

			}
		}
	}

	/**
	 * Reset the data
	 *
	 * @since 3.0.0
	 */
	if ( isset( $_POST['wpvulnerability_reset'] ) && check_admin_referer( 'wpvulnerability_nonce', 'wpauto_nonce' ) ) {

		// Calls the reset function.
		wpvulnerability_update_database_data();

		set_transient( 'wpvulnerability_message_manual_success', __( 'Data from source has been reloaded.', 'wpvulnerability' ), 10 );

	}

	/**
	 * Send an test email
	 *
	 * @since 3.0.0
	 */
	if ( isset( $_POST['wpvulnerability_email'] ) && check_admin_referer( 'wpvulnerability_nonce', 'wpauto_nonce' ) ) {

		if ( ! function_exists( 'wpvulnerability_execute_notification' ) ) {
			require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-core.php';
			require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-plugins.php';
			require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-themes.php';
			require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-software.php';
			require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-process.php';
			require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-notifications.php';
		}

		// Calls the notifications function, forced.
		$wpmail = wpvulnerability_execute_notification( true );

		if ( $wpmail ) {

			set_transient( 'wpvulnerability_message_manual_success', __( 'Test email has been sent.', 'wpvulnerability' ), 10 );

		} else {

			set_transient( 'wpvulnerability_message_manual_error', __( 'Test email has failed. Please, check your email settings.', 'wpvulnerability' ), 10 );

		}
	}

	$wpvulnerability_settings = get_site_option( 'wpvulnerability-config' );
	?>
	<div class="header-wrap">
		<div class="wrapper">
			<div class="header wpvulnerability-header">
				<div class="logo">
					<img src="<?php echo esc_url( WPVULNERABILITY_PLUGIN_URL ); ?>assets/logo64.png" style="height: 64px; vertical-align: text-top; width: 64px;" alt="" title="WPVulnerability">
					<h2><?php esc_html_e( 'WPVulnerability settings', 'wpvulnerability' ); ?></h2>
				</div>
			</div>
		</div>
	</div>
	<?php
	$wpvulnerability_message_manual_success = get_transient( 'wpvulnerability_message_manual_success' );
	if ( $wpvulnerability_message_manual_success ) {
		echo '<div class="notice notice-success"><p>' . esc_html( (string) $wpvulnerability_message_manual_success ) . '</p></div>';
		delete_transient( 'wpvulnerability_message_manual_success' );
		unset( $wpvulnerability_message_manual_success );
	}
	$wpvulnerability_message_manual_error = get_transient( 'wpvulnerability_message_manual_error' );
	if ( $wpvulnerability_message_manual_error ) {
		echo '<div class="notice notice-error"><p>' . esc_html( (string) $wpvulnerability_message_manual_error ) . '</p></div>';
		delete_transient( 'wpvulnerability_message_manual_error' );
		unset( $wpvulnerability_message_manual_error );
	}
	?>
	<?php settings_errors( 'wpvulnerability-messages', true ); ?>
	<div class="wrap">
	<div class="wpvulnerability-container">
	<div class="wpvulnerability-column">
		<section class="section">
			<form method="post">
				<?php
					settings_fields( 'admin_wpvulnerability_settings' );
					do_settings_sections( 'wpvulnerability-config' );
					wp_nonce_field( 'wpvulnerability_nonce', 'wpauto_nonce' );
					submit_button(
						__( 'Save Changes', 'wpvulnerability' ),
						'primary',
						'wpvulnerability_submit'
					);
				?>
			</form>
		</section>
		<section class="section">
			<form method="post">
				<?php
					settings_fields( 'admin_wpvulnerability_analyze' );
					do_settings_sections( 'wpvulnerability-analyze' );
					wp_nonce_field( 'wpvulnerability_nonce', 'wpauto_nonce' );
					submit_button(
						__( 'Save Changes', 'wpvulnerability' ),
						'primary',
						'wpvulnerability_submit'
					);
				?>
			</form>
		</section>
		<section class="section">
			<header class="section-header">
				<hr>
				<h3><?php esc_html_e( 'Reload the data from source', 'wpvulnerability' ); ?></h3>
			</header>
			<div class="section-content">
								<p><?php esc_html_e( 'Reload all Core, Plugins, Themes and other components information directly from the API to have updated data.', 'wpvulnerability' ); ?></p>
								<form method="post" action="settings.php?page=wpvulnerability-options">
										<?php wp_nonce_field( 'wpvulnerability_nonce', 'wpauto_nonce' ); ?>
										<input type="submit" name="wpvulnerability_reset" value="<?php esc_attr_e( 'Reload Data', 'wpvulnerability' ); ?>" class="button button-secondary">
								</form>
			</div>
		</section>
		<section class="section">
			<header class="section-header">
				<hr>
				<h3><?php esc_html_e( 'Email test', 'wpvulnerability' ); ?></h3>
			</header>
			<div class="section-content">
	<?php
		$from_email = null;
	if ( defined( 'WPVULNERABILITY_MAIL' ) ) {
		$from_email = sanitize_email( trim( WPVULNERABILITY_MAIL ) );
		if ( is_email( $from_email ) ) {
			?>
				<p><?php esc_html_e( 'The mail will be sent from (set on WPVULNERABILITY_MAIL): ', 'wpvulnerability' ); ?> <code><?php echo esc_html( $from_email ); ?></code></p>
			<?php
		}
	}
	if ( ! $from_email ) {
		$from_email = get_site_option( 'admin_email' );
		?>
				<p><?php esc_html_e( 'The mail will be sent from: ', 'wpvulnerability' ); ?> <code><?php echo esc_html( $from_email ); ?></code></p>
		<?php
	}
	?>
<p><?php esc_html_e( 'Send an email with the vulnerabilities (or empty).', 'wpvulnerability' ); ?></p>
<p><a href="https://www.wpvulnerability.com/plugin/#from-mail" target="_blank"><small><i><?php esc_html_e( 'Read more about how to change the "From:" of the email.', 'wpvulnerability' ); ?></i></small></a></p>
<form method="post" action="settings.php?page=wpvulnerability-options">
	<?php wp_nonce_field( 'wpvulnerability_nonce', 'wpauto_nonce' ); ?>
<input type="submit" name="wpvulnerability_email" value="<?php esc_attr_e( 'Send email', 'wpvulnerability' ); ?>" class="button button-secondary">
</form>
			</div>
		</section>
		</div><div class="wpvulnerability-column">
	<?php
	$wpvulnerability_statistics = json_decode( get_site_option( 'wpvulnerability-statistics' ), true );
	?>
		<section class="section">
			<header class="section-header">
				<h2><?php esc_html_e( 'WPVulnerability Statistics', 'wpvulnerability' ); ?></h2>
			</header>
			<div class="section-content">
				<div class="wpvulnerability-container">
					<div class="wpvulnerability-column">
				<dl>
					<dt><?php esc_html_e( 'Plugins', 'wpvulnerability' ); ?></dt>
	<?php
	if ( isset( $wpvulnerability_statistics['plugins'] ) ) {
		?>
					<dd>
		<?php

		printf(
			// translators: number of vulnerabilities.
			esc_html( _n( '%s vulnerability', '%s vulnerabilities', absint( $wpvulnerability_statistics['plugins']['vulnerabilities'] ), 'wpvulnerability' ) ),
			esc_html( number_format_i18n( absint( $wpvulnerability_statistics['plugins']['vulnerabilities'] ) ) )
		);

		printf(
			// translators: number of plugins.
			esc_html( _n( ' (%s plugin)', ' (%s plugins)', absint( $wpvulnerability_statistics['plugins']['products'] ), 'wpvulnerability' ) ),
			esc_html( number_format_i18n( absint( $wpvulnerability_statistics['plugins']['products'] ) ) )
		);
		?>
					</dd>
		<?php
	} else {
		?>
					<dd><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></dd>
		<?php
	}
	?>
					<dt><?php esc_html_e( 'Themes', 'wpvulnerability' ); ?></dt>
	<?php
	if ( isset( $wpvulnerability_statistics['themes'] ) ) {
		?>
					<dd>
		<?php
		printf(
			// translators: number of vulnerabilities.
			esc_html( _n( '%s vulnerability', '%s vulnerabilities', absint( $wpvulnerability_statistics['themes']['vulnerabilities'] ), 'wpvulnerability' ) ),
			esc_html( number_format_i18n( absint( $wpvulnerability_statistics['themes']['vulnerabilities'] ) ) )
		);

		printf(
			// translators: number of themes.
			esc_html( _n( ' (%s theme)', ' (%s themes)', absint( $wpvulnerability_statistics['themes']['products'] ), 'wpvulnerability' ) ),
			esc_html( number_format_i18n( absint( $wpvulnerability_statistics['themes']['products'] ) ) )
		);
		?>
					</dd>
		<?php
	} else {
		?>
					<dd><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></dd>
		<?php
	}
	?>
					<dt><?php esc_html_e( 'PHP', 'wpvulnerability' ); ?></dt>
	<?php
	if ( isset( $wpvulnerability_statistics['php'] ) ) {
		?>
					<dd>
					<?php
					printf(
						// translators: number of vulnerabilities.
						esc_html( _n( '%s vulnerability', '%s vulnerabilities', absint( $wpvulnerability_statistics['php']['vulnerabilities'] ), 'wpvulnerability' ) ),
						esc_html( number_format_i18n( absint( $wpvulnerability_statistics['php']['vulnerabilities'] ) ) )
					);
					?>
					</dd>
		<?php
	} else {
		?>
					<dd><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></dd>
		<?php
	}
	?>
					<dt><?php esc_html_e( 'Apache HTTPD', 'wpvulnerability' ); ?></dt>
	<?php
	if ( isset( $wpvulnerability_statistics['apache'] ) ) {
		?>
					<dd>
					<?php
					printf(
						// translators: number of vulnerabilities.
						esc_html( _n( '%s vulnerability', '%s vulnerabilities', absint( $wpvulnerability_statistics['apache']['vulnerabilities'] ), 'wpvulnerability' ) ),
						esc_html( number_format_i18n( absint( $wpvulnerability_statistics['apache']['vulnerabilities'] ) ) )
					);
					?>
					</dd>
		<?php
	} else {
		?>
					<dd><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></dd>
		<?php
	}
	?>
					<dt><?php esc_html_e( 'nginx', 'wpvulnerability' ); ?></dt>
	<?php
	if ( isset( $wpvulnerability_statistics['nginx'] ) ) {
		?>
					<dd>
					<?php
					printf(
						// translators: number of vulnerabilities.
						esc_html( _n( '%s vulnerability', '%s vulnerabilities', absint( $wpvulnerability_statistics['nginx']['vulnerabilities'] ), 'wpvulnerability' ) ),
						esc_html( number_format_i18n( absint( $wpvulnerability_statistics['nginx']['vulnerabilities'] ) ) )
					);
					?>
					</dd>
		<?php
	} else {
		?>
					<dd><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></dd>
		<?php
	}
	?>
					<dt><?php esc_html_e( 'MariaDB', 'wpvulnerability' ); ?></dt>
	<?php
	if ( isset( $wpvulnerability_statistics['mariadb'] ) ) {
		?>
					<dd>
					<?php
					printf(
						// translators: number of vulnerabilities.
						esc_html( _n( '%s vulnerability', '%s vulnerabilities', absint( $wpvulnerability_statistics['mariadb']['vulnerabilities'] ), 'wpvulnerability' ) ),
						esc_html( number_format_i18n( absint( $wpvulnerability_statistics['mariadb']['vulnerabilities'] ) ) )
					);
					?>
					</dd>
		<?php
	} else {
		?>
					<dd><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></dd>
		<?php
	}
	?>
						</dl>
							</div>
							<div class="wpvulnerability-column">
						<dl>
					<dt><?php esc_html_e( 'MySQL', 'wpvulnerability' ); ?></dt>
	<?php
	if ( isset( $wpvulnerability_statistics['mysql'] ) ) {
		?>
					<dd>
					<?php
					printf(
						// translators: number of vulnerabilities.
						esc_html( _n( '%s vulnerability', '%s vulnerabilities', absint( $wpvulnerability_statistics['mysql']['vulnerabilities'] ), 'wpvulnerability' ) ),
						esc_html( number_format_i18n( absint( $wpvulnerability_statistics['mysql']['vulnerabilities'] ) ) )
					);
					?>
					</dd>
		<?php
	} else {
		?>
					<dd><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></dd>
		<?php
	}
	?>
					<dt><?php esc_html_e( 'ImageMagick', 'wpvulnerability' ); ?></dt>
	<?php
	if ( isset( $wpvulnerability_statistics['imagemagick'] ) ) {
		?>
					<dd>
					<?php
					printf(
						// translators: number of vulnerabilities.
						esc_html( _n( '%s vulnerability', '%s vulnerabilities', absint( $wpvulnerability_statistics['imagemagick']['vulnerabilities'] ), 'wpvulnerability' ) ),
						esc_html( number_format_i18n( absint( $wpvulnerability_statistics['imagemagick']['vulnerabilities'] ) ) )
					);
					?>
					</dd>
		<?php
	} else {
		?>
					<dd><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></dd>
		<?php
	}
	?>
					<dt><?php esc_html_e( 'curl', 'wpvulnerability' ); ?></dt>
	<?php
	if ( isset( $wpvulnerability_statistics['curl'] ) ) {
		?>
					<dd>
					<?php
					printf(
						// translators: number of vulnerabilities.
						esc_html( _n( '%s vulnerability', '%s vulnerabilities', absint( $wpvulnerability_statistics['curl']['vulnerabilities'] ), 'wpvulnerability' ) ),
						esc_html( number_format_i18n( absint( $wpvulnerability_statistics['curl']['vulnerabilities'] ) ) )
					);
					?>
					</dd>
		<?php
	} else {
		?>
					<dd><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></dd>
		<?php
	}
	?>
					<dt><?php esc_html_e( 'memcached', 'wpvulnerability' ); ?></dt>
	<?php
	if ( isset( $wpvulnerability_statistics['memcached'] ) ) {
		?>
					<dd>
					<?php
					printf(
						// translators: number of vulnerabilities.
						esc_html( _n( '%s vulnerability', '%s vulnerabilities', absint( $wpvulnerability_statistics['memcached']['vulnerabilities'] ), 'wpvulnerability' ) ),
						esc_html( number_format_i18n( absint( $wpvulnerability_statistics['memcached']['vulnerabilities'] ) ) )
					);
					?>
					</dd>
		<?php
	} else {
		?>
					<dd><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></dd>
		<?php
	}
	?>
					<dt><?php esc_html_e( 'Redis', 'wpvulnerability' ); ?></dt>
	<?php
	if ( isset( $wpvulnerability_statistics['redis'] ) ) {
		?>
					<dd>
					<?php
					printf(
						// translators: number of vulnerabilities.
						esc_html( _n( '%s vulnerability', '%s vulnerabilities', absint( $wpvulnerability_statistics['redis']['vulnerabilities'] ), 'wpvulnerability' ) ),
						esc_html( number_format_i18n( absint( $wpvulnerability_statistics['redis']['vulnerabilities'] ) ) )
					);
					?>
					</dd>
		<?php
	} else {
		?>
					<dd><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></dd>
		<?php
	}
	?>
					<dt><?php esc_html_e( 'SQLite', 'wpvulnerability' ); ?></dt>
	<?php
	if ( isset( $wpvulnerability_statistics['sqlite'] ) ) {
		?>
					<dd>
					<?php
					printf(
						// translators: number of vulnerabilities.
						esc_html( _n( '%s vulnerability', '%s vulnerabilities', absint( $wpvulnerability_statistics['sqlite']['vulnerabilities'] ), 'wpvulnerability' ) ),
						esc_html( number_format_i18n( absint( $wpvulnerability_statistics['sqlite']['vulnerabilities'] ) ) )
					);
					?>
					</dd>
		<?php
	} else {
		?>
					<dd><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></dd>
		<?php
	}
	?>
				</dl>
							</div>
						</div>
	<?php
	if ( isset( $wpvulnerability_statistics['updated'] ) ) {
		if ( version_compare( $GLOBALS['wp_version'], '5.0', '>=' ) ) {
			switch_to_locale( determine_locale() );
		} elseif ( version_compare( $GLOBALS['wp_version'], '4.7', '>=' ) ) {
			switch_to_locale( get_locale() );
		}
		$formatted_datetime = date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), (int) $wpvulnerability_statistics['updated']['unixepoch'] );
		?>
				<p><small>
				<?php
				// translators: date of last update.
				printf( esc_html__( 'Updated: %s', 'wpvulnerability' ), esc_html( $formatted_datetime ) );
				?>
				</small></p>
		<?php
		if ( version_compare( $GLOBALS['wp_version'], '4.7', '>=' ) ) {
			restore_previous_locale();
		}
	}
	?>
			</div>
		</section>
		<section class="section">
			<header class="section-header">
				<h2><?php esc_html_e( 'Behind the Project', 'wpvulnerability' ); ?></h2>
			</header>
			<div class="section-content"><div class="wpvulnerability-container">
				<div class="wpvulnerability-column">
				<h3><?php esc_html_e( 'Sponsors', 'wpvulnerability' ); ?></h3>
	<?php
	if ( isset( $wpvulnerability_statistics['sponsors'] ) ) {
		foreach ( $wpvulnerability_statistics['sponsors'] as $sponsor ) {
			?>
				<p><img src="<?php echo esc_url( $sponsor['image'] ); ?>" width="32" height="32" style="vertical-align: middle; margin-right: 8px;"> <a href="<?php echo esc_url( $sponsor['url'] ); ?>" target="_blank" rel="noreferrer noopener"><?php echo esc_html( $sponsor['name'] ); ?></a></p>
			<?php
		}
	} else {
		?>
				<p><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></p>
		<?php
	}
	?>

				</div><div class="wpvulnerability-column">

				<h3><?php esc_html_e( 'Contributors', 'wpvulnerability' ); ?></h3>
	<?php
	if ( isset( $wpvulnerability_statistics['contributors'] ) ) {
		foreach ( $wpvulnerability_statistics['contributors'] as $contributor ) {
			?>
				<p><img src="<?php echo esc_url( $contributor['image'] ); ?>" width="32" height="32" style="vertical-align: middle; margin-right: 8px;"> <a href="<?php echo esc_url( $contributor['url'] ); ?>" target="_blank" rel="noreferrer noopener"><?php echo esc_html( $contributor['name'] ); ?></a></p>
			<?php
		}
	} else {
		?>
				<p><?php esc_html_e( 'Data not available.', 'wpvulnerability' ); ?></p>
		<?php
	}
	?>

				</div>
			</div></div>
		</section>
		</div>
	</div></div>
	<?php
}

/**
 * Adds a WP-Admin menu option for the WPVulnerability plugin.
 *
 * @since 2.0.0
 *
 * @return void
 */
function wpvulnerability_admin_menu() {
	// Adds a submenu page under the Settings menu.
	add_submenu_page(
		'settings.php',
		__( 'WPVulnerability', 'wpvulnerability' ),
		__( 'WPVulnerability', 'wpvulnerability' ),
		'manage_network_options',
		'wpvulnerability-options',
		'wpvulnerability_create_admin_page'
	);
}
add_action( 'network_admin_menu', 'wpvulnerability_admin_menu' );

/**
 * Print the settings header information for the notifications section.
 *
 * @since 2.0.0
 *
 * @return void
 */
function wpvulnerability_admin_section_notifications() {
		// Output the header information for the notifications section.
		esc_html_e( 'Configure and save these settings to receive notifications.', 'wpvulnerability' );
}

/**
 * Callback function to display the email input field in the admin settings page.
 * This function retrieves the current WPVulnerability plugin settings and displays the email input field
 * for users to enter their email addresses. If no email is saved in the settings, the admin email is displayed.
 *
 * @since 2.0.0
 *
 * @return void
 */
function wpvulnerability_admin_emails_callback() {
	// Retrieve the WPVulnerability plugin settings.
	$wpvulnerability_settings = get_site_option( 'wpvulnerability-config' );

	// Set a default value for the email input field if no email is saved in the settings.
	if ( ! isset( $wpvulnerability_settings['emails'] ) ) {
		$wpvulnerability_settings['emails'] = '';
	}

	// Output the email input field. Use the network admin email as a placeholder in a multisite environment.
	$admin_email = get_site_option( 'admin_email' );

	// Output the email input field and display the admin email as a hint.
	?>
	<input class="regular-text" type="text" name="wpvulnerability-config[emails]" id="wpvulnerability_emails" placeholder="<?php echo esc_attr( (string) $admin_email ); ?>" value="<?php echo esc_attr( (string) $wpvulnerability_settings['emails'] ); ?>">
	<br><small><?php esc_html_e( 'Default administrator email', 'wpvulnerability' ); ?>: <?php echo esc_attr( (string) $admin_email ); ?></small>
	<?php

	unset( $admin_email );
}

/**
 * Print the cache expiration selector.
 *
 * @since 4.1.0
 *
 * @return void
 */
function wpvulnerability_admin_cache_callback() {

	$wpvulnerability_settings = get_site_option( 'wpvulnerability-config', array() );
	$options                  = array( 1, 6, 12, 24 );
	$forced_cache             = null;

	if ( defined( 'WPVULNERABILITY_CACHE_HOURS' ) ) {
		$forced_cache = (int) WPVULNERABILITY_CACHE_HOURS;
		if ( ! in_array( $forced_cache, $options, true ) ) {
			$options[] = $forced_cache;
			sort( $options, SORT_NUMERIC );
		}
	}

	$current = isset( $wpvulnerability_settings['cache'] ) ? (int) $wpvulnerability_settings['cache'] : 12;
	if ( null !== $forced_cache ) {
		$current = $forced_cache;
	}

	echo '<select name="wpvulnerability-config[cache]" id="wpvulnerability_cache"';
	disabled( null !== $forced_cache );
	echo '>';
	foreach ( $options as $hours ) {
		printf(
			'<option value="%1$s"%2$s>%3$s</option>',
			esc_attr( $hours ),
			selected( $current, $hours, false ),
			esc_html(
				sprintf(
						/* translators: %d: number of hours */
					_n( '%d hour', '%d hours', $hours, 'wpvulnerability' ),
					$hours
				)
			)
		);
	}
		echo '</select>';

	if ( null !== $forced_cache ) {
			printf(
				'<input type="hidden" name="wpvulnerability-config[cache]" value="%s" />',
				esc_attr( $current )
			);
	}

		printf(
			'<p class="description"><a href="%1$s" target="_blank"><small><i>%2$s</i></small></a></p>',
			esc_url( 'https://www.wpvulnerability.com/plugin/#cache-duration' ),
			esc_html__( 'Read more if you want to force the cache time.', 'wpvulnerability' )
		);
}


/**
 * Print the settings header information for the analyze section.
 *
 * @since 3.3.0
 *
 * @return void
 */
function wpvulnerability_admin_section_analyze() {
	// Output the header information for the analyze section.
	esc_html_e( 'Configure and save these settings to hide vulnerabilities.', 'wpvulnerability' );
}

/**
 * Print when to send the vulnerability scan emails.
 *
 * @since 2.0.0
 *
 * @return void
 */
function wpvulnerability_admin_period_callback() {
		// Get the saved plugin settings.
		$wpvulnerability_settings = get_site_option( 'wpvulnerability-config', array() );
		$defaults                 = array(
			'period' => 'weekly',
			'day'    => 'monday',
			'hour'   => 0,
			'minute' => 0,
		);
		$wpvulnerability_settings = wp_parse_args( $wpvulnerability_settings, $defaults );

		?>
		<div id="wpvulnerability_period">
		<label>
				<input type="radio" name="wpvulnerability-config[period]" value="never" <?php checked( $wpvulnerability_settings['period'], 'never' ); ?> />
				<?php esc_html_e( 'Never', 'wpvulnerability' ); ?>
		</label>
		<br/>
		<label>
				<input type="radio" name="wpvulnerability-config[period]" value="daily" <?php checked( $wpvulnerability_settings['period'], 'daily' ); ?> />
				<?php esc_html_e( 'Daily', 'wpvulnerability' ); ?>
		</label>
		<br/>
		<label>
				<input type="radio" name="wpvulnerability-config[period]" value="weekly" <?php checked( $wpvulnerability_settings['period'], 'weekly' ); ?> />
				<?php esc_html_e( 'Weekly', 'wpvulnerability' ); ?>
		</label>
		<div id="wpvulnerability_day_wrap">
				<br/>
				<label for="wpvulnerability_day"><?php esc_html_e( 'Day', 'wpvulnerability' ); ?></label>
				<select name="wpvulnerability-config[day]" id="wpvulnerability_day">
						<option value="monday" <?php selected( $wpvulnerability_settings['day'], 'monday' ); ?>><?php esc_html_e( 'Monday', 'wpvulnerability' ); ?></option>
						<option value="tuesday" <?php selected( $wpvulnerability_settings['day'], 'tuesday' ); ?>><?php esc_html_e( 'Tuesday', 'wpvulnerability' ); ?></option>
						<option value="wednesday" <?php selected( $wpvulnerability_settings['day'], 'wednesday' ); ?>><?php esc_html_e( 'Wednesday', 'wpvulnerability' ); ?></option>
						<option value="thursday" <?php selected( $wpvulnerability_settings['day'], 'thursday' ); ?>><?php esc_html_e( 'Thursday', 'wpvulnerability' ); ?></option>
						<option value="friday" <?php selected( $wpvulnerability_settings['day'], 'friday' ); ?>><?php esc_html_e( 'Friday', 'wpvulnerability' ); ?></option>
						<option value="saturday" <?php selected( $wpvulnerability_settings['day'], 'saturday' ); ?>><?php esc_html_e( 'Saturday', 'wpvulnerability' ); ?></option>
						<option value="sunday" <?php selected( $wpvulnerability_settings['day'], 'sunday' ); ?>><?php esc_html_e( 'Sunday', 'wpvulnerability' ); ?></option>
				</select>
		</div>
		<div id="wpvulnerability_time_wrap">
				<br/>
				<label for="wpvulnerability_hour"><?php esc_html_e( 'Hour', 'wpvulnerability' ); ?></label>
				<input type="number" min="0" max="23" name="wpvulnerability-config[hour]" id="wpvulnerability_hour" value="<?php echo esc_attr( (string) $wpvulnerability_settings['hour'] ); ?>" />
				<label for="wpvulnerability_minute"><?php esc_html_e( 'Minute', 'wpvulnerability' ); ?></label>
				<input type="number" min="0" max="59" name="wpvulnerability-config[minute]" id="wpvulnerability_minute" value="<?php echo esc_attr( (string) $wpvulnerability_settings['minute'] ); ?>" />
		</div>
		</div>
		<?php
}

/**
 * Print where to send the notifications.
 *
 * @since 3.6.0
 *
 * @return void
 */
function wpvulnerability_admin_notify_callback() {
		$wpvulnerability_settings = get_site_option( 'wpvulnerability-config', array() );
			$defaults             = array(
				'email' => 'y',
				'slack' => 'n',
				'teams' => 'n',
			);

			if ( ! isset( $wpvulnerability_settings['notify'] ) || ! is_array( $wpvulnerability_settings['notify'] ) ) {
							$wpvulnerability_settings['notify'] = $defaults;
			} else {
							$wpvulnerability_settings['notify'] = wp_parse_args( $wpvulnerability_settings['notify'], $defaults );
			}

			$wpvulnerability_settings['notify'] = wpvulnerability_normalize_notify_settings( $wpvulnerability_settings['notify'] );

			$email_enabled = wpvulnerability_is_yes( $wpvulnerability_settings['notify']['email'] );
			$slack_enabled = wpvulnerability_is_yes( $wpvulnerability_settings['notify']['slack'] );
			$teams_enabled = wpvulnerability_is_yes( $wpvulnerability_settings['notify']['teams'] );

			?>
		<div id="wpvulnerability_notify">
		<label>
							<input type="checkbox" name="wpvulnerability-config[notify][email]" value="y" <?php checked( $email_enabled ); ?> />
				<?php esc_html_e( 'Email', 'wpvulnerability' ); ?>
		</label>
		<br/>
		<label>
							<input type="checkbox" name="wpvulnerability-config[notify][slack]" value="y" <?php checked( $slack_enabled ); ?> />
				<?php esc_html_e( 'Slack', 'wpvulnerability' ); ?>
		</label>
		<br/>
		<label>
							<input type="checkbox" name="wpvulnerability-config[notify][teams]" value="y" <?php checked( $teams_enabled ); ?> />
				<?php esc_html_e( 'Microsoft Teams', 'wpvulnerability' ); ?>
		</label>
		</div>
		<?php
}

/**
 * Print the Slack webhook input field.
 *
 * @since 3.6.0
 *
 * @return void
 */
function wpvulnerability_admin_slack_callback() {

		$wpvulnerability_settings = get_site_option( 'wpvulnerability-config', array() );
		$slack_webhook            = isset( $wpvulnerability_settings['slack_webhook'] ) ? $wpvulnerability_settings['slack_webhook'] : '';

	?>
				<input class="regular-text" type="text" name="wpvulnerability-config[slack_webhook]" id="wpvulnerability_slack_webhook" placeholder="<?php echo esc_attr( 'https://hooks.slack.com/services/...' ); ?>" value="<?php echo esc_attr( (string) $slack_webhook ); ?>" />
				<?php
}

/**
 * Print the Teams webhook input field.
 *
 * @since 3.6.0
 *
 * @return void
 */
function wpvulnerability_admin_teams_callback() {

		$wpvulnerability_settings = get_site_option( 'wpvulnerability-config', array() );
		$teams_webhook            = isset( $wpvulnerability_settings['teams_webhook'] ) ? $wpvulnerability_settings['teams_webhook'] : '';

	?>
				<input class="regular-text" type="text" name="wpvulnerability-config[teams_webhook]" id="wpvulnerability_teams_webhook" placeholder="<?php echo esc_attr( 'https://outlook.office.com/webhook/...' ); ?>" value="<?php echo esc_attr( (string) $teams_webhook ); ?>" />
				<?php
}

/**
 * Displays the WPVulnerability plugin analysis settings in the admin panel.
 *
 * This function retrieves the current WPVulnerability analysis settings and
 * ensures all necessary options are set. It then outputs a multiple-select
 * field allowing the user to select which components (core, plugins, themes,
 * php, apache, nginx) to analyze.
 *
 * @since 3.3.0
 *
 * @return void
 */
function wpvulnerability_admin_analyze_callback() {

	// Retrieve the WPVulnerability plugin settings.
	$wpvulnerability_analyze = get_site_option( 'wpvulnerability-analyze', array() );
	$components              = array( 'core', 'plugins', 'themes', 'php', 'apache', 'nginx', 'mariadb', 'mysql', 'imagemagick', 'curl', 'memcached', 'redis', 'sqlite' );
	$forced                  = array();

	foreach ( $components as $component ) {
		if ( ! isset( $wpvulnerability_analyze[ $component ] ) ) {
			$wpvulnerability_analyze[ $component ] = 0;
		}
		$constant             = 'WPVULNERABILITY_HIDE_' . strtoupper( $component );
		$forced[ $component ] = defined( $constant ) && constant( $constant );
		if ( $forced[ $component ] ) {
			$wpvulnerability_analyze[ $component ] = 1;
		}
	}
	?>
	<div id="wpvulnerability_analyze">
	<label>
		<input type="checkbox" name="wpvulnerability-analyze[core]" value="core" <?php checked( $wpvulnerability_analyze['core'] ); ?> <?php disabled( $forced['core'] ); ?> />
		<?php esc_html_e( 'Core', 'wpvulnerability' ); ?>
	</label>
	<br/>
	<label>
		<input type="checkbox" name="wpvulnerability-analyze[plugins]" value="plugins" <?php checked( $wpvulnerability_analyze['plugins'] ); ?> <?php disabled( $forced['plugins'] ); ?> />
		<?php esc_html_e( 'Plugins', 'wpvulnerability' ); ?>
	</label>
	<br/>
	<label>
		<input type="checkbox" name="wpvulnerability-analyze[themes]" value="themes" <?php checked( $wpvulnerability_analyze['themes'] ); ?> <?php disabled( $forced['themes'] ); ?> />
		<?php esc_html_e( 'Themes', 'wpvulnerability' ); ?>
	</label>
	<br/>
	<label>
		<input type="checkbox" name="wpvulnerability-analyze[php]" value="php" <?php checked( $wpvulnerability_analyze['php'] ); ?> <?php disabled( $forced['php'] ); ?> />
		<?php esc_html_e( 'PHP', 'wpvulnerability' ); ?>
	</label>
	<br/>
	<label>
		<input type="checkbox" name="wpvulnerability-analyze[apache]" value="apache" <?php checked( $wpvulnerability_analyze['apache'] ); ?> <?php disabled( $forced['apache'] ); ?> />
		<?php esc_html_e( 'Apache HTTPD', 'wpvulnerability' ); ?>
	</label>
	<br/>
	<label>
		<input type="checkbox" name="wpvulnerability-analyze[nginx]" value="nginx" <?php checked( $wpvulnerability_analyze['nginx'] ); ?> <?php disabled( $forced['nginx'] ); ?> />
		<?php esc_html_e( 'nginx', 'wpvulnerability' ); ?>
	</label>
	<br/>
	<label>
		<input type="checkbox" name="wpvulnerability-analyze[mariadb]" value="mariadb" <?php checked( $wpvulnerability_analyze['mariadb'] ); ?> <?php disabled( $forced['mariadb'] ); ?> />
		<?php esc_html_e( 'MariaDB', 'wpvulnerability' ); ?>
	</label>
	<br/>
	<label>
		<input type="checkbox" name="wpvulnerability-analyze[mysql]" value="mysql" <?php checked( $wpvulnerability_analyze['mysql'] ); ?> <?php disabled( $forced['mysql'] ); ?> />
		<?php esc_html_e( 'MySQL', 'wpvulnerability' ); ?>
	</label>
	<br/>
	<label>
		<input type="checkbox" name="wpvulnerability-analyze[imagemagick]" value="imagemagick" <?php checked( $wpvulnerability_analyze['imagemagick'] ); ?> <?php disabled( $forced['imagemagick'] ); ?> />
		<?php esc_html_e( 'ImageMagick', 'wpvulnerability' ); ?>
	</label>
	<br/>
	<label>
		<input type="checkbox" name="wpvulnerability-analyze[curl]" value="curl" <?php checked( $wpvulnerability_analyze['curl'] ); ?> <?php disabled( $forced['curl'] ); ?> />
		<?php esc_html_e( 'curl', 'wpvulnerability' ); ?>
	</label>
	<br/>
	<label>
		<input type="checkbox" name="wpvulnerability-analyze[memcached]" value="memcached" <?php checked( $wpvulnerability_analyze['memcached'] ); ?> <?php disabled( $forced['memcached'] ); ?> />
		<?php esc_html_e( 'memcached', 'wpvulnerability' ); ?>
	</label>
	<br/>
	<label>
		<input type="checkbox" name="wpvulnerability-analyze[redis]" value="redis" <?php checked( $wpvulnerability_analyze['redis'] ); ?> <?php disabled( $forced['redis'] ); ?> />
		<?php esc_html_e( 'Redis', 'wpvulnerability' ); ?>
	</label>
	<br/>
	<label>
		<input type="checkbox" name="wpvulnerability-analyze[sqlite]" value="sqlite" <?php checked( $wpvulnerability_analyze['sqlite'] ); ?> <?php disabled( $forced['sqlite'] ); ?> />
		<?php esc_html_e( 'SQLite', 'wpvulnerability' ); ?>
	</label>
	<p><a href="https://www.wpvulnerability.com/plugin/#force-hiding-checks" target="_blank"><small><i><?php esc_html_e( 'Read more about how to force the deactivation of an item.', 'wpvulnerability' ); ?></i></small></a></p>
	</div>
	<?php
}

/**
 * Content for the Dashboard Widget
 *
 * @since 2.2.0
 *
 * @return void
 */
function wpvulnerability_admin_dashboard_content() {
	// Get the number of core vulnerabilities from cache.
	$wpvulnerability_test_core_counter = json_decode( get_site_option( 'wpvulnerability-core-vulnerable' ) );
	if ( ! is_numeric( $wpvulnerability_test_core_counter ) ) {
		$wpvulnerability_test_core_counter = 0;
	}
	/* translators: Show the number of vulnerabilities in a WP-Admin dashboard */
	$msg_core = sprintf( _n( 'Core: %d vulnerability', 'Core: %d vulnerabilities', $wpvulnerability_test_core_counter, 'wpvulnerability' ), $wpvulnerability_test_core_counter );

	// Get the number of themes vulnerabilities from cache.
	$wpvulnerability_test_themes_counter = json_decode( get_site_option( 'wpvulnerability-themes-vulnerable' ) );
	if ( ! is_numeric( $wpvulnerability_test_themes_counter ) ) {
		$wpvulnerability_test_themes_counter = 0;
	}
	/* translators: Show the number of vulnerabilities in a WP-Admin dashboard */
	$msg_themes = sprintf( _n( 'Themes: %d vulnerability', 'Themes: %d vulnerabilities', $wpvulnerability_test_themes_counter, 'wpvulnerability' ), $wpvulnerability_test_themes_counter );

	// Get the number of plugins vulnerabilities from cache.
	$wpvulnerability_test_plugins_counter = json_decode( get_site_option( 'wpvulnerability-plugins-vulnerable' ) );
	if ( ! is_numeric( $wpvulnerability_test_plugins_counter ) ) {
		$wpvulnerability_test_plugins_counter = 0;
	}
	/* translators: Show the number of vulnerabilities in a WP-Admin dashboard */
	$msg_plugins = sprintf( _n( 'Plugins: %d vulnerability', 'Plugins: %d vulnerabilities', $wpvulnerability_test_plugins_counter, 'wpvulnerability' ), $wpvulnerability_test_plugins_counter );

	// Get the number of PHP vulnerabilities from cache.
	$wpvulnerability_test_php_counter = json_decode( get_site_option( 'wpvulnerability-php-vulnerable' ) );
	if ( ! is_numeric( $wpvulnerability_test_php_counter ) ) {
		$wpvulnerability_test_php_counter = 0;
	}
	$wpvulnerability_test_php_version = wpvulnerability_detect_php();
	/* translators: Show the number of vulnerabilities in a WP-Admin dashboard */
	$msg_php = sprintf( __( 'PHP %s: ', 'wpvulnerability' ), $wpvulnerability_test_php_version ) . sprintf( _n( '%d vulnerability', '%d vulnerabilities', $wpvulnerability_test_php_counter, 'wpvulnerability' ), $wpvulnerability_test_php_counter );

	// Get the number of Apache HTTPD vulnerabilities from cache.
	$show_apache = false;
	$msg_apache  = null;
	$webserver   = wpvulnerability_detect_webserver();
	if ( isset( $webserver['id'] ) && 'apache' === $webserver['id'] && isset( $webserver['version'] ) && $webserver['version'] ) {
		// Get the Apache HTTPD version.
		$apache_version                      = wp_kses( (string) $webserver['version'], 'strip' );
		$wpvulnerability_test_apache_counter = json_decode( get_site_option( 'wpvulnerability-apache-vulnerable' ) );
		if ( ! is_numeric( $wpvulnerability_test_apache_counter ) ) {
			$wpvulnerability_test_apache_counter = 0;
		}
		$wpvulnerability_test_apache_version = wpvulnerability_sanitize_and_validate_version( $apache_version );
		$show_apache                         = true;
		/* translators: Show the number of vulnerabilities in a WP-Admin dashboard */
		$msg_apache = sprintf( __( 'Apache %s: ', 'wpvulnerability' ), $wpvulnerability_test_apache_version ) . sprintf( _n( '%d vulnerability', '%d vulnerabilities', $wpvulnerability_test_apache_counter, 'wpvulnerability' ), $wpvulnerability_test_apache_counter );
	}

	// Get the number of nginx vulnerabilities from cache.
	$show_nginx = false;
	$msg_nginx  = null;
	$webserver  = wpvulnerability_detect_webserver();
	if ( isset( $webserver['id'] ) && 'nginx' === $webserver['id'] && isset( $webserver['version'] ) && $webserver['version'] ) {
		// Get the nginx version.
		$nginx_version                      = wp_kses( (string) $webserver['version'], 'strip' );
		$wpvulnerability_test_nginx_counter = json_decode( get_site_option( 'wpvulnerability-nginx-vulnerable' ) );
		if ( ! is_numeric( $wpvulnerability_test_nginx_counter ) ) {
			$wpvulnerability_test_nginx_counter = 0;
		}
		$wpvulnerability_test_nginx_version = wpvulnerability_sanitize_and_validate_version( $nginx_version );
		$show_nginx                         = true;
		/* translators: Show the number of vulnerabilities in a WP-Admin dashboard */
		$msg_nginx = sprintf( __( 'nginx %s: ', 'wpvulnerability' ), $wpvulnerability_test_nginx_version ) . sprintf( _n( '%d vulnerability', '%d vulnerabilities', $wpvulnerability_test_nginx_counter, 'wpvulnerability' ), $wpvulnerability_test_nginx_counter );
	}

	// Get the number of MariaDB vulnerabilities from cache.
	$show_mariadb = false;
	$msg_mariadb  = null;
	$sqlserver    = wpvulnerability_detect_sqlserver();
	if ( isset( $sqlserver['id'] ) && 'mariadb' === $sqlserver['id'] && isset( $sqlserver['version'] ) && $sqlserver['version'] ) {
		// Get the MariaDB version.
		$mariadb_version                      = wp_kses( (string) $sqlserver['version'], 'strip' );
		$wpvulnerability_test_mariadb_counter = json_decode( get_site_option( 'wpvulnerability-mariadb-vulnerable' ) );
		if ( ! is_numeric( $wpvulnerability_test_mariadb_counter ) ) {
			$wpvulnerability_test_mariadb_counter = 0;
		}
		$wpvulnerability_test_mariadb_version = wpvulnerability_sanitize_and_validate_version( $mariadb_version );
		$show_mariadb                         = true;
		/* translators: Show the number of vulnerabilities in a WP-Admin dashboard */
		$msg_mariadb = sprintf( __( 'MariaDB %s: ', 'wpvulnerability' ), $wpvulnerability_test_mariadb_version ) . sprintf( _n( '%d vulnerability', '%d vulnerabilities', $wpvulnerability_test_mariadb_counter, 'wpvulnerability' ), $wpvulnerability_test_mariadb_counter );
	}

	// Get the number of MySQL vulnerabilities from cache.
	$show_mysql = false;
	$msg_mysql  = null;
	$sqlserver  = wpvulnerability_detect_sqlserver();
	if ( isset( $sqlserver['id'] ) && 'mysql' === $sqlserver['id'] && isset( $sqlserver['version'] ) && $sqlserver['version'] ) {
		// Get the MySQL version.
		$mysql_version                      = wp_kses( (string) $sqlserver['version'], 'strip' );
		$wpvulnerability_test_mysql_counter = json_decode( get_site_option( 'wpvulnerability-mysql-vulnerable' ) );
		if ( ! is_numeric( $wpvulnerability_test_mysql_counter ) ) {
			$wpvulnerability_test_mysql_counter = 0;
		}
		$wpvulnerability_test_mysql_version = wpvulnerability_sanitize_and_validate_version( $mysql_version );
		$show_mysql                         = true;
		/* translators: Show the number of vulnerabilities in a WP-Admin dashboard */
		$msg_mysql = sprintf( __( 'MySQL %s: ', 'wpvulnerability' ), $wpvulnerability_test_mysql_version ) . sprintf( _n( '%d vulnerability', '%d vulnerabilities', $wpvulnerability_test_mysql_counter, 'wpvulnerability' ), $wpvulnerability_test_mysql_counter );
	}

	// Get the number of ImageMagick vulnerabilites from cache.
	$msg_imagemagick     = null;
	$show_imagemagick    = false;
	$version_imagemagick = wpvulnerability_get_software_version( 'imagemagick' );
	if ( $version_imagemagick ) {
		$show_imagemagick                         = true;
		$wpvulnerability_test_imagemagick_counter = json_decode( get_site_option( 'wpvulnerability-imagemagick-vulnerable' ) );
		if ( ! is_numeric( $wpvulnerability_test_imagemagick_counter ) ) {
			$wpvulnerability_test_imagemagick_counter = 0;
		}
		$wpvulnerability_test_imagemagick_version = wpvulnerability_sanitize_and_validate_version( $version_imagemagick );
		/* translators: Show the number of vulnerabilities in a WP-Admin dashboard */
		$msg_imagemagick = sprintf( __( 'ImageMagick %s: ', 'wpvulnerability' ), $wpvulnerability_test_imagemagick_version ) . sprintf( _n( '%d vulnerability', '%d vulnerabilities', $wpvulnerability_test_imagemagick_counter, 'wpvulnerability' ), $wpvulnerability_test_imagemagick_counter );
	}

	// Get the number of curl vulnerabilites from cache.
	$msg_curl     = null;
	$show_curl    = false;
	$version_curl = wpvulnerability_get_software_version( 'curl' );
	if ( $version_curl ) {
		$show_curl                         = true;
		$wpvulnerability_test_curl_counter = json_decode( get_site_option( 'wpvulnerability-curl-vulnerable' ) );
		if ( ! is_numeric( $wpvulnerability_test_curl_counter ) ) {
			$wpvulnerability_test_curl_counter = 0;
		}
		$wpvulnerability_test_curl_version = wpvulnerability_sanitize_and_validate_version( $version_curl );
		/* translators: Show the number of vulnerabilities in a WP-Admin dashboard */
		$msg_curl = sprintf( __( 'curl %s: ', 'wpvulnerability' ), $wpvulnerability_test_curl_version ) . sprintf( _n( '%d vulnerability', '%d vulnerabilities', $wpvulnerability_test_curl_counter, 'wpvulnerability' ), $wpvulnerability_test_curl_counter );
	}

	// Get the number of memcached vulnerabilites from cache.
	$msg_memcached     = null;
	$show_memcached    = false;
	$version_memcached = wpvulnerability_get_software_version( 'memcached' );
	if ( $version_memcached ) {
		$show_memcached                         = true;
		$wpvulnerability_test_memcached_counter = json_decode( get_site_option( 'wpvulnerability-memcached-vulnerable' ) );
		if ( ! is_numeric( $wpvulnerability_test_memcached_counter ) ) {
			$wpvulnerability_test_memcached_counter = 0;
		}
		$wpvulnerability_test_memcached_version = wpvulnerability_sanitize_and_validate_version( $version_memcached );
		/* translators: Show the number of vulnerabilities in a WP-Admin dashboard */
		$msg_memcached = sprintf( __( 'memcached %s: ', 'wpvulnerability' ), $wpvulnerability_test_memcached_version ) . sprintf( _n( '%d vulnerability', '%d vulnerabilities', $wpvulnerability_test_memcached_counter, 'wpvulnerability' ), $wpvulnerability_test_memcached_counter );
	}

	// Get the number of Redis vulnerabilites from cache.
	$msg_redis     = null;
	$show_redis    = false;
	$version_redis = wpvulnerability_get_software_version( 'redis' );
	if ( $version_redis ) {
		$show_redis                         = true;
		$wpvulnerability_test_redis_counter = json_decode( get_site_option( 'wpvulnerability-redis-vulnerable' ) );
		if ( ! is_numeric( $wpvulnerability_test_redis_counter ) ) {
			$wpvulnerability_test_redis_counter = 0;
		}
		$wpvulnerability_test_redis_version = wpvulnerability_sanitize_and_validate_version( $version_redis );
		/* translators: Show the number of vulnerabilities in a WP-Admin dashboard */
		$msg_redis = sprintf( __( 'Redis %s: ', 'wpvulnerability' ), $wpvulnerability_test_redis_version ) . sprintf( _n( '%d vulnerability', '%d vulnerabilities', $wpvulnerability_test_redis_counter, 'wpvulnerability' ), $wpvulnerability_test_redis_counter );
	}

	// Get the number of SQLite vulnerabilites from cache.
	$msg_sqlite     = null;
	$show_sqlite    = false;
	$version_sqlite = wpvulnerability_get_software_version( 'sqlite' );
	if ( $version_sqlite ) {
		$show_sqlite                         = true;
		$wpvulnerability_test_sqlite_counter = json_decode( get_site_option( 'wpvulnerability-sqlite-vulnerable' ) );
		if ( ! is_numeric( $wpvulnerability_test_sqlite_counter ) ) {
			$wpvulnerability_test_sqlite_counter = 0;
		}
		$wpvulnerability_test_sqlite_version = wpvulnerability_sanitize_and_validate_version( $version_sqlite );
		/* translators: Show the number of vulnerabilities in a WP-Admin dashboard */
		$msg_sqlite = sprintf( __( 'SQLite %s: ', 'wpvulnerability' ), $wpvulnerability_test_sqlite_version ) . sprintf( _n( '%d vulnerability', '%d vulnerabilities', $wpvulnerability_test_sqlite_counter, 'wpvulnerability' ), $wpvulnerability_test_sqlite_counter );
	}

	// Show the widget.
	echo esc_html( __( 'Vulnerability analysis of your WordPress installation:', 'wpvulnerability' ) );
	echo '<ul>';

	if ( wpvulnerability_analyze_filter( 'core' ) && ! $wpvulnerability_test_core_counter ) {
		echo '<li>🟢 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-wordpress.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_core ) . '</li>';
	} elseif ( wpvulnerability_analyze_filter( 'core' ) ) {
		echo '<li>🔴 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-wordpress.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_core ) . '</li>';
	}

	if ( wpvulnerability_analyze_filter( 'plugins' ) && ! $wpvulnerability_test_plugins_counter ) {
		echo '<li>🟢 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-plugin.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_plugins ) . '</li>';
	} elseif ( wpvulnerability_analyze_filter( 'plugins' ) ) {
		echo '<li>🔴 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-plugin.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_plugins );
		echo wpvulnerability_list_plugins(); // phpcs:ignore
		echo '</li>';
	}

	if ( wpvulnerability_analyze_filter( 'themes' ) && ! $wpvulnerability_test_themes_counter ) {
		echo '<li>🟢 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-theme.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_themes ) . '</li>';
	} elseif ( wpvulnerability_analyze_filter( 'themes' ) ) {
		echo '<li>🔴 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-theme.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_themes );
		echo wpvulnerability_list_themes(); // phpcs:ignore
		echo '</li>';
	}

	if ( wpvulnerability_analyze_filter( 'php' ) && ! $wpvulnerability_test_php_counter ) {
		echo '<li>🟢 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-php.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_php ) . '</li>';
	} elseif ( wpvulnerability_analyze_filter( 'php' ) ) {
		echo '<li>🔴 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-php.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_php ) . '</li>';
	}

	if ( $show_apache ) {
		if ( wpvulnerability_analyze_filter( 'apache' ) && ! $wpvulnerability_test_apache_counter ) {
			echo '<li>🟢 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-apache.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_apache ) . '</li>';
		} elseif ( wpvulnerability_analyze_filter( 'apache' ) ) {
			echo '<li>🔴 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-apache.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_apache ) . '</li>';
		}
	}

	if ( $show_nginx ) {
		if ( wpvulnerability_analyze_filter( 'nginx' ) && ! $wpvulnerability_test_nginx_counter ) {
			echo '<li>🟢 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-nginx.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_nginx ) . '</li>';
		} elseif ( wpvulnerability_analyze_filter( 'nginx' ) ) {
			echo '<li>🔴 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-nginx.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_nginx ) . '</li>';
		}
	}

	if ( $show_mariadb ) {
		if ( wpvulnerability_analyze_filter( 'mariadb' ) && ! $wpvulnerability_test_mariadb_counter ) {
			echo '<li>🟢 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-mariadb.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_mariadb ) . '</li>';
		} elseif ( wpvulnerability_analyze_filter( 'mariadb' ) ) {
			echo '<li>🔴 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-mariadb.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_mariadb ) . '</li>';
		}
	}

	if ( $show_mysql ) {
		if ( wpvulnerability_analyze_filter( 'mysql' ) && ! $wpvulnerability_test_mysql_counter ) {
			echo '<li>🟢 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-mysql.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_mysql ) . '</li>';
		} elseif ( wpvulnerability_analyze_filter( 'mysql' ) ) {
			echo '<li>🔴 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-mysql.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_mysql ) . '</li>';
		}
	}

	if ( $show_imagemagick ) {
		if ( wpvulnerability_analyze_filter( 'imagemagick' ) && ! $wpvulnerability_test_imagemagick_counter ) {
			echo '<li>🟢 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-imagemagick.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_imagemagick ) . '</li>';
		} elseif ( wpvulnerability_analyze_filter( 'imagemagick' ) ) {
			echo '<li>🔴 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-imagemagick.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_imagemagick ) . '</li>';
		}
	}

	if ( $show_curl ) {
		if ( wpvulnerability_analyze_filter( 'curl' ) && ! $wpvulnerability_test_curl_counter ) {
			echo '<li>🟢 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-curl.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_curl ) . '</li>';
		} elseif ( wpvulnerability_analyze_filter( 'curl' ) ) {
			echo '<li>🔴 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-curl.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_curl ) . '</li>';
		}
	}

	if ( $show_memcached ) {
		if ( wpvulnerability_analyze_filter( 'memcached' ) && ! $wpvulnerability_test_memcached_counter ) {
			echo '<li>🟢 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-memcached.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_memcached ) . '</li>';
		} elseif ( wpvulnerability_analyze_filter( 'memcached' ) ) {
			echo '<li>🔴 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-memcached.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_memcached ) . '</li>';
		}
	}

	if ( $show_redis ) {
		if ( wpvulnerability_analyze_filter( 'redis' ) && ! $wpvulnerability_test_redis_counter ) {
			echo '<li>🟢 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-redis.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_redis ) . '</li>';
		} elseif ( wpvulnerability_analyze_filter( 'redis' ) ) {
			echo '<li>🔴 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-redis.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_redis ) . '</li>';
		}
	}

	if ( $show_sqlite ) {
		if ( wpvulnerability_analyze_filter( 'sqlite' ) && ! $wpvulnerability_test_sqlite_counter ) {
			echo '<li>🟢 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-sqlite.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_sqlite ) . '</li>';
		} elseif ( wpvulnerability_analyze_filter( 'sqlite' ) ) {
			echo '<li>🔴 <img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/icon-sqlite.svg" width="12" height="12" alt=""> ' . esc_html( (string) $msg_sqlite ) . '</li>';
		}
	}

	echo '</ul>';

	if ( version_compare( get_bloginfo( 'version' ), '5.2', '>=' ) ) {
		echo esc_html( __( 'More information? Visit', 'wpvulnerability' ) ) . ' <a href="' . esc_url( get_admin_url( null, 'site-health.php' ) ) . '">' . esc_html( __( 'Site Health', 'wpvulnerability' ) ) . '</a>';
	}

	unset( $wpvulnerability_test_core_counter, $wpvulnerability_test_themes_counter, $wpvulnerability_test_plugins_counter );
}

/**
 * Created a widget in the WordPress dashboard with vulnerability info.
 *
 * @since 2.2.0
 *
 * @return void
 */
function wpvulnerability_admin_dashboard() {

	if ( wpvulnerability_capabilities() ) {
		wp_add_dashboard_widget(
			'wpvulnerability',
			__( 'WPVulnerability Status', 'wpvulnerability' ),
			'wpvulnerability_admin_dashboard_content',
			null,
			null,
			'side',
			'high'
		);
	}
}
add_action( 'wp_network_dashboard_setup', 'wpvulnerability_admin_dashboard' );

/**
 * Strictly sanitizes the main configuration (emails and periods).
 *
 * @param array $input Input values.
 * @return array Sanitized values.
 */
function wpvulnerability_sanitize_config( $input ) {
				$sanitized = array();

				// Emails (comma-separated list).
	if ( isset( $input['emails'] ) ) {
			$emails_raw       = explode( ',', $input['emails'] );
			$sanitized_emails = array();

		foreach ( $emails_raw as $email ) {
				$email = sanitize_email( trim( $email ) );
			if ( is_email( $email ) ) {
					$sanitized_emails[] = $email;
			}
		}

			$sanitized['emails'] = implode( ',', $sanitized_emails );
	}

				// Period (daily, weekly, monthly, never).
				$allowed_periods = array( 'daily', 'weekly', 'monthly', 'never' );
	if ( isset( $input['period'] ) && in_array( $input['period'], $allowed_periods, true ) ) {
					$sanitized['period'] = $input['period'];
	} else {
					$sanitized['period'] = 'weekly';
	}

				// Day of week for weekly schedule.
				$sanitized['day'] = 'monday';
	if ( isset( $input['day'] ) ) {
					$day              = strtolower( $input['day'] );
					$valid            = array( 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday' );
					$sanitized['day'] = in_array( $day, $valid, true ) ? $day : 'monday';
	}

		// Time (hour and minute).
		$sanitized['hour']   = 0;
		$sanitized['minute'] = 0;
	if ( isset( $input['hour'] ) ) {
					$hour              = (int) $input['hour'];
					$sanitized['hour'] = max( 0, min( 23, $hour ) );
	}
	if ( isset( $input['minute'] ) ) {
					$minute              = (int) $input['minute'];
					$sanitized['minute'] = max( 0, min( 59, $minute ) );
	}

		// Cache expiration.
		$sanitized['cache'] = 12;
	if ( isset( $input['cache'] ) ) {
					$cache              = (int) $input['cache'];
					$sanitized['cache'] = in_array( $cache, array( 1, 6, 12, 24 ), true ) ? $cache : 12;
	}

		// Notification methods.
			$sanitized['notify'] = array(
				'email' => 'n',
				'slack' => 'n',
				'teams' => 'n',
			);
			if ( isset( $input['notify'] ) && is_array( $input['notify'] ) ) {
							$notify_input        = array_map( 'sanitize_text_field', (array) wp_unslash( $input['notify'] ) );
							$sanitized['notify'] = wpvulnerability_normalize_notify_settings( $notify_input );
			}

			// Webhooks.
			if ( isset( $input['slack_webhook'] ) ) {
				$sanitized['slack_webhook'] = esc_url_raw( trim( $input['slack_webhook'] ) );
			}

			if ( isset( $input['teams_webhook'] ) ) {
				$sanitized['teams_webhook'] = esc_url_raw( trim( $input['teams_webhook'] ) );
			}

			return $sanitized;
}

/**
 * Sanitizes the messages generated by the plugin (simple messages).
 *
 * @param array $input Input values.
 * @return array Sanitized values.
 */
function wpvulnerability_sanitize_messages( $input ) {
	$sanitized = array();

	foreach ( $input as $key => $message ) {
		$sanitized[ sanitize_key( $key ) ] = sanitize_text_field( $message );
	}

	return $sanitized;
}

/**
 * Strictly sanitizes the analysis options (booleans).
 *
 * @param array $input Input values.
 * @return array Sanitized values.
 */
function wpvulnerability_sanitize_analyze( $input ) {
	$components = array(
		'core',
		'plugins',
		'themes',
		'php',
		'apache',
		'nginx',
		'mariadb',
		'mysql',
		'imagemagick',
		'curl',
		'memcached',
		'redis',
		'sqlite',
	);

	$sanitized = array();

	foreach ( $components as $component ) {
		$sanitized[ $component ] = isset( $input[ $component ] ) ? (bool) $input[ $component ] : false;

		$constant = 'WPVULNERABILITY_HIDE_' . strtoupper( $component );
		if ( defined( $constant ) && constant( $constant ) ) {
			$sanitized[ $component ] = true;
		}
	}

	return $sanitized;
}

/**
 * Initializes the WP-Admin settings page for the WP Vulnerability plugin.
 *
 * @since 2.0.0
 *
 * @return void
 */
function wpvulnerability_admin_init() {

	// Register the plugin settings to be saved in the database.
	register_setting(
		'admin_wpvulnerability_settings',
		'wpvulnerability-config',
		array(
			'sanitize_callback' => 'wpvulnerability_sanitize_config',
			'default'           => array(),
			'show_in_rest'      => false,
			'type'              => 'array',
		)
	);

	// Register messages.
	register_setting(
		'admin_wpvulnerability_settings',
		'wpvulnerability-messages',
		array(
			'sanitize_callback' => 'wpvulnerability_sanitize_messages',
			'default'           => array(),
			'show_in_rest'      => false,
			'type'              => 'array',
		)
	);

	// Add a section to the settings page.
		add_settings_section(
			'admin_wpvulnerability_settings',
			__( 'Receive vulnerability notifications', 'wpvulnerability' ),
			'wpvulnerability_admin_section_notifications',
			'wpvulnerability-config'
		);

		// Add a field to the settings page for the cache expiration time.
		add_settings_field(
			'wpvulnerability_cache',
			__( 'Cache expiration time', 'wpvulnerability' ),
			'wpvulnerability_admin_cache_callback',
			'wpvulnerability-config',
			'admin_wpvulnerability_settings'
		);

		// Add a field to the settings page for the notification period.
		add_settings_field(
			'wpvulnerability_period',
			__( 'How often you want to receive notifications', 'wpvulnerability' ),
			'wpvulnerability_admin_period_callback',
			'wpvulnerability-config',
			'admin_wpvulnerability_settings'
		);

				// Add a field for notification methods.
				add_settings_field(
					'wpvulnerability_notify',
					__( 'Where do you want to receive notifications?', 'wpvulnerability' ),
					'wpvulnerability_admin_notify_callback',
					'wpvulnerability-config',
					'admin_wpvulnerability_settings'
				);

		// Add a field to the settings page for the email addresses.
		add_settings_field(
			'wpvulnerability_emails',
			__( 'Email addresses to notify (separated by commas)', 'wpvulnerability' ),
			'wpvulnerability_admin_emails_callback',
			'wpvulnerability-config',
			'admin_wpvulnerability_settings'
		);

				// Add a field for the Slack webhook.
				add_settings_field(
					'wpvulnerability_slack_webhook',
					__( 'Slack webhook URL', 'wpvulnerability' ),
					'wpvulnerability_admin_slack_callback',
					'wpvulnerability-config',
					'admin_wpvulnerability_settings'
				);

				// Add a field for the Teams webhook.
				add_settings_field(
					'wpvulnerability_teams_webhook',
					__( 'Teams webhook URL', 'wpvulnerability' ),
					'wpvulnerability_admin_teams_callback',
					'wpvulnerability-config',
					'admin_wpvulnerability_settings'
				);

	// Register the plugin settings to be saved in the database.
	register_setting(
		'admin_wpvulnerability_analyze',
		'wpvulnerability-analyze',
		array(
			'sanitize_callback' => 'wpvulnerability_sanitize_analyze',
			'default'           => array(),
			'show_in_rest'      => false,
			'type'              => 'array',
		)
	);

	// Add a section to the settings page.
	add_settings_section(
		'admin_wpvulnerability_analyze',
		__( 'Vulnerabilities to hide', 'wpvulnerability' ),
		'wpvulnerability_admin_section_analyze',
		'wpvulnerability-analyze'
	);

	// Add a field to the settings page for analyzing components.
	add_settings_field(
		'wpvulnerability_analyze',
		__( 'What do you want to hide?', 'wpvulnerability' ),
		'wpvulnerability_admin_analyze_callback',
		'wpvulnerability-analyze',
		'admin_wpvulnerability_analyze'
	);
}
add_action( 'admin_init', 'wpvulnerability_admin_init' );