457 lines
14 KiB
PHP
457 lines
14 KiB
PHP
<?php
|
|
/**
|
|
* Sensor: Main WP
|
|
*
|
|
* Main WP sensor class file.
|
|
*
|
|
* @since 4.6.0
|
|
* @package wsal
|
|
* @subpackage sensors
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace WSAL\WP_Sensors;
|
|
|
|
use WSAL\Helpers\Settings_Helper;
|
|
use WSAL\Controllers\Alert_Manager;
|
|
use WSAL\Helpers\Plugin_Settings_Helper;
|
|
use WSAL\WP_Sensors\Helpers\MainWP_Server_Helper;
|
|
|
|
// Exit if accessed directly.
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
if ( ! class_exists( '\WSAL\WP_Sensors\Main_WP_Sensor' ) ) {
|
|
/**
|
|
* MainWP Plugins & Themes sensor.
|
|
*
|
|
* 5000 User installed a plugin
|
|
* 5001 User activated a WordPress plugin
|
|
* 5002 User deactivated a WordPress plugin
|
|
* 5003 User uninstalled a plugin
|
|
* 5004 User upgraded a plugin
|
|
* 5005 User installed a theme
|
|
* 5006 User activated a theme
|
|
* 5007 User uninstalled a theme
|
|
* 5031 User updated a theme
|
|
*
|
|
* @package wsal
|
|
* @subpackage sensors
|
|
*/
|
|
class Main_WP_Sensor {
|
|
/**
|
|
* List of Themes.
|
|
*
|
|
* @var array
|
|
*
|
|
* @since 4.5.0
|
|
*/
|
|
private static $old_themes = array();
|
|
|
|
/**
|
|
* Inits the main hooks
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 4.5.0
|
|
*/
|
|
public static function init() {
|
|
\add_action( 'admin_init', array( __CLASS__, 'event_admin_init' ) );
|
|
|
|
// Check if MainWP Child Plugin exists.
|
|
if ( \WpSecurityAuditLog::is_mainwp_active() ) {
|
|
self::mainwp_child_init();
|
|
|
|
// Handle plugin/theme installation event via MainWP dashboard.
|
|
\add_action( 'mainwp_child_installPluginTheme', array( __CLASS__, 'mainwp_child_install_assets' ), 10, 1 );
|
|
|
|
// Activate/Deactivate plugin event.
|
|
\add_action( 'activated_plugin', array( __CLASS__, 'mainwp_child_plugin_events' ), 10, 1 );
|
|
\add_action( 'deactivated_plugin', array( __CLASS__, 'mainwp_child_plugin_events' ), 10, 1 );
|
|
|
|
// Uninstall plugin from MainWP dashboard.
|
|
\add_action( 'mainwp_child_plugin_action', array( __CLASS__, 'mainwp_child_uninstall_plugin' ), 10, 1 );
|
|
|
|
// Uninstall theme from MainWP dashboard.
|
|
\add_action( 'mainwp_child_theme_action', array( __CLASS__, 'mainwp_child_uninstall_theme' ), 10, 1 );
|
|
|
|
// Update theme/plugin from MainWP dashboard.
|
|
\add_action( 'upgrader_process_complete', array( __CLASS__, 'mainwp_child_update_assets' ), 10, 2 );
|
|
|
|
}
|
|
\add_action( 'deactivated_plugin', array( __CLASS__, 'reset_stealth_mode' ), 10, 1 );
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Reset Stealth Mode on MainWP Child plugin deactivation.
|
|
*
|
|
* @param string $plugin — Plugin.
|
|
*
|
|
* @since 5.1.0
|
|
*/
|
|
public static function reset_stealth_mode( $plugin ) {
|
|
if ( 'mainwp-child/mainwp-child.php' !== $plugin ) {
|
|
return;
|
|
}
|
|
|
|
if ( Settings_Helper::get_boolean_option_value( 'mwp-child-stealth-mode', false ) ) {
|
|
Plugin_Settings_Helper::deactivate_mainwp_child_stealth_mode();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Triggered when a user accesses the admin area.
|
|
*
|
|
* @since 4.5.0
|
|
*/
|
|
public static function event_admin_init() {
|
|
self::$old_themes = \wp_get_themes();
|
|
}
|
|
|
|
/**
|
|
* Method: Check and initialize class members for MainWP.
|
|
*
|
|
* @since 4.5.0
|
|
*/
|
|
public static function mainwp_child_init() {
|
|
if ( isset( $_POST['mainwpsignature'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
|
$function = ( isset( $_POST['function'] ) ) ? \sanitize_text_field( \wp_unslash( $_POST['function'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
|
$action = ( isset( $_POST['action'] ) ) ? \sanitize_text_field( \wp_unslash( $_POST['action'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
|
$theme = ( isset( $_POST['theme'] ) ) ? \sanitize_text_field( \wp_unslash( $_POST['theme'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
|
$mainwpsignature = ( isset( $_POST['mainwpsignature'] ) ) ? \sanitize_text_field( \wp_unslash( $_POST['mainwpsignature'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
|
|
|
if (
|
|
isset( $function ) && 'theme_action' === $function
|
|
&& isset( $action ) && 'delete' === $action
|
|
&& isset( $theme ) && ! empty( $theme )
|
|
&& isset( $mainwpsignature ) && ! empty( $mainwpsignature )
|
|
) {
|
|
if ( empty( self::$old_themes ) ) {
|
|
self::$old_themes = \wp_get_themes();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get removed themes.
|
|
*
|
|
* @return \WP_Theme[] List of WP_Theme objects.
|
|
*
|
|
* @since 4.5.0
|
|
*/
|
|
protected static function get_removed_themes() {
|
|
$result = self::$old_themes;
|
|
foreach ( $result as $i => $theme ) {
|
|
if ( file_exists( $theme->get_template_directory() ) ) {
|
|
unset( $result[ $i ] );
|
|
}
|
|
}
|
|
|
|
return array_values( $result );
|
|
}
|
|
|
|
/**
|
|
* Method: Handle plugin/theme install event
|
|
* from MainWP dashboard on child site.
|
|
*
|
|
* @param array $args - Array of arguments related to asset installed.
|
|
*
|
|
* @since 4.5.0
|
|
*/
|
|
public static function mainwp_child_install_assets( $args ) {
|
|
if ( empty( $args ) || ! is_array( $args ) ) {
|
|
return;
|
|
}
|
|
|
|
// Verify the action from MainWP.
|
|
if (
|
|
isset( $args['action'] ) && 'install' === $args['action']
|
|
&& isset( $args['success'] ) && ! empty( $args['success'] )
|
|
) {
|
|
if ( isset( $args['type'] ) && 'theme' === $args['type'] ) { // Installing theme.
|
|
// Get theme name & object.
|
|
$theme_slug = isset( $args['slug'] ) ? $args['slug'] : false;
|
|
$theme_obj = \wp_get_theme( $theme_slug );
|
|
|
|
// Check if theme exists.
|
|
if ( $theme_obj->exists() ) {
|
|
Alert_Manager::trigger_event(
|
|
5005,
|
|
array(
|
|
'Theme' => (object) array(
|
|
'Name' => $theme_obj->Name, // phpcs:ignore
|
|
'ThemeURI' => $theme_obj->ThemeURI, // phpcs:ignore
|
|
'Description' => $theme_obj->Description, // phpcs:ignore
|
|
'Author' => $theme_obj->Author, // phpcs:ignore
|
|
'Version' => $theme_obj->Version, // phpcs:ignore
|
|
'get_template_directory' => $theme_obj->get_template_directory(),
|
|
),
|
|
)
|
|
);
|
|
}
|
|
} elseif ( isset( $args['type'] ) && 'plugin' === $args['type'] ) {
|
|
// Get plugin slug.
|
|
$plugin_slug = isset( $args['slug'] ) ? $args['slug'] : false;
|
|
|
|
$plugins = get_plugins(); // Get all plugins.
|
|
$plugin = $plugins[ $plugin_slug ]; // Take out the plugin being installed.
|
|
|
|
$plugin_path = plugin_dir_path( WP_PLUGIN_DIR . '/' . $plugin_slug );
|
|
Alert_Manager::trigger_event(
|
|
5000,
|
|
array(
|
|
'PluginData' => (object) array(
|
|
'Name' => $plugin['Name'],
|
|
'PluginURI' => $plugin['PluginURI'],
|
|
'PluginRepoUrl' => WP_Plugins_Themes_Sensor::get_plugin_wp_repo_url( $plugin_slug ),
|
|
'Version' => $plugin['Version'],
|
|
'Author' => $plugin['Author'],
|
|
'Network' => $plugin['Network'] ? 'True' : 'False',
|
|
'plugin_dir_path' => $plugin_path,
|
|
),
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Method: Handle plugin uninstall event
|
|
* from MainWP dashboard on child site.
|
|
*
|
|
* @param array $args - Array of arguments related to asset uninstalled.
|
|
*
|
|
* @since 4.5.0
|
|
*/
|
|
public static function mainwp_child_uninstall_plugin( $args ) {
|
|
if ( empty( $args ) || ! is_array( $args ) ) {
|
|
return;
|
|
}
|
|
|
|
// Get MainWP post data.
|
|
$post_array = filter_input_array( INPUT_POST );
|
|
|
|
// Get plugins from MainWP.
|
|
if ( isset( $post_array['plugin'] ) && ! empty( $post_array['plugin'] ) ) {
|
|
$wp_plugins = explode( '||', \sanitize_text_field( \wp_unslash( $post_array['plugin'] ) ) );
|
|
}
|
|
|
|
// Verify actions from MainWP.
|
|
if (
|
|
isset( $args['action'] ) && 'delete' === $args['action']
|
|
&& isset( $args['Name'] ) && ! empty( $args['Name'] )
|
|
&& isset( $post_array['mainwpsignature'] ) && ! empty( $post_array['mainwpsignature'] )
|
|
) {
|
|
// Get plugin name.
|
|
$plugin_name = $args['Name'];
|
|
|
|
$plugin_slug = dirname( $plugin_name );
|
|
|
|
// Get plugin filename.
|
|
$plugin_filename = WP_Plugins_Themes_Sensor::get_plugin_file_name( $plugin_name );
|
|
|
|
if ( ! empty( $plugin_filename ) && in_array( $plugin_filename, $wp_plugins, true ) ) {
|
|
Alert_Manager::trigger_event(
|
|
5003,
|
|
array(
|
|
'PluginFile' => $plugin_filename,
|
|
'PluginData' => (object) array(
|
|
'Name' => $plugin_name,
|
|
'PluginRepoUrl' => WP_Plugins_Themes_Sensor::get_plugin_wp_repo_url( $plugin_slug ),
|
|
),
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Method: Handle theme uninstall event
|
|
* from MainWP dashboard on child site.
|
|
*
|
|
* @param array $args - Array of arguments related to asset uninstalled.
|
|
*
|
|
* @since 4.5.0
|
|
*/
|
|
public static function mainwp_child_uninstall_theme( $args ) {
|
|
if ( empty( $args ) || ! is_array( $args ) ) {
|
|
return;
|
|
}
|
|
|
|
// Get MainWP post data.
|
|
$post_array = filter_input_array( INPUT_POST );
|
|
|
|
// Get themes from MainWP.
|
|
if ( isset( $post_array['theme'] ) && ! empty( $post_array['theme'] ) ) {
|
|
$wp_themes = explode( '||', \sanitize_text_field( \wp_unslash( $post_array['theme'] ) ) );
|
|
}
|
|
|
|
// Verify actions from MainWP.
|
|
if (
|
|
isset( $args['action'] ) && 'delete' === $args['action']
|
|
&& isset( $args['Name'] ) && ! empty( $args['Name'] )
|
|
&& isset( $post_array['mainwpsignature'] ) && ! empty( $post_array['mainwpsignature'] )
|
|
) {
|
|
// Get theme object.
|
|
$themes = self::get_removed_themes();
|
|
|
|
if ( ! empty( $themes ) ) {
|
|
foreach ( $themes as $index => $theme ) {
|
|
if ( ! empty( $theme ) && $theme instanceof \WP_Theme && in_array( $theme->Name, $wp_themes, true ) ) { // phpcs:ignore
|
|
Alert_Manager::trigger_event(
|
|
5007,
|
|
array(
|
|
'Theme' => (object) array(
|
|
'Name' => $theme->Name, // phpcs:ignore
|
|
'ThemeURI' => $theme->ThemeURI, // phpcs:ignore
|
|
'Description' => $theme->Description, // phpcs:ignore
|
|
'Author' => $theme->Author, // phpcs:ignore
|
|
'Version' => $theme->Version, // phpcs:ignore
|
|
'get_template_directory' => $theme->get_template_directory(),
|
|
),
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Method: Handle plugin activation event
|
|
* from MainWP dashboard on a child site.
|
|
*
|
|
* @param string $plugin - Plugin slug.
|
|
*
|
|
* @since 4.5.0
|
|
*/
|
|
public static function mainwp_child_plugin_events( $plugin ) {
|
|
// Check parameter.
|
|
if ( empty( $plugin ) && ! \is_wp_error( \validate_plugin( $plugin ) ) ) {
|
|
return;
|
|
}
|
|
|
|
$plugin_slug = dirname( $plugin );
|
|
|
|
// Get MainWP post data.
|
|
$post_array = filter_input_array( INPUT_POST );
|
|
|
|
// Get plugins from MainWP.
|
|
if ( isset( $post_array['plugin'] ) && ! empty( $post_array['plugin'] ) ) {
|
|
$wp_plugins = explode( '||', \sanitize_text_field( \wp_unslash( $post_array['plugin'] ) ) );
|
|
}
|
|
|
|
if (
|
|
isset( $post_array['mainwpsignature'] ) // Check MainWP signature.
|
|
&& isset( $post_array['action'] ) // Check if action is set.
|
|
&& isset( $post_array['function'] ) // Check if function is set.
|
|
&& 'plugin_action' === $post_array['function']
|
|
&& in_array( $plugin, $wp_plugins, true ) // Check if plugin being activate/deactivate is in the list of plugins from MainWP.
|
|
) {
|
|
if ( 'activate' === $post_array['action'] ) {
|
|
$event = 5001;
|
|
} elseif ( 'deactivate' === $post_array['action'] ) {
|
|
$event = 5002;
|
|
}
|
|
|
|
$plugin = WP_PLUGIN_DIR . '/' . $plugin;
|
|
|
|
$plugin_data = get_plugin_data( $plugin, false, true );
|
|
|
|
Alert_Manager::trigger_event(
|
|
$event,
|
|
array(
|
|
'PluginFile' => $plugin,
|
|
'PluginData' => (object) array(
|
|
'Name' => $plugin_data['Name'],
|
|
'PluginURI' => $plugin_data['PluginURI'],
|
|
'PluginRepoUrl' => WP_Plugins_Themes_Sensor::get_plugin_wp_repo_url( $plugin_slug ),
|
|
'Version' => $plugin_data['Version'],
|
|
'Author' => $plugin_data['Author'],
|
|
'Network' => $plugin_data['Network'] ? 'True' : 'False',
|
|
),
|
|
)
|
|
);
|
|
} elseif (
|
|
isset( $post_array['mainwpsignature'] ) // Check MainWP signature.
|
|
&& isset( $post_array['function'] ) // Check if function is set.
|
|
&& 'installplugintheme' === $post_array['function']
|
|
&& isset( $post_array['type'] ) // Check if type is set.
|
|
&& 'plugin' === $post_array['type']
|
|
) {
|
|
$plugin = WP_PLUGIN_DIR . '/' . $plugin;
|
|
$plugin_data = get_plugin_data( $plugin, false, true );
|
|
Alert_Manager::trigger_event(
|
|
5001,
|
|
array(
|
|
'PluginFile' => $plugin,
|
|
'PluginData' => (object) array(
|
|
'Name' => $plugin_data['Name'],
|
|
'PluginURI' => $plugin_data['PluginURI'],
|
|
'PluginRepoUrl' => WP_Plugins_Themes_Sensor::get_plugin_wp_repo_url( $plugin_slug ),
|
|
'Version' => $plugin_data['Version'],
|
|
'Author' => $plugin_data['Author'],
|
|
'Network' => $plugin_data['Network'] ? 'True' : 'False',
|
|
),
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Method: Handle plugin/theme update event from MainWP dashboard on child site.
|
|
*
|
|
* @param WP_Upgrader $upgrader WordPress upgrader.
|
|
* @param array $args - Array of arguments related to asset updated.
|
|
*
|
|
* @since 4.5.0
|
|
*/
|
|
public static function mainwp_child_update_assets( $upgrader, $args ) {
|
|
if ( empty( $args ) || ! is_array( $args ) ) {
|
|
return;
|
|
}
|
|
|
|
// Get MainWP post data.
|
|
$post_array = filter_input_array( INPUT_POST );
|
|
|
|
// Check type.
|
|
if (
|
|
isset( $post_array['function'] ) && 'upgradeplugintheme' === $post_array['function']
|
|
&& isset( $post_array['mainwpsignature'] ) && ! empty( $post_array['mainwpsignature'] )
|
|
&& isset( $post_array['list'] ) && ! empty( $post_array['list'] )
|
|
&& isset( $args['action'] ) && 'update' === $args['action']
|
|
&& isset( $args['type'] ) && ! empty( $args['type'] )
|
|
) {
|
|
if ( 'theme' === $args['type'] ) {
|
|
// Site themes updated.
|
|
$site_themes = array_key_exists( 'themes', $args ) ? $args['themes'] : explode( ',', \sanitize_text_field( \wp_unslash( $post_array['list'] ) ) );
|
|
|
|
if ( empty( $site_themes ) ) {
|
|
// No themes in any of the lists.
|
|
return;
|
|
}
|
|
|
|
foreach ( $site_themes as $theme_name ) {
|
|
MainWP_Server_Helper::log_theme_updated_event( $theme_name );
|
|
}
|
|
} elseif ( 'plugin' === $args['type'] ) {
|
|
// Site plugins updated.
|
|
if ( ! array_key_exists( 'plugins', $args ) || empty( $args['plugins'] ) ) {
|
|
// No plugins in the list.
|
|
return;
|
|
}
|
|
|
|
$plugins = $args['plugins'];
|
|
foreach ( $plugins as $plugin_file ) {
|
|
MainWP_Server_Helper::log_plugin_updated_event( $plugin_file );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|