As the sun rises and the forest mist clears, and the clouds return and the caves darken, these changes of light and shadow are the morning and evening in the mountains. Wildflowers bloom with their subtle fragrance, fine trees flourish with their dense shade, the wind and frost are pure and clean, and the water recedes to reveal the rocks—these are the four seasons in the mountains. Going out in the morning and returning in the evening, the scenery of the four seasons is different, and the joy is endless.至于负者歌于途,行者休于树,前者呼,后者应,伛偻提携,往来而不绝者,滁人游也。临溪而渔,溪深而鱼肥,酿泉为酒,泉香而酒洌,山肴野蔌,杂然而前陈者,太守宴也。宴酣之乐,非丝非竹,射者中,弈者胜,觥筹交错,起坐而喧哗者,众宾欢也。苍颜白发,颓然乎其间者,太守醉也。 HEX
HEX
Server: Apache
System: Linux webd003.cluster106.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64
User: labeautef (51223)
PHP: 8.0.30
Disabled: _dyuweyrj4,_dyuweyrj4r,dl
Upload Files
File: /home/labeautef/rochasson-risoul.com/wp-content/plugins/disable-comments/disable-comments.php
<?php

/**
 * Plugin Name: Disable Comments
 * Plugin URI: https://wordpress.org/plugins/disable-comments/
 * Description: Allows administrators to globally disable comments on their site. Comments can be disabled according to post type. You could bulk delete comments using Tools.
 * Version: 2.6.2
 * Author: WPDeveloper
 * Author URI: https://wpdeveloper.com
 * License: GPL-3.0+
 * License URI: https://www.gnu.org/licenses/gpl-3.0.html
 * Text Domain: disable-comments
 * Domain Path: /languages/
 *
 * @package Disable_Comments
 */

if (!defined('ABSPATH')) {
	exit;
}

class Disable_Comments {
	const DB_VERSION         = 8;
	private static $instance = null;
	private $options;
	public  $networkactive;
	public  $tracker;
	public  $is_CLI;
	public  $sitewide_settings;
	public  $setup_notice_flag;
	private $modified_types = array();

	public static function get_instance() {
		if (is_null(self::$instance)) {
			self::$instance = new self;
		}
		return self::$instance;
	}

	function __construct() {
		define('DC_VERSION', '2.6.2');
		define('DC_PLUGIN_SLUG', 'disable_comments_settings');
		define('DC_PLUGIN_ROOT_PATH', dirname(__FILE__));
		define('DC_PLUGIN_VIEWS_PATH', DC_PLUGIN_ROOT_PATH . '/views/');
		define('DC_PLUGIN_ROOT_URI', plugins_url("/", __FILE__));
		define('DC_ASSETS_URI', DC_PLUGIN_ROOT_URI . 'assets/');

		// save settings
		add_action('wp_ajax_disable_comments_save_settings', array($this, 'disable_comments_settings'));
		add_action('wp_ajax_disable_comments_delete_comments', array($this, 'delete_comments_settings'));
		add_action('wp_ajax_get_sub_sites', array($this, 'get_sub_sites'));

		// Including cli.php
		if (defined('WP_CLI') && WP_CLI) {
			add_action('init', array($this, 'enable_cli'), 9999);
		}

		// are we network activated?
		$this->networkactive = (is_multisite() && array_key_exists(plugin_basename(__FILE__), (array) get_site_option('active_sitewide_plugins')));
		$this->is_CLI = defined('WP_CLI') && WP_CLI;

		$this->sitewide_settings = get_site_option('disable_comments_sitewide_settings', false);
		// Load options.
		if ($this->networkactive && ($this->is_network_admin() || $this->sitewide_settings !== '1')) {
			$this->options = get_site_option('disable_comments_options', array());
			$this->options['disabled_sites'] = $this->get_disabled_sites();

			$blog_id = get_current_blog_id();
			if (
				!$this->is_network_admin() && (
					empty($this->options['disabled_sites']) ||
					// if site disabled
					empty($this->options['disabled_sites']["site_$blog_id"])
				)
			) {
				$this->options = [
					'remove_everywhere' => false,
					'disabled_post_types' => array(),
					'extra_post_types' => array(),
					'disabled_sites' => array(),
					'remove_xmlrpc_comments' => 0,
					'remove_rest_API_comments' => 0,
					'show_existing_comments' => false,
					'allowed_comment_types' => array(),
					'settings_saved' => true,
					'db_version' => $this->options['db_version']
				];
			}
		} else {
			$this->options = get_option('disable_comments_options', array());
			$not_configured = empty($this->options) || empty($this->options['settings_saved']);

			if (is_multisite() && $not_configured && $this->sitewide_settings == '1') {
				$this->options = get_site_option('disable_comments_options', array());
				$this->options['is_network_options'] = true;
			}
		}


		// If it looks like first run, check compat.
		if (empty($this->options)) {
			$this->check_compatibility();
		}

		$this->options['sitewide_settings'] = ($this->sitewide_settings == '1');

		// Upgrade DB if necessary.
		$this->check_db_upgrades();
		$this->check_upgrades();

		add_action('plugins_loaded', [$this, 'init_filters']);
		add_action('wp_loaded', [$this, 'start_plugin_usage_tracking']);

		// Add Site Health integration
		add_filter('debug_information', array($this, 'add_site_health_info'));
	}

	public function is_network_admin() {
		$sanitized_referer = isset($_SERVER['HTTP_REFERER']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_REFERER'])) : '';
		if (is_network_admin() || !empty($sanitized_referer) && defined('DOING_AJAX') && DOING_AJAX && is_multisite() && preg_match('#^' . network_admin_url() . '#i', $sanitized_referer)) {
			return true;
		}
		return false;
	}
	/**
	 * Enable CLI
	 * @since 2.0.0
	 */
	public function enable_cli() {
		require_once DC_PLUGIN_ROOT_PATH . "/includes/cli.php";
		new Disable_Comment_Command($this);
	}

	public function admin_notice() {
		if ($this->tracker instanceof DisableComments_Plugin_Tracker) {
			if (isset($this->setup_notice_flag) && $this->setup_notice_flag === true) {
				return;
			}
			$current_screen = get_current_screen()->id;
			$has_caps = $this->networkactive && is_network_admin() ? current_user_can('manage_network_plugins') : current_user_can('manage_options');
			// if( ! in_array( $current_screen, ['settings_page_disable_comments_settings', 'settings_page_disable_comments_settings-network']) && $has_caps ) {
			if ($has_caps && in_array($current_screen, ['dashboard-network', 'dashboard'])) {
				$this->tracker->notice();
			}
		}
	}

	public function start_plugin_usage_tracking() {
		if ($this->networkactive && !$this->options['sitewide_settings']) {
			$this->tracker = null;
			return;
		}
		if (!class_exists('DisableComments_Plugin_Tracker')) {
			include_once(DC_PLUGIN_ROOT_PATH . '/includes/class-plugin-usage-tracker.php');
		}
		$tracker = $this->tracker = DisableComments_Plugin_Tracker::get_instance(__FILE__, [
			'opt_in' => true,
			'goodbye_form' => true,
			'item_id' => 'b0112c9030af6ba53de4'
		]);
		$tracker->set_notice_options(array(
			'notice' => __('Want to help make Disable Comments even better?', 'disable-comments'),
			'extra_notice' => __('We collect non-sensitive diagnostic data and plugin usage information. Your site URL, WordPress & PHP version, plugins & themes and email address to send you the discount coupon. This data lets us make sure this plugin always stays compatible with the most popular plugins and themes. No spam, I promise.', 'disable-comments'),
		));
		$tracker->init();
	}

	private function check_compatibility() {
		if (version_compare($GLOBALS['wp_version'], '4.7', '<')) {
			require_once(ABSPATH . 'wp-admin/includes/plugin.php');
			deactivate_plugins(__FILE__);

			// @phpcs:ignore WordPress.Security.NonceVerification.Recommended
			if (isset($_GET['action']) && ($_GET['action'] == 'activate' || $_GET['action'] == 'error_scrape')) {
				// translators: %s: WordPress version no.
				exit(sprintf(esc_html__('Disable Comments requires WordPress version %s or greater.', 'disable-comments'), '4.7'));
			}
		}
	}

	private function check_db_upgrades() {
		$old_ver = isset($this->options['db_version']) ? $this->options['db_version'] : 0;
		if ($old_ver < self::DB_VERSION) {
			if ($this->networkactive) {
				$this->options['is_network_admin'] = true;
			}
			if ($old_ver < 2) {
				// upgrade options from version 0.2.1 or earlier to 0.3.
				$this->options['disabled_post_types'] = get_option('disable_comments_post_types', array());
				delete_option('disable_comments_post_types');
			}
			if ($old_ver < 5) {
				// simple is beautiful - remove multiple settings in favour of one.
				$this->options['remove_everywhere'] = isset($this->options['remove_admin_menu_comments']) ? $this->options['remove_admin_menu_comments'] : false;
				foreach (array('remove_admin_menu_comments', 'remove_admin_bar_comments', 'remove_recent_comments', 'remove_discussion', 'remove_rc_widget') as $v) {
					unset($this->options[$v]);
				}
			}
			if ($old_ver < 7 && function_exists('get_sites')) {
				$this->options['disabled_sites'] = [];
				$dc_options = get_site_option('disable_comments_options', array());

				foreach (get_sites(['number' => 0, 'fields' => 'ids']) as $blog_id) {
					if (isset($dc_options['disabled_sites'])) {
						$this->options['disabled_sites']["site_$blog_id"] = in_array($blog_id, $dc_options['disabled_sites']);
					} else {
						$this->options['disabled_sites']["site_$blog_id"] = true;
					}
				}
				$this->options['disabled_sites'] = $this->get_disabled_sites();
			}

			if ($old_ver < 8) {
				// Add new show_existing_comments option with default value false
				// This maintains backward compatibility - existing behavior is preserved
				$this->options['show_existing_comments'] = false;
			}

			foreach (array('remove_everywhere', 'extra_post_types', 'show_existing_comments') as $v) {
				if (!isset($this->options[$v])) {
					$this->options[$v] = false;
				}
			}

			$this->options['db_version'] = self::DB_VERSION;
			$this->update_options();
		}
	}

	public function check_upgrades() {
		$dc_version = get_option('disable_comment_version');
		if (version_compare($dc_version, '2.3.1', '<')) {
			if ($this->is_remove_everywhere()) {
				update_option('show_avatars', true);
			}
		}
		if (!$dc_version || $dc_version != DC_VERSION) {
			update_option('disable_comment_version', DC_VERSION);
		}
	}

	private function update_options() {
		if ($this->networkactive && !empty($this->options['is_network_admin']) && $this->options['is_network_admin']) {
			unset($this->options['is_network_admin']);
			update_site_option('disable_comments_options', $this->options);
		} else {
			update_option('disable_comments_options', $this->options);
		}
	}

	public function get_disabled_sites($default = false) {
		$disabled_sites = ['all' => true];
		foreach (get_sites(['number' => 0, 'fields' => 'ids']) as $blog_id) {
			$disabled_sites["site_{$blog_id}"] = true;
		}
		if ($default) {
			return $disabled_sites;
		}

		$this->options['disabled_sites'] = isset($this->options['disabled_sites']) ? $this->options['disabled_sites'] : [];
		$this->options['disabled_sites'] = wp_parse_args($this->options['disabled_sites'], $disabled_sites);
		$disabled_sites = $this->options['disabled_sites'];
		unset($disabled_sites['all']);
		if (in_array(false, $disabled_sites)) {
			$this->options['disabled_sites']['all'] = false;
		} else {
			$this->options['disabled_sites']['all'] = true;
		}
		return $this->options['disabled_sites'];
	}

	// public function get_disabled_count(){
	// 	$disabled_sites = isset($this->options['disabled_sites']) ? $this->options['disabled_sites'] : [];
	// 	unset($disabled_sites['all']);
	// 	return array_sum($disabled_sites);
	// }

	/**
	 * Get an array of disabled post type.
	 */
	public function get_disabled_post_types() {
		$types = $this->options['disabled_post_types'];
		// Not all extra_post_types might be registered on this particular site.
		if ($this->networkactive && !empty($this->options['extra_post_types'])) {
			foreach ((array) $this->options['extra_post_types'] as $extra) {
				if (post_type_exists($extra)) {
					$types[] = $extra;
				}
			}
		}
		return $types;
	}

	/**
	 * Check whether comments have been disabled on a given post type.
	 */
	private function is_exclude_by_role() {
		if (!empty($this->options['enable_exclude_by_role']) && !empty($this->options['exclude_by_role'])) {
			if (is_user_logged_in()) {
				$user = wp_get_current_user();
				$roles = (array) $user->roles;
				$diff = array_intersect($this->options['exclude_by_role'], $roles);
				if (count($diff) || (in_array("administrator", $this->options['exclude_by_role']) && is_super_admin())) {
					return true;
				}
			} else if (in_array('logged-out-users', $this->options['exclude_by_role'])) {
				return true;
			}
		}
		return false;
	}
	private function is_remove_everywhere() {
		if ($this->is_exclude_by_role()) {
			return false;
		}
		if (isset($this->options['remove_everywhere'])) {
			return $this->options['remove_everywhere'];
		}
		return false;
	}

	/**
	 * Check whether comments have been disabled on a given post type.
	 */
	private function is_post_type_disabled($type) {
		if ($this->is_exclude_by_role()) {
			return false;
		}
		return $type && in_array($type, $this->get_disabled_post_types());
	}

	public function init_filters() {
		// These need to happen now.
		if ($this->is_remove_everywhere()) {
			add_action('widgets_init', array($this, 'disable_rc_widget'));
			add_filter('wp_headers', array($this, 'filter_wp_headers'));
			add_action('template_redirect', array($this, 'filter_query'), 9);   // before redirect_canonical.

			// Admin bar filtering has to happen here since WP 3.6.
			add_action('template_redirect', array($this, 'filter_admin_bar'));
			add_action('admin_init', array($this, 'filter_admin_bar'));

			// Disable Comments REST API Endpoint (but allow notes)
			add_filter('rest_endpoints', array($this, 'filter_rest_endpoints'));
			add_filter('rest_pre_dispatch', array($this, 'filter_rest_comment_dispatch'), 10, 3);
			add_filter('rest_comment_query', array($this, 'filter_rest_comment_query'), 10, 2);
		}

		// remove create comment via xmlrpc
		if (isset($this->options['remove_xmlrpc_comments']) && intval($this->options['remove_xmlrpc_comments']) === 1) {
			add_filter('xmlrpc_methods', array($this, 'disable_xmlrc_comments'));
		}
		// rest API Comment Block (but allow notes)
		if (isset($this->options['remove_rest_API_comments']) && intval($this->options['remove_rest_API_comments']) === 1) {
			add_filter('rest_endpoints', array($this, 'filter_rest_endpoints'));
			add_filter('rest_pre_insert_comment', array($this, 'disable_rest_API_comments'), 10, 2);
			add_filter('rest_pre_dispatch', array($this, 'filter_rest_comment_dispatch'), 10, 3);
			add_filter('rest_comment_query', array($this, 'filter_rest_comment_query'), 10, 2);
		}

		// These can happen later.
		add_action('wp_loaded', array($this, 'init_wploaded_filters'));
		// Disable "Latest comments" block in Gutenberg.
		add_action('enqueue_block_editor_assets', array($this, 'filter_gutenberg_blocks'));
		// settings page assets
		add_action('admin_enqueue_scripts', array($this, 'settings_page_assets'));

		if (!$this->networkactive || $this->options['sitewide_settings']) {
			add_filter('comment_status_links', function ($status_links) {
				$status_links['disable_comments'] = sprintf("<a href='" . $this->settings_page_url() . "'>%s</a>", __("Disable Comments", 'disable-comments'));
				return $status_links;
			});
		}
	}

	public function init_wploaded_filters() {
		$disabled_post_types = $this->get_disabled_post_types();
		if (!empty($disabled_post_types) && !$this->is_exclude_by_role()) {
			foreach ($disabled_post_types as $type) {
				// we need to know what native support was for later.
				if (post_type_supports($type, 'comments')) {
					$this->modified_types[] = $type;
					// Keep comments support if show_existing_comments is enabled
					// or if there are allowed comment types that need to be displayed
					if (empty($this->options['show_existing_comments']) && !$this->has_allowed_comment_types()) {
						remove_post_type_support($type, 'comments');
					}
					remove_post_type_support($type, 'trackbacks');
				}
			}
		} elseif (is_admin() && !$this->is_configured()) {
			/**
			 * It is possible that $disabled_post_types is empty if other
			 * plugins have disabled comments. Hence we also check for
			 * remove_everywhere. If you still get a warning you probably
			 * shouldn't be using this plugin.
			 */
			add_action('all_admin_notices', array($this, 'setup_notice'));
		}

		if ($this->is_remove_everywhere() || (!empty($disabled_post_types) && !$this->is_exclude_by_role())) {
			add_filter('comments_array', array($this, 'filter_existing_comments'), 20, 2);
			add_filter('comments_open', array($this, 'filter_comment_status'), 20, 2);
			add_filter('pings_open', array($this, 'filter_comment_status'), 20, 2);
			add_filter('get_comments_number', array($this, 'filter_comments_number'), 20, 2);
		}

		// Filters for the admin only.
		if (is_admin()) {
			add_action('all_admin_notices', array($this, 'admin_notice'));
			if ($this->networkactive && is_network_admin()) {
				add_action('network_admin_menu', array($this, 'settings_menu'));
				add_action('network_admin_menu', array($this, 'tools_menu'));
				add_filter('network_admin_plugin_action_links', array($this, 'plugin_actions_links'), 10, 2);
			} elseif (!$this->networkactive || $this->options['sitewide_settings']) {
				add_action('admin_menu', array($this, 'settings_menu'));
				add_action('admin_menu', array($this, 'tools_menu'));
				add_filter('plugin_action_links', array($this, 'plugin_actions_links'), 10, 2);
				if (is_multisite()) {    // We're on a multisite setup, but the plugin isn't network activated.
					register_deactivation_hook(__FILE__, array($this, 'single_site_deactivate'));
				}
			}
			add_action('admin_notices', array($this, 'discussion_notice'));
			add_filter('plugin_row_meta', array($this, 'set_plugin_meta'), 10, 2);

			if ($this->is_remove_everywhere()) {
				add_action('admin_menu', array($this, 'filter_admin_menu'), 9999);  // do this as late as possible.
				add_action('admin_print_styles-index.php', array($this, 'admin_css'));
				add_action('admin_print_styles-profile.php', array($this, 'admin_css'));
				add_action('wp_dashboard_setup', array($this, 'filter_dashboard'));
				add_filter('pre_option_default_pingback_flag', '__return_zero');
			}
		}
		// Filters for front end only.
		else {
			add_action('template_redirect', array($this, 'check_comment_template'));

			if ($this->is_remove_everywhere()) {
				add_filter('feed_links_show_comments_feed', '__return_false');
			}
		}
	}

	// public function get_option( $key, $default = false ){
	// 	return $this->networkactive ? get_site_option( $key, $default ) : get_option( $key, $default );
	// }
	// public function update_option( $option, $value ){
	// 	return $this->networkactive ? update_site_option( $option, $value ) : update_option( $option, $value );
	// }
	// public function delete_option( $option ){
	// 	return $this->networkactive ? delete_site_option( $option ) : delete_option( $option );
	// }

	/**
	 * Replace the theme's comment template with a blank one.
	 * To prevent this, define DISABLE_COMMENTS_REMOVE_COMMENTS_TEMPLATE
	 * and set it to True
	 */
	public function check_comment_template() {
		if (is_singular() && ($this->is_remove_everywhere() || $this->is_post_type_disabled(get_post_type()))) {
			if (!defined('DISABLE_COMMENTS_REMOVE_COMMENTS_TEMPLATE') || DISABLE_COMMENTS_REMOVE_COMMENTS_TEMPLATE == true) {
				// Kill the comments template unless:
				// - show_existing_comments is enabled, OR
				// - there are allowed comment types that need to be displayed
				if (empty($this->options['show_existing_comments']) && !$this->has_allowed_comment_types()) {
					add_filter('comments_template', array($this, 'dummy_comments_template'), 20);
				}
			}
			// Remove comment-reply script for themes that include it indiscriminately.
			wp_deregister_script('comment-reply');
			// feed_links_extra inserts a comments RSS link.
			remove_action('wp_head', 'feed_links_extra', 3);
		}
	}

	public function dummy_comments_template() {
		return dirname(__FILE__) . '/views/comments.php';
	}

	public function is_xmlrpc_rest() {
		// remove create comment via xmlrpc
		if (isset($this->options['remove_xmlrpc_comments']) && intval($this->options['remove_xmlrpc_comments']) === 1) {
			return true;
		}
		// rest API Comment Block
		if (isset($this->options['remove_rest_API_comments']) && intval($this->options['remove_rest_API_comments']) === 1) {
			return true;
		}
		return false;
	}

	/**
	 * Remove the X-Pingback HTTP header
	 */
	public function filter_wp_headers($headers) {
		unset($headers['X-Pingback']);
		return $headers;
	}

	/**
	 * remove method wp.newComment
	 */
	public function disable_xmlrc_comments($methods) {
		unset($methods['wp.newComment']);
		return $methods;
	}

	public function disable_rest_API_comments($prepared_comment, $request) {
		// Allow comment types in the allowlist (e.g., WordPress 6.9+ block notes)
		if ($this->is_allowed_comment_type_request($request)) {
			return $prepared_comment;
		}
		return;
	}

	/**
	 * Get the list of allowed comment types from settings
	 *
	 * @return array Array of allowed comment types
	 */
	private function get_allowed_comment_types() {
		if (!isset($this->options['allowed_comment_types']) || !is_array($this->options['allowed_comment_types'])) {
			return array(); // Default: all special comment types disabled
		}
		return $this->options['allowed_comment_types'];
	}

	/**
	 * Check if any comment types are enabled in the allowlist
	 *
	 * @return bool True if there are allowed comment types, false otherwise
	 */
	private function has_allowed_comment_types() {
		$allowed_types = $this->get_allowed_comment_types();
		return !empty($allowed_types);
	}

	/**
	 * Check if a specific comment type is allowed (enabled in the allowlist)
	 *
	 * @param string $comment_type The comment type to check
	 * @return bool True if the comment type is allowed, false otherwise
	 */
	private function is_comment_type_allowed($comment_type) {
		$allowed_types = $this->get_allowed_comment_types();
		return in_array($comment_type, $allowed_types, true);
	}

	/**
	 * Get available comment type options for the "Enable Certain Comment Types" UI
	 *
	 * This function returns a list of known special comment types that users can enable,
	 * regardless of whether any comments of those types currently exist in the database.
	 *
	 * IMPORTANT: WordPress does not provide a formal API for registering or retrieving
	 * comment types (unlike post types with get_post_types()). Comment types are simply
	 * arbitrary string values stored in the wp_comments table. Therefore, we maintain
	 * a curated list of known special comment types that plugins commonly use.
	 *
	 * This function returns only predefined known types plus any types added via the
	 * 'disable_comments_known_comment_types' filter hook.
	 *
	 * @return array Associative array of comment_type => label
	 */
	public function get_available_comment_type_options() {
		// Predefined known special comment types with descriptive labels
		// These are shown even if no comments of these types exist yet in the database
		//
		// Note: WordPress does not have a formal comment type registration API,
		// so this list is maintained manually based on common plugin usage.
		$known_types = array(
			'note' => __('Notes - WordPress 6.9+ (note)', 'disable-comments'),
		);

		/**
		 * Filter the list of known comment types shown in the "Enable Certain Comment Types" UI
		 *
		 * Plugins can add their own comment types to this list so users can enable them
		 * even before any comments of those types exist in the database.
		 *
		 * Example:
		 *   add_filter( 'disable_comments_known_comment_types', function( $types ) {
		 *       $types['my_custom_type'] = __( 'My Custom Comment Type', 'my-plugin' );
		 *       return $types;
		 *   } );
		 *
		 * @param array $known_types Associative array of comment_type => label
		 */
		return apply_filters('disable_comments_known_comment_types', $known_types);
	}

	/**
	 * Check if a REST API request is for an allowed comment type
	 *
	 * @param WP_REST_Request $request The REST API request object
	 * @return bool True if the request is for an allowed comment type, false otherwise
	 */
	private function is_allowed_comment_type_request($request = null) {
		$comment_type = null;

		// Check if we have a request object
		if (!$request) {
			// Check global $_REQUEST for type parameter
			if (isset($_REQUEST['type'])) {
				$comment_type = sanitize_text_field(wp_unslash($_REQUEST['type']));
			}
			// Check if we're in a REST API context
			elseif (defined('REST_REQUEST') && REST_REQUEST) {
				global $wp;
				if (isset($wp->query_vars['type'])) {
					$comment_type = sanitize_text_field($wp->query_vars['type']);
				}
			}
		} else {
			// Check the request object for type parameter
			$type = $request->get_param('type');
			if ($type) {
				$comment_type = $type;
			}

			// Check the request body for type parameter (for POST requests)
			if (!$comment_type) {
				$body = $request->get_body_params();
				if (isset($body['type'])) {
					$comment_type = $body['type'];
				}
			}

			// Check JSON body for type parameter
			if (!$comment_type) {
				$json = $request->get_json_params();
				if (isset($json['type'])) {
					$comment_type = $json['type'];
				}
			}

			// For UPDATE requests (PUT/PATCH), check if the existing comment is an allowed type
			// WordPress doesn't send the type parameter when updating, only the ID and content
			if (!$comment_type) {
				$comment_id = $request->get_param('id');
				if ($comment_id) {
					$comment = get_comment($comment_id);
					if ($comment && isset($comment->comment_type)) {
						$comment_type = $comment->comment_type;
					}
				}
			}

			// For DELETE requests, extract comment ID from the route path
			// The comment ID is only in the URL (e.g., /wp/v2/comments/123), not in request params
			if (!$comment_type && $request->is_method('DELETE')) {
				$route_parts = explode('/', $request->get_route());
				$comment_id = end($route_parts);

				// Ensure we have a numeric comment ID
				if (is_numeric($comment_id)) {
					$comment = get_comment((int) $comment_id);
					if ($comment && isset($comment->comment_type)) {
						$comment_type = $comment->comment_type;
					}
				}
			}
		}

		// Check if the comment type is in the allowlist
		if ($comment_type && $this->is_comment_type_allowed($comment_type)) {
			return true;
		}

		return false;
	}

	/**
	 * Issue a 403 for all comment feed requests.
	 */
	public function filter_query() {
		if (is_comment_feed()) {
			wp_die(esc_html__('Comments are closed.', 'disable-comments'), '', array('response' => 403));
		}
	}

	/**
	 * Remove comment links from the admin bar.
	 */
	public function filter_admin_bar() {
		if (is_admin_bar_showing()) {
			// Remove comments links from admin bar.
			remove_action('admin_bar_menu', 'wp_admin_bar_comments_menu', 60);
			if (is_multisite()) {
				add_action('admin_bar_menu', array($this, 'remove_network_comment_links'), 500);
			}
		}
	}

	/**
	 * Remove the comments endpoint for the REST API
	 * But allow WordPress 6.9+ block notes (type=note) to work
	 */
	public function filter_rest_endpoints($endpoints) {
		// Don't remove endpoints entirely - instead we'll use permission callbacks
		// and other filters to block regular comments while allowing notes

		// We still need to add a filter to block non-note requests
		// This is handled by rest_pre_dispatch filter added in init_filters

		return $endpoints;
	}

	/**
	 * Filter REST API comment requests to block comments except allowed types
	 *
	 * @param mixed $result Response to replace the requested version with
	 * @param WP_REST_Server $server Server instance
	 * @param WP_REST_Request $request Request used to generate the response
	 * @return mixed
	 */
	public function filter_rest_comment_dispatch($result, $server, $request) {
		// Only filter comment-related routes
		$route = $request->get_route();
		if (strpos($route, '/wp/v2/comments') === false) {
			return $result;
		}

		// Allow requests for comment types in the allowlist to pass through
		if ($this->is_allowed_comment_type_request($request)) {
			return $result;
		}

		// Block all other comment requests
		return new WP_Error(
			'rest_comment_disabled',
			__('Comments are disabled.', 'disable-comments'),
			array('status' => 403)
		);
	}

	/**
	 * Filter comment queries in REST API to allow only allowed comment types
	 *
	 * @param array $prepared_args Array of arguments for WP_Comment_Query
	 * @param WP_REST_Request $request The REST API request
	 * @return array
	 */
	public function filter_rest_comment_query($prepared_args, $request) {
		// If this is a request for an allowed comment type, allow it
		if ($this->is_allowed_comment_type_request($request)) {
			return $prepared_args;
		}

		// For non-allowed requests, return empty results
		// by setting an impossible condition
		$prepared_args['comment__in'] = array(0);

		return $prepared_args;
	}

	/**
	 * Determines if scripts should be enqueued
	 */
	public function filter_gutenberg_blocks($hook) {
		global $post;
		if ($this->is_remove_everywhere() || (isset($post->post_type) && $this->is_post_type_disabled($post->post_type))) {
			return $this->disable_comments_script();
		}
	}

	/**
	 * Enqueues scripts
	 */
	public function disable_comments_script() {
		wp_enqueue_script('disable-comments-gutenberg', plugin_dir_url(__FILE__) . 'assets/js/disable-comments.js', array(), DC_VERSION, true);
	}

	/**
	 * Enqueues Scripts for Settings Page
	 */
	public function settings_page_assets($hook_suffix) {
		if (
			$hook_suffix === 'settings_page_' . DC_PLUGIN_SLUG ||
			$hook_suffix === 'options-general_' . DC_PLUGIN_SLUG
		) {
			// css
			wp_enqueue_style('sweetalert2', DC_ASSETS_URI . 'css/sweetalert2.min.css', [], DC_VERSION);
			// wp_enqueue_style('pagination',  DC_ASSETS_URI . 'css/pagination.css', [], false);
			wp_enqueue_style('disable-comments-style', DC_ASSETS_URI . 'css/style.css', [], DC_VERSION);
			wp_enqueue_style('select2', DC_ASSETS_URI . 'css/select2.min.css', [], DC_VERSION);
			// js
			wp_enqueue_script('sweetalert2', DC_ASSETS_URI . 'js/sweetalert2.all.min.js', array('jquery'), DC_VERSION, true);
			wp_enqueue_script('pagination', DC_ASSETS_URI . 'js/pagination.min.js', array('jquery'), DC_VERSION, true);
			wp_enqueue_script('select2', DC_ASSETS_URI . 'js/select2.min.js', array('jquery'), DC_VERSION, true);
			wp_enqueue_script('disable-comments-scripts', DC_ASSETS_URI . 'js/disable-comments-settings-scripts.js', array('jquery', 'select2', 'pagination', 'sweetalert2', 'wp-i18n'), DC_VERSION, true);
			wp_localize_script(
				'disable-comments-scripts',
				'disableCommentsObj',
				array(
					'save_action' => 'disable_comments_save_settings',
					'delete_action' => 'disable_comments_delete_comments',
					'settings_URI' => $this->settings_page_url(),
					'_nonce' => wp_create_nonce('disable_comments_save_settings')
				)
			);
			wp_set_script_translations('disable-comments-scripts', 'disable-comments');
		} else {
			// notice css
			wp_enqueue_style('disable-comments-notice', DC_ASSETS_URI . 'css/notice.css', [], DC_VERSION);
		}
	}

	/**
	 * Remove comment links from the admin bar in a multisite network.
	 */
	public function remove_network_comment_links($wp_admin_bar) {
		if ($this->networkactive && is_user_logged_in()) {
			foreach ((array) $wp_admin_bar->user->blogs as $blog) {
				$wp_admin_bar->remove_menu('blog-' . $blog->userblog_id . '-c');
			}
		} else {
			// We have no way to know whether the plugin is active on other sites, so only remove this one.
			$wp_admin_bar->remove_menu('blog-' . get_current_blog_id() . '-c');
		}
	}

	public function discussion_notice() {
		$disabled_post_types = $this->get_disabled_post_types();
		if (get_current_screen()->id == 'options-discussion' && !empty($disabled_post_types)) {
			$names_escaped = array();
			foreach ($disabled_post_types as $type) {
				$names_escaped[$type] = esc_html(get_post_type_object($type)->labels->name);
			}

			// translators: %s: disabled post types.
			echo '<div class="notice notice-warning"><p>' . sprintf(esc_html__('Note: The <em>Disable Comments</em> plugin is currently active, and comments are completely disabled on: %s. Many of the settings below will not be applicable for those post types.', 'disable-comments'), implode(esc_html__(', ', 'disable-comments'), $names_escaped)) . '</p></div>';
		}
	}

	/**
	 * Return context-aware settings page URL
	 */
	private function settings_page_url() {
		$base = $this->networkactive && is_network_admin() ? network_admin_url('settings.php') : admin_url('options-general.php');
		return add_query_arg('page', DC_PLUGIN_SLUG, $base);
	}

	/**
	 * Return context-aware tools page URL
	 */
	private function tools_page_url() {
		$base = $this->networkactive && is_network_admin() ? network_admin_url('settings.php') : admin_url('tools.php');
		return add_query_arg('page', 'disable_comments_tools', $base);
	}


	public function setup_notice() {
		$current_screen = get_current_screen()->id;
		if (!in_array($current_screen, ['dashboard-network', 'dashboard'])) {
			return;
		}
		$hascaps = $this->networkactive && is_network_admin() ? current_user_can('manage_network_plugins') : current_user_can('manage_options');
		if ($this->networkactive && !is_network_admin() && !$this->options['sitewide_settings']) {
			$hascaps = false;
		}
		if ($hascaps) {
			$this->setup_notice_flag = true;
			// translators: %s: URL to Disabled Comment settings page.
			$html = sprintf(__('The <strong>Disable Comments</strong> plugin is active, but isn\'t configured to do anything yet. Visit the <a href="%s">configuration page</a> to choose which post types to disable comments on.', 'disable-comments'), esc_attr($this->settings_page_url()));
			// phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage
			echo wp_kses_post('<div class="notice dc-text__block disable__comment__alert mb30"><img height="30" src="' . esc_url(DC_ASSETS_URI . 'img/icon-logo.png') . '" alt=""><p>' . $html . '</p></div>');
		}
	}

	public function filter_admin_menu() {
		global $pagenow;

		if (empty($this->options['show_existing_comments'])) {
			if ($pagenow == 'comment.php' || $pagenow == 'edit-comments.php') {
				wp_die(esc_html__('Comments are closed.', 'disable-comments'), '', array('response' => 403));
			}

			remove_menu_page('edit-comments.php');
		}

		if (!$this->discussion_settings_allowed()) {
			if ($pagenow == 'options-discussion.php') {
				wp_die(esc_html__('Comments are closed.', 'disable-comments'), '', array('response' => 403));
			}

			remove_submenu_page('options-general.php', 'options-discussion.php');
		}
	}

	public function filter_dashboard() {
		remove_meta_box('dashboard_recent_comments', 'dashboard', 'normal');
	}

	public function admin_css() {
		echo '<style>
			#dashboard_right_now .comment-count,
			#dashboard_right_now .comment-mod-count,
			#latest-comments,
			#welcome-panel .welcome-comments,
			.user-comment-shortcuts-wrap {
				display: none !important;
			}
		</style>';
	}

	public function filter_existing_comments($comments, $post_id) {
		$post_type = get_post_type($post_id);
		$comments_disabled = $this->is_remove_everywhere() || $this->is_post_type_disabled($post_type);

		// If comments are disabled but show_existing_comments is enabled, return existing comments
		if ($comments_disabled && !empty($this->options['show_existing_comments'])) {
			$comments_disabled = false;
		}

		// If comments are disabled, filter out regular comments but keep allowed comment types
		if ($comments_disabled && !empty($comments)) {
			$filtered_comments = array();
			foreach ($comments as $comment) {
				// Keep comment types that are in the allowlist even when comments are disabled
				if (isset($comment->comment_type) && $this->is_comment_type_allowed($comment->comment_type)) {
					$filtered_comments[] = $comment;
				}
			}
			return $filtered_comments;
		}

		// Default behavior: return all comments if not disabled
		return $comments;
	}

	public function filter_comment_status($open, $post_id) {
		$post_type = get_post_type($post_id);
		return ($this->is_remove_everywhere() || $this->is_post_type_disabled($post_type) ? false : $open);
	}

	public function filter_comments_number($count, $post_id) {
		$post_type = get_post_type($post_id);
		$comments_disabled = $this->is_remove_everywhere() || $this->is_post_type_disabled($post_type);

		// If comments are disabled but show_existing_comments is enabled, return actual count
		if ($comments_disabled && !empty($this->options['show_existing_comments'])) {
			return $count;
		}

		// If comments are disabled but there are allowed comment types, count only those types
		if ($comments_disabled && $this->has_allowed_comment_types()) {
			return $this->count_allowed_comment_types($post_id);
		}

		return $comments_disabled ? 0 : $count;
	}

	/**
	 * Count comments of allowed types for a specific post
	 *
	 * @param int $post_id The post ID
	 * @return int The count of comments matching allowed types
	 */
	private function count_allowed_comment_types($post_id) {
		$allowed_types = $this->get_allowed_comment_types();
		if (empty($allowed_types)) {
			return 0;
		}

		$comments = get_comments(array(
			'post_id' => $post_id,
			'type__in' => $allowed_types,
			'status' => 'approve',
			'count' => true,
		));

		return (int) $comments;
	}

	public function disable_rc_widget() {
		unregister_widget('WP_Widget_Recent_Comments');
		/**
		 * The widget has added a style action when it was constructed - which will
		 * still fire even if we now unregister the widget... so filter that out
		 */
		add_filter('show_recent_comments_widget_style', '__return_false');
	}

	public function set_plugin_meta($links, $file) {
		static $plugin;
		$plugin = plugin_basename(__FILE__);
		if ($file == $plugin) {
			$links[] = '<a href="https://github.com/WPDevelopers/disable-comments">GitHub</a>';
		}
		return $links;
	}

	/**
	 * Add links to Settings page
	 */
	public function plugin_actions_links($links, $file) {
		static $plugin;
		$plugin = plugin_basename(__FILE__);
		if ($file == $plugin && current_user_can('manage_options')) {
			array_unshift(
				$links,
				sprintf('<a href="%s">%s</a>', esc_attr($this->settings_page_url()), __('Settings', 'disable-comments')),
				sprintf('<a href="%s">%s</a>', esc_attr($this->tools_page_url()), __('Tools', 'disable-comments'))
			);
		}

		return $links;
	}

	public function settings_menu() {
		$title = _x('Disable Comments', 'settings menu title', 'disable-comments');
		if ($this->networkactive && is_network_admin()) {
			add_submenu_page('settings.php', $title, $title, 'manage_network_plugins', DC_PLUGIN_SLUG, array($this, 'settings_page'));
		} elseif (!$this->networkactive || $this->options['sitewide_settings']) {
			add_submenu_page('options-general.php', $title, $title, 'manage_options', DC_PLUGIN_SLUG, array($this, 'settings_page'));
		}
	}

	public function tools_menu() {
		$title = __('Delete Comments', 'disable-comments');
		$hook = '';
		if ($this->networkactive && is_network_admin()) {
			$hook = add_submenu_page('settings.php', $title, $title, 'manage_network_plugins', 'disable_comments_tools', array($this, 'tools_page'));
		} elseif (!$this->networkactive || $this->options['sitewide_settings']) {
			$hook = add_submenu_page('tools.php', $title, $title, 'manage_options', 'disable_comments_tools', array($this, 'tools_page'));
		}
		add_action('load-' . $hook, array($this, 'redirectToMainSettingsPage'));
	}

	public function redirectToMainSettingsPage() {
		wp_safe_redirect($this->settings_page_url() . '#delete');
		exit;
	}

	public function get_all_comments_number() {
		global $wpdb;
		if (is_network_admin() && function_exists('get_sites') && class_exists('WP_Site_Query')) {
			$count = 0;
			$sites = get_sites([
				'number' => 0,
				'fields' => 'ids',
			]);
			foreach ($sites as $blog_id) {
				switch_to_blog($blog_id);
				$count += $this->__get_comment_count();
				restore_current_blog();
			}
			return $count;
		} else {
			return $this->__get_comment_count();
		}
	}

	public function get_all_comment_types($exclude_allowed = true) {
		if ($this->networkactive && is_network_admin() && function_exists('get_sites')) {
			$comment_types = [];
			$sites = get_sites([
				'number' => 0,
				'fields' => 'ids',
			]);
			foreach ($sites as $blog_id) {
				switch_to_blog($blog_id);
				$comment_types = array_merge($this->_get_all_comment_types($exclude_allowed), $comment_types);
				restore_current_blog();
			}
			return $comment_types;
		} else {
			return $this->_get_all_comment_types($exclude_allowed);
		}
	}
	public function _get_all_comment_types($exclude_allowed = true) {
		global $wpdb;
		$commenttypes = array();
		// we need fresh data in every call.
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery -- We need to count comments across multiple sites
		$commenttypes_query = $wpdb->get_results("SELECT DISTINCT comment_type FROM $wpdb->comments", ARRAY_A);
		if (!empty($commenttypes_query) && is_array($commenttypes_query)) {
			foreach ($commenttypes_query as $entry) {
				$value = $entry['comment_type'];
				// Exclude comment types that are in the allowlist from deletable comment types
				// These are protected and should not appear in the "Delete Certain Comment Types" interface
				if ($exclude_allowed && $this->is_comment_type_allowed($value)) {
					continue;
				}
				if ('' === $value) {
					$commenttypes['default'] = __('Default (no type)', 'disable-comments');
				} else {
					$commenttypes[$value] = ucwords(str_replace('_', ' ', $value)) . ' (' . $value . ')';
				}
			}
		}
		return $commenttypes;
	}

	public function get_all_post_types($network = false) {
		$typeargs = array('public' => true);
		if ($network || $this->networkactive && is_network_admin()) {
			$typeargs['_builtin'] = true;   // stick to known types for network.
		}
		$types = get_post_types($typeargs, 'objects');
		foreach (array_keys($types) as $type) {
			if (!in_array($type, $this->modified_types) && !post_type_supports($type, 'comments')) {   // the type doesn't support comments anyway.
				unset($types[$type]);
			}
		}
		return $types;
	}

	public function get_roles($selected) {
		$roles = [
			[
				"id" => 'logged-out-users',
				"text" => __('Logged out users', 'disable-comments'),
				"selected" => in_array('logged-out-users', (array) $selected),
			]
		];
		$editable_roles = array_reverse(get_editable_roles());
		foreach ($editable_roles as $role => $details) {
			$roles[] = [
				"id" => esc_attr($role),
				"text" => translate_user_role($details['name']),
				"selected" => in_array($role, (array) $selected),
			];
		}
		return $roles;
	}

	public function tools_page() {
		return;
	}

	public function settings_page() {
		// if( isset( $_GET['cancel'] ) && trim( $_GET['cancel'] ) === 'setup' ){
		// 	$this->update_option('dc_setup_screen_seen', true);
		// }
		$avatar_status = '-1';
		if ($this->is_network_admin()) {
			$show_avatars = [];
			$sites = get_sites([
				'number' => 0,
				'fields' => 'ids',
			]);
			foreach ($sites as $blog_id) {
				switch_to_blog($blog_id);
				$show_avatars[] = (int) get_option('show_avatars', '0');
				restore_current_blog();
			}
			if (count($show_avatars) == array_sum($show_avatars)) {
				$avatar_status = '0';
			} elseif (0 == array_sum($show_avatars)) {
				$avatar_status = '1';
			}
		}

		include_once DC_PLUGIN_VIEWS_PATH . 'settings.php';
	}

	public function get_sub_sites() {
		$nonce = (isset($_REQUEST['nonce']) ? sanitize_text_field(wp_unslash($_REQUEST['nonce'])) : '');
		if (!wp_verify_nonce($nonce, 'disable_comments_save_settings')) {
			wp_send_json(['data' => [], 'totalNumber' => 0]);
		}

		$_sub_sites = [];
		$type = isset($_GET['type']) ? sanitize_text_field(wp_unslash($_GET['type'])) : 'disabled';
		$search = isset($_GET['search']) ? sanitize_text_field(wp_unslash($_GET['search'])) : '';
		$pageSize = isset($_GET['pageSize']) ? sanitize_text_field(wp_unslash($_GET['pageSize'])) : 50;
		$pageNumber = isset($_GET['pageNumber']) ? sanitize_text_field(wp_unslash($_GET['pageNumber'])) : 1;
		$offset = ($pageNumber - 1) * $pageSize;
		$sub_sites = get_sites([
			'number' => $pageSize,
			'offset' => $offset,
			'search' => $search,
			'fields' => 'ids',
		]);
		$totalNumber = get_sites([
			// 'number' => $pageSize,
			// 'offset' => $offset,
			'search' => $search,
			'count' => true,
		]);

		if ($type == 'disabled') {
			$disabled_site_options = isset($this->options['disabled_sites']) ? $this->options['disabled_sites'] : [];
		} else { // if($type == 'delete')
			$disabled_site_options = $this->get_disabled_sites(true);
		}

		foreach ($sub_sites as $sub_site_id) {
			$blog = get_blog_details($sub_site_id);
			$is_checked = checked(!empty($disabled_site_options["site_$sub_site_id"]), true, false);
			$_sub_sites[] = [
				'site_id' => $sub_site_id,
				'is_checked' => $is_checked,
				'blogname' => $blog->blogname,
			];
		}
		wp_send_json(['data' => $_sub_sites, 'totalNumber' => $totalNumber]);
	}

	public function get_form_array_escaped($_args = array()) {
		$formArray = [];
		if (!empty($_args)) {
			$formArray = wp_parse_args($_args);
		}
		// nonce is verified in the calling function
		// phpcs:ignore WordPress.Security.NonceVerification.Missing
		else if (isset($_POST['data'])) {
			// need to use wp_parse_args before map_deep sanitize_text_field
			// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
			$formArray = map_deep(wp_parse_args(wp_unslash($_POST['data'])), 'sanitize_text_field');
		}
		return $formArray;
	}

	public function disable_comments_settings($_args = array()) {
		$nonce = (isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '');
		if (($this->is_CLI && !empty($_args)) || wp_verify_nonce($nonce, 'disable_comments_save_settings')) {

			$formArray = $this->get_form_array_escaped($_args);

			$old_options = $this->options;
			$this->options = [];
			if ($this->is_CLI) {
				$this->options = $old_options;
			}

			$this->options['is_network_admin'] = isset($formArray['is_network_admin']) && $formArray['is_network_admin'] == '1' ? true : false;

			if (!empty($this->options['is_network_admin']) && function_exists('get_sites') && empty($formArray['sitewide_settings'])) {
				$formArray['disabled_sites'] = isset($formArray['disabled_sites']) ? $formArray['disabled_sites'] : [];
				$this->options['disabled_sites'] = isset($old_options['disabled_sites']) ? $old_options['disabled_sites'] : [];
				$this->options['disabled_sites'] = array_merge($this->options['disabled_sites'], $formArray['disabled_sites']);
			} elseif (!empty($this->options['is_network_admin']) && !empty($formArray['sitewide_settings'])) {
				$this->options['disabled_sites'] = $old_options['disabled_sites'];
			}

			if (isset($formArray['mode'])) {
				$this->options['remove_everywhere'] = (sanitize_text_field($formArray['mode']) == 'remove_everywhere');
			}
			$post_types = $this->get_all_post_types($this->options['is_network_admin']);

			if ($this->options['remove_everywhere']) {
				$disabled_post_types = array_keys($post_types);
			} else {
				$disabled_post_types = (isset($formArray['disabled_types']) ? array_map('sanitize_key', (array) $formArray['disabled_types']) : ($this->is_CLI && isset($this->options['disabled_post_types']) ? $this->options['disabled_post_types'] : []));
			}

			$disabled_post_types = array_intersect($disabled_post_types, array_keys($post_types));
			$this->options['disabled_post_types'] = $disabled_post_types;

			// Extra custom post types.
			if ($this->networkactive && isset($formArray['extra_post_types'])) {
				$extra_post_types = array_filter(array_map('sanitize_key', explode(',', $formArray['extra_post_types'])));
				$this->options['extra_post_types'] = array_diff($extra_post_types, array_keys($post_types)); // Make sure we don't double up builtins.
			}

			if (isset($formArray['sitewide_settings'])) {
				update_site_option('disable_comments_sitewide_settings', $formArray['sitewide_settings']);
			}

			if (isset($formArray['disable_avatar'])) {
				if ($this->is_network_admin()) {
					if ($formArray['disable_avatar'] == '0' || $formArray['disable_avatar'] == '1') {
						$sites = get_sites([
							'number' => 0,
							'fields' => 'ids',
						]);
						foreach ($sites as $blog_id) {
							switch_to_blog($blog_id);
							update_option('show_avatars', (bool) !$formArray['disable_avatar']);
							restore_current_blog();
						}
					}
				} else {
					update_option('show_avatars', (bool) !$formArray['disable_avatar']);
				}
			}

			if (isset($formArray['enable_exclude_by_role'])) {
				$this->options['enable_exclude_by_role'] = $formArray['enable_exclude_by_role'];
			}
			if (isset($formArray['exclude_by_role'])) {
				$this->options['exclude_by_role'] = $formArray['exclude_by_role'];
			}

			// xml rpc
			$this->options['remove_xmlrpc_comments'] = (isset($formArray['remove_xmlrpc_comments']) ? intval($formArray['remove_xmlrpc_comments']) : ($this->is_CLI && isset($this->options['remove_xmlrpc_comments']) ? $this->options['remove_xmlrpc_comments'] : 0));
			// rest api comments
			$this->options['remove_rest_API_comments'] = (isset($formArray['remove_rest_API_comments']) ? intval($formArray['remove_rest_API_comments']) : ($this->is_CLI && isset($this->options['remove_rest_API_comments']) ? $this->options['remove_rest_API_comments'] : 0));
			// show existing comments
			$this->options['show_existing_comments'] = (isset($formArray['show_existing_comments']) ? (bool) $formArray['show_existing_comments'] : ($this->is_CLI && isset($this->options['show_existing_comments']) ? $this->options['show_existing_comments'] : false));

			// allowed comment types (opt-in allowlist)
			if (isset($formArray['allowed_comment_types']) && is_array($formArray['allowed_comment_types'])) {
				// Sanitize and validate the allowed comment types
				$this->options['allowed_comment_types'] = array_map('sanitize_key', $formArray['allowed_comment_types']);
			} else {
				// Default: empty array (all special comment types disabled)
				$this->options['allowed_comment_types'] = array();
			}

			$this->options['db_version'] = self::DB_VERSION;
			$this->options['settings_saved'] = true;
			// save settings
			$this->update_options();
		}
		if (!$this->is_CLI) {
			wp_send_json_success(array('message' => __('Saved', 'disable-comments')));
			wp_die();
		}
	}

	public function is_configured() {
		$disabled_post_types = $this->get_disabled_post_types();

		if (empty($disabled_post_types) && empty($this->options['remove_everywhere']) && empty($this->options['remove_rest_API_comments']) && empty($this->options['remove_xmlrpc_comments'])) {
			return false;
		}
		return true;
	}

	public function delete_comments_settings($_args = array()) {
		global $deletedPostTypeNames;
		$log = '';
		$nonce = (isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '');

		if (($this->is_CLI && !empty($_args)) || wp_verify_nonce($nonce, 'disable_comments_save_settings')) {
			$formArray = $this->get_form_array_escaped($_args);

			if (!empty($formArray['is_network_admin']) && function_exists('get_sites') && class_exists('WP_Site_Query')) {
				$sites = get_sites([
					'number' => 0,
					'fields' => 'ids',
				]);
				foreach ($sites as $blog_id) {
					// $formArray['disabled_sites'] ids don't include "site_" prefix.
					if (!empty($formArray['disabled_sites']) && !empty($formArray['disabled_sites']["site_$blog_id"])) {
						switch_to_blog($blog_id);
						$log = $this->delete_comments($_args);
						restore_current_blog();
					}
				}
			} else {
				$log = $this->delete_comments($_args);
			}
		}
		// message
		$deletedPostTypeNames = array_unique((array) $deletedPostTypeNames);
		$message = (count($deletedPostTypeNames) == 0 ? $log . '.' : $log . ' for ' . implode(", ", $deletedPostTypeNames) . '.');
		if (!$this->is_CLI) {
			wp_send_json_success(array('message' => $message));
			wp_die();
		} else {
			return $log;
		}
	}

	private function delete_comments($_args) {
		global $wpdb;
		global $deletedPostTypeNames;

		$formArray = $this->get_form_array_escaped($_args);

		$types = $this->get_all_post_types(!empty($formArray['is_network_admin']));
		$commenttypes = $this->get_all_comment_types();
		$log = "";
		// comments delete
		if (isset($formArray['delete_mode'])) {
			if ($formArray['delete_mode'] == 'delete_everywhere') {
				// Delete all comment metadata except for allowed comment types
				$allowed_types = $this->get_allowed_comment_types();

				if (empty($allowed_types)) {
					// No allowed types, delete all comments
					// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
					$wpdb->query("DELETE FROM $wpdb->commentmeta");
					// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
					$wpdb->query("DELETE FROM $wpdb->comments");
				} else {
					// Build exclusion query for allowed comment types
					$placeholders = implode(', ', array_fill(0, count($allowed_types), '%s'));

					// Delete comment metadata
					$query = $wpdb->prepare(
						"DELETE cmeta FROM $wpdb->commentmeta cmeta INNER JOIN $wpdb->comments comments ON cmeta.comment_id=comments.comment_ID WHERE comments.comment_type NOT IN ($placeholders)",
						$allowed_types
					);
					// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
					$wpdb->query($query);

					// Delete comments
					$query = $wpdb->prepare(
						"DELETE FROM $wpdb->comments WHERE comment_type NOT IN ($placeholders)",
						$allowed_types
					);
					// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
					$wpdb->query($query);
				}

				// Update comment counts
				// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
				$wpdb->query("UPDATE $wpdb->posts SET comment_count = 0");
				$this->optimize_table($wpdb->commentmeta);
				$this->optimize_table($wpdb->comments);
				$log = __('All comments have been deleted', 'disable-comments');
			} elseif ($formArray['delete_mode'] == 'selected_delete_types') {
				$delete_post_types = empty($formArray['delete_types']) ? array() : (array) $formArray['delete_types'];
				$delete_post_types = array_intersect($delete_post_types, array_keys($types));

				// Extra custom post types.
				if ($this->networkactive && !empty($formArray['delete_extra_post_types'])) {
					$delete_extra_post_types = array_filter(array_map('sanitize_key', explode(',', $formArray['delete_extra_post_types'])));
					$delete_extra_post_types = array_diff($delete_extra_post_types, array_keys($types));    // Make sure we don't double up builtins.
					$delete_post_types = array_merge($delete_post_types, $delete_extra_post_types);
				}

				if (!empty($delete_post_types)) {
					// Loop through post_types and remove comments/meta (excluding allowed comment types) and set posts comment_count to 0.
					$allowed_types = $this->get_allowed_comment_types();

					foreach ($delete_post_types as $delete_post_type) {
						if (empty($allowed_types)) {
							// No allowed types, delete all comments for this post type
							// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
							$wpdb->query($wpdb->prepare("DELETE cmeta FROM $wpdb->commentmeta cmeta INNER JOIN $wpdb->comments comments ON cmeta.comment_id=comments.comment_ID INNER JOIN $wpdb->posts posts ON comments.comment_post_ID=posts.ID WHERE posts.post_type = %s", $delete_post_type));
							// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
							$wpdb->query($wpdb->prepare("DELETE comments FROM $wpdb->comments comments INNER JOIN $wpdb->posts posts ON comments.comment_post_ID=posts.ID WHERE posts.post_type = %s", $delete_post_type));
						} else {
							// Build exclusion query for allowed comment types
							$placeholders = implode(', ', array_fill(0, count($allowed_types), '%s'));
							$params = array_merge(array($delete_post_type), $allowed_types);

							// Delete comment metadata
							$query = $wpdb->prepare(
								"DELETE cmeta FROM $wpdb->commentmeta cmeta INNER JOIN $wpdb->comments comments ON cmeta.comment_id=comments.comment_ID INNER JOIN $wpdb->posts posts ON comments.comment_post_ID=posts.ID WHERE posts.post_type = %s AND comments.comment_type NOT IN ($placeholders)",
								$params
							);
							// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
							$wpdb->query($query);

							// Delete comments
							$query = $wpdb->prepare(
								"DELETE comments FROM $wpdb->comments comments INNER JOIN $wpdb->posts posts ON comments.comment_post_ID=posts.ID WHERE posts.post_type = %s AND comments.comment_type NOT IN ($placeholders)",
								$params
							);
							// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
							$wpdb->query($query);
						}

						// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
						$wpdb->query($wpdb->prepare("UPDATE $wpdb->posts SET comment_count = 0 WHERE post_author != 0 AND post_type = %s", $delete_post_type));

						$post_type_object = get_post_type_object($delete_post_type);
						$post_type_label = $post_type_object ? $post_type_object->labels->name : $delete_post_type;
						$deletedPostTypeNames[] = $post_type_label;
					}

					$this->optimize_table($wpdb->commentmeta);
					$this->optimize_table($wpdb->comments);
					$log = __('All comments have been deleted', 'disable-comments');
				}
			} elseif ($formArray['delete_mode'] == 'selected_delete_comment_types') {
				$delete_comment_types = empty($formArray['delete_comment_types']) ? array() : (array) $formArray['delete_comment_types'];
				$delete_comment_types = array_intersect($delete_comment_types, array_keys($commenttypes));

				if (!empty($delete_comment_types)) {
					// Loop through comment_types and remove comments/meta and set posts comment_count to 0.
					foreach ($delete_comment_types as $delete_comment_type) {
						// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
						$wpdb->query($wpdb->prepare("DELETE cmeta FROM $wpdb->commentmeta cmeta INNER JOIN $wpdb->comments comments ON cmeta.comment_id=comments.comment_ID WHERE comments.comment_type = %s", $delete_comment_type));
						// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
						$wpdb->query($wpdb->prepare("DELETE comments FROM $wpdb->comments comments  WHERE comments.comment_type = %s", $delete_comment_type));
						$deletedPostTypeNames[] = $commenttypes[$delete_comment_type];
					}

					// Update comment_count on post_types
					foreach ($types as $key => $value) {
						// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
						$comment_count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(comments.comment_ID) FROM $wpdb->comments comments INNER JOIN $wpdb->posts posts ON comments.comment_post_ID=posts.ID WHERE posts.post_type = %s", $key));
						// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
						$wpdb->query($wpdb->prepare("UPDATE $wpdb->posts SET comment_count = %d WHERE post_author != 0 AND post_type = %s", $comment_count, $key));
					}

					$this->optimize_table($wpdb->commentmeta);
					$this->optimize_table($wpdb->comments);

					$log = __('All comments have been deleted', 'disable-comments');
				}
			} elseif ($formArray['delete_mode'] == 'delete_spam') {

				// Delete spam comments and their metadata (excluding allowed comment types)
				$allowed_types = $this->get_allowed_comment_types();

				if (empty($allowed_types)) {
					// No allowed types, delete all spam comments
					// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
					$wpdb->query($wpdb->prepare("DELETE cmeta FROM $wpdb->commentmeta cmeta INNER JOIN $wpdb->comments comments ON cmeta.comment_id=comments.comment_ID WHERE comments.comment_approved = %s", 'spam'));
					// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
					$wpdb->query($wpdb->prepare("DELETE comments FROM $wpdb->comments comments WHERE comments.comment_approved = %s", 'spam'));
				} else {
					// Build exclusion query for allowed comment types
					$placeholders = implode(', ', array_fill(0, count($allowed_types), '%s'));
					$params = array_merge(array('spam'), $allowed_types);

					// Delete comment metadata
					$query = $wpdb->prepare(
						"DELETE cmeta FROM $wpdb->commentmeta cmeta INNER JOIN $wpdb->comments comments ON cmeta.comment_id=comments.comment_ID WHERE comments.comment_approved = %s AND comments.comment_type NOT IN ($placeholders)",
						$params
					);
					// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
					$wpdb->query($query);

					// Delete comments
					$query = $wpdb->prepare(
						"DELETE comments FROM $wpdb->comments comments WHERE comments.comment_approved = %s AND comments.comment_type NOT IN ($placeholders)",
						$params
					);
					// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
					$wpdb->query($query);
				}

				$this->optimize_table($wpdb->commentmeta);
				$this->optimize_table($wpdb->comments);
				$log = __('All spam comments have been deleted.', 'disable-comments');
			}
		}
		delete_transient('wc_count_comments');
		return $log;
	}

	private function discussion_settings_allowed() {
		if (defined('DISABLE_COMMENTS_ALLOW_DISCUSSION_SETTINGS') && DISABLE_COMMENTS_ALLOW_DISCUSSION_SETTINGS == true) {
			return true;
		}
	}

	public function single_site_deactivate() {
		// for single sites, delete the options upon deactivation, not uninstall.
		delete_option('disable_comments_options');
	}

	/**
	 * We need fresh data in every call. Called after switching to blog in loop.
	 *
	 * @return int The number of comments.
	 */
	protected function __get_comment_count() {
		global $wpdb;

		// Exclude allowed comment types from the count since they cannot be deleted
		// and should not be displayed in the "Total Comments" count in the Delete Comments tab
		$allowed_types = $this->get_allowed_comment_types();

		if (empty($allowed_types)) {
			// No allowed types, count all comments
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
			return $wpdb->get_var("SELECT COUNT(comment_id) FROM $wpdb->comments");
		}

		// Build exclusion query for allowed comment types
		$placeholders = implode(', ', array_fill(0, count($allowed_types), '%s'));
		$query = $wpdb->prepare(
			"SELECT COUNT(comment_id) FROM $wpdb->comments WHERE comment_type NOT IN ($placeholders)",
			$allowed_types
		);

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
		return $wpdb->get_var($query);
	}

	/**
	 * Optimize a given table in the WordPress database.
	 *
	 * @param string $table_name The name of the table to optimize.
	 */
	protected function optimize_table($table_name) {
		global $wpdb;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
		return $wpdb->query("OPTIMIZE TABLE " . esc_sql($table_name));
	}

	/**
	 * Truncate a given table in the WordPress database.
	 *
	 * @param string $table_name The name of the table to truncate.
	 */
	protected function truncate_table($table_name) {
		global $wpdb;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
		return $wpdb->query("TRUNCATE TABLE " . esc_sql($table_name));
	}

	/**
	 * Get the current site-wide comment status as a descriptive string.
	 *
	 * This function analyzes the current Disable Comments plugin configuration
	 * and returns a string describing which content types have comments disabled.
	 *
	 * @return string The current comment status:
	 *                - 'all' if comments are disabled site-wide for all content types
	 *                - 'posts' if comments are disabled only for posts
	 *                - 'pages' if comments are disabled only for pages
	 *                - 'posts,pages' if comments are disabled for both posts and pages
	 *                - 'custom_type_name' for other specific content types
	 *                - 'multiple' if multiple specific types are disabled (not all)
	 *                - 'none' if comments are not disabled anywhere
	 *
	 * @since 2.5.2
	 */
	public function get_current_comment_status() {
		try {
			// Handle case where plugin is not properly initialized
			if (empty($this->options)) {
				return 'none';
			}

			// Check if comments are disabled everywhere
			if ($this->is_remove_everywhere()) {
				return 'all';
			}

			// Get disabled post types
			$disabled_post_types = $this->get_disabled_post_types();

			// If no post types are disabled, comments are enabled everywhere
			if (empty($disabled_post_types)) {
				return 'none';
			}

			// Get all available post types that support comments
			$all_post_types = $this->get_all_post_types();
			$all_post_type_keys = array_keys($all_post_types);

			// Check if all available post types are disabled
			if (count($disabled_post_types) >= count($all_post_type_keys)) {
				$missing_types = array_diff($all_post_type_keys, $disabled_post_types);
				if (empty($missing_types)) {
					return 'all';
				}
			}

			// Handle specific common cases
			if (count($disabled_post_types) === 1) {
				$disabled_type = $disabled_post_types[0];

				// Return the specific post type name for single disabled types
				switch ($disabled_type) {
					case 'post':
						return 'posts';
					case 'page':
						return 'pages';
					default:
						// For custom post types, return the post type slug
						return $disabled_type;
				}
			}

			// Handle multiple specific post types
			if (count($disabled_post_types) === 2 &&
				in_array('post', $disabled_post_types) &&
				in_array('page', $disabled_post_types)) {
				return 'posts,pages';
			}

			// For other combinations, return 'multiple' to indicate partial disabling
			return 'multiple';
		} catch (Exception $e) {
			// Error handling - return safe default
			if (defined('WP_DEBUG') && WP_DEBUG) {
				// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Debug logging for WP_DEBUG mode
				error_log('Disable Comments: Error in get_current_comment_status() - ' . $e->getMessage());
			}
			return 'none';
		}
	}

	/**
	 * Get detailed comment status information including API restrictions.
	 *
	 * This function provides comprehensive information about comment restrictions
	 * including post type restrictions, API-level restrictions, network settings,
	 * role exclusions, and comment counts.
	 *
	 * @return array Associative array with detailed status information:
	 *               - 'status' => Main status (same as get_current_comment_status())
	 *               - 'disabled_post_types' => Array of disabled post type slugs
	 *               - 'disabled_post_type_labels' => Array of disabled post type labels
	 *               - 'remove_everywhere' => Boolean indicating global disable
	 *               - 'xmlrpc_disabled' => Boolean indicating XML-RPC comments disabled
	 *               - 'rest_api_disabled' => Boolean indicating REST API comments disabled
	 *               - 'total_post_types' => Total number of available post types
	 *               - 'is_configured' => Boolean indicating if plugin is configured
	 *               - 'total_comments' => Total number of comments in database
	 *               - 'network_active' => Boolean indicating if plugin is network activated
	 *               - 'sitewide_settings' => Site-wide settings status
	 *               - 'role_exclusion_enabled' => Boolean indicating if role exclusions are enabled
	 *               - 'excluded_roles' => Array of excluded role slugs
	 *               - 'excluded_role_labels' => Array of human-readable excluded role names
	 *
	 * @since 2.5.2
	 */
	public function get_detailed_comment_status() {
		try {
			$status = $this->get_current_comment_status();
			$disabled_post_types = $this->get_disabled_post_types();
			$all_post_types = $this->get_all_post_types();

			// Get human-readable labels for disabled post types
			$disabled_labels = array();
			foreach ($disabled_post_types as $post_type) {
				if (isset($all_post_types[$post_type])) {
					$disabled_labels[] = $all_post_types[$post_type]->labels->name;
				} else {
					// Fallback for custom post types not in the main list
					$post_type_obj = get_post_type_object($post_type);
					$disabled_labels[] = $post_type_obj ? $post_type_obj->labels->name : $post_type;
				}
			}

			// Get total comments count
			$total_comments = $this->get_all_comments_number();

			// Determine site-wide settings status
			$sitewide_settings = 'not_applicable';
			if ($this->networkactive) {
				$sitewide_settings = isset($this->options['sitewide_settings']) && $this->options['sitewide_settings'] ?
					'enabled' : 'disabled';
			}

			// Process role-based exclusion information
			$role_exclusion_enabled = isset($this->options['enable_exclude_by_role']) && $this->options['enable_exclude_by_role'];
			$excluded_roles = isset($this->options['exclude_by_role']) ? $this->options['exclude_by_role'] : array();

			// Get human-readable role names
			$excluded_role_labels = array();
			if ($role_exclusion_enabled && !empty($excluded_roles)) {
				$editable_roles = get_editable_roles();

				foreach ($excluded_roles as $role) {
					if ($role === 'logged-out-users') {
						$excluded_role_labels[] = __('Logged out users', 'disable-comments');
					} elseif (isset($editable_roles[$role])) {
						$excluded_role_labels[] = translate_user_role($editable_roles[$role]['name']);
					} else {
						$excluded_role_labels[] = $role;
					}
				}
			}

			return array(
				'status' => $status,
				'disabled_post_types' => $disabled_post_types,
				'disabled_post_type_labels' => $disabled_labels,
				'remove_everywhere' => $this->is_remove_everywhere(),
				'xmlrpc_disabled' => !empty($this->options['remove_xmlrpc_comments']),
				'rest_api_disabled' => !empty($this->options['remove_rest_API_comments']),
				'show_existing_comments' => !empty($this->options['show_existing_comments']),
				'total_post_types' => count($all_post_types),
				'is_configured' => $this->is_configured(),
				'total_comments' => $total_comments,
				'network_active' => $this->networkactive,
				'sitewide_settings' => $sitewide_settings,
				'role_exclusion_enabled' => $role_exclusion_enabled,
				'excluded_roles' => $excluded_roles,
				'excluded_role_labels' => $excluded_role_labels
			);
		} catch (Exception $e) {
			// Error handling - return safe defaults
			if (defined('WP_DEBUG') && WP_DEBUG) {
				// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Debug logging for WP_DEBUG mode
				error_log('Disable Comments: Error in get_detailed_comment_status() - ' . $e->getMessage());
			}
			return array(
				'status' => 'none',
				'disabled_post_types' => array(),
				'disabled_post_type_labels' => array(),
				'remove_everywhere' => false,
				'xmlrpc_disabled' => false,
				'rest_api_disabled' => false,
				'show_existing_comments' => false,
				'total_post_types' => 0,
				'is_configured' => false,
				'total_comments' => 0,
				'network_active' => false,
				'sitewide_settings' => 'not_applicable',
				'role_exclusion_enabled' => false,
				'excluded_roles' => array(),
				'excluded_role_labels' => array()
			);
		}
	}
	/**
	 * Add Disable Comments information to WordPress Site Health Info panel.
	 *
	 * This method integrates the plugin's status information into WordPress's
	 * built-in Site Health system for easy debugging and site overview.
	 *
	 * @param array $debug_info The debug information array.
	 * @return array Modified debug information array.
	 *
	 * @since 2.5.2
	 */
	public function add_site_health_info($debug_info) {
		$data = $this->get_detailed_comment_status();

		// Create the main status description
		$status_descriptions = array(
			'all' => __('Comments are disabled site-wide for all content types', 'disable-comments'),
			'posts' => __('Comments are disabled only for blog posts', 'disable-comments'),
			'pages' => __('Comments are disabled only for pages', 'disable-comments'),
			'posts,pages' => __('Comments are disabled for both posts and pages', 'disable-comments'),
			'multiple' => __('Comments are disabled for multiple specific content types', 'disable-comments'),
			'none' => __('Comments are enabled everywhere', 'disable-comments'),
		);

		// translators: %s: disabled post types.
		$other_status_description = sprintf(__('Comments are disabled for: %s', 'disable-comments'), $data['status']);
		$status_description = isset($status_descriptions[$data['status']]) ?
			$status_descriptions[$data['status']] :
			$other_status_description;

		// Format site-wide settings value
		$sitewide_settings_labels = array(
			'enabled' => __('Enabled', 'disable-comments'),
			'disabled' => __('Disabled', 'disable-comments'),
			'not_applicable' => __('Not applicable', 'disable-comments'),
		);

		// Build the fields array using data from get_detailed_comment_status()
		$fields = array(
			'status' => array(
				'label' => __('Comment Status', 'disable-comments'),
				'value' => $status_description,
			),
			'plugin_configured' => array(
				'label' => __('Plugin Configured', 'disable-comments'),
				'value' => $data['is_configured'] ? __('Yes', 'disable-comments') : __('No', 'disable-comments'),
			),
			'total_comments' => array(
				'label' => __('Total Comments', 'disable-comments'),
				'value' => number_format_i18n($data['total_comments']),
			),
			'global_disable' => array(
				'label' => __('Global Disable Active', 'disable-comments'),
				'value' => $data['remove_everywhere'] ? __('Yes', 'disable-comments') : __('No', 'disable-comments'),
			),
			'disabled_post_type_count' => array(
				'label' => __('Disabled Post Types Count', 'disable-comments'),
				'value' => sprintf('%d of %d', count($data['disabled_post_types']), $data['total_post_types']),
			),
			'disabled_post_types' => array(
				'label' => __('Disabled Post Types', 'disable-comments'),
				'value' => !empty($data['disabled_post_type_labels']) ?
					implode(', ', $data['disabled_post_type_labels']) :
					__('None', 'disable-comments'),
			),
			'xmlrpc_comments' => array(
				'label' => __('XML-RPC Comments', 'disable-comments'),
				'value' => $data['xmlrpc_disabled'] ? __('Disabled', 'disable-comments') : __('Enabled', 'disable-comments'),
			),
			'rest_api_comments' => array(
				'label' => __('REST API Comments', 'disable-comments'),
				'value' => $data['rest_api_disabled'] ? __('Disabled', 'disable-comments') : __('Enabled', 'disable-comments'),
			),
			'show_existing_comments' => array(
				'label' => __('Show Existing Comments', 'disable-comments'),
				'value' => $data['show_existing_comments'] ? __('Yes', 'disable-comments') : __('No', 'disable-comments'),
			),
			'network_active' => array(
				'label' => __('Network Active', 'disable-comments'),
				'value' => $data['network_active'] ? __('Yes', 'disable-comments') : __('No', 'disable-comments'),
			),
			'sitewide_settings' => array(
				'label' => __('Site-wide Settings', 'disable-comments'),
				'value' => $sitewide_settings_labels[$data['sitewide_settings']],
			),
			'role_exclusion_enabled' => array(
				'label' => __('Role-based Exclusions', 'disable-comments'),
				'value' => $data['role_exclusion_enabled'] ? __('Enabled', 'disable-comments') : __('Disabled', 'disable-comments'),
			),
			'excluded_roles' => array(
				'label' => __('Excluded Roles', 'disable-comments'),
				'value' => !empty($data['excluded_role_labels']) ?
					implode(', ', $data['excluded_role_labels']) :
					__('None', 'disable-comments'),
			),
		);

		// Add the section to Site Health
		$debug_info['disable-comments'] = array(
			'label' => __('Disable Comments', 'disable-comments'),
			'description' => __('Complete overview of comment disable settings and configuration.', 'disable-comments'),
			'fields' => $fields,
		);

		return $debug_info;
	}
}

Disable_Comments::get_instance();