1518 lines
48 KiB
PHP
1518 lines
48 KiB
PHP
<?php
|
||
/**
|
||
* Audit Log List View
|
||
*
|
||
* Base WSAL class
|
||
*
|
||
* @since 5.0.0
|
||
*
|
||
* @package wsal
|
||
*/
|
||
|
||
use WSAL\Helpers\Notices;
|
||
use WSAL\Utils\Migration;
|
||
use WSAL\Helpers\WP_Helper;
|
||
use WSAL\MainWP\MainWP_Addon;
|
||
use WSAL\Views\Notifications;
|
||
use WSAL\Helpers\Email_Helper;
|
||
use WSAL\Helpers\View_Manager;
|
||
use WSAL\Controllers\Constants;
|
||
use WSAL\Controllers\Cron_Jobs;
|
||
use WSAL\Controllers\Connection;
|
||
use WSAL\EventNotes\Event_Notes;
|
||
use WSAL\Helpers\Plugins_Helper;
|
||
use WSAL\Helpers\Upgrade_Notice;
|
||
use WSAL\Helpers\Widget_Manager;
|
||
use WSAL\Helpers\Settings_Helper;
|
||
use WSAL\Actions\Plugin_Installer;
|
||
use WSAL\Helpers\Uninstall_Helper;
|
||
use WSAL\Controllers\Alert_Manager;
|
||
use WSAL\FeedbackForm\Feedback_Form;
|
||
use WSAL\ListAdminEvents\List_Events;
|
||
use WSAL\CopyEventData\Copy_Event_Data;
|
||
use WSAL\Controllers\Plugin_Extensions;
|
||
use WSAL\WP_Sensors\WP_Database_Sensor;
|
||
use WSAL\Helpers\Plugin_Settings_Helper;
|
||
use WSAL\Controllers\Sensors_Load_Manager;
|
||
use WSAL\Migration\Metadata_Migration_440;
|
||
|
||
if ( ! defined( 'ABSPATH' ) ) {
|
||
exit;
|
||
}
|
||
|
||
if ( ! class_exists( 'WpSecurityAuditLog' ) ) {
|
||
|
||
/**
|
||
* WSAL Main Class.
|
||
*
|
||
* @package wsal
|
||
*/
|
||
class WpSecurityAuditLog {
|
||
|
||
/**
|
||
* Minimal PHP version.
|
||
*
|
||
* @var string
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
const MIN_PHP_VERSION = '7.4.0';
|
||
|
||
/**
|
||
* Premium version constant
|
||
*
|
||
* @var string
|
||
*
|
||
* @since 5.1.0
|
||
*/
|
||
const PREMIUM_VERSION_WHOLE_PLUGIN_NAME = 'wp-security-audit-log-premium/wp-security-audit-log.php';
|
||
|
||
/**
|
||
* NOFS version constant
|
||
*
|
||
* @var string
|
||
*
|
||
* @since 5.1.0
|
||
*/
|
||
const NOFS_VERSION_WHOLE_PLUGIN_NAME = 'wp-security-audit-log-nofs/wp-security-audit-log.php';
|
||
|
||
/**
|
||
* Free version constant
|
||
*
|
||
* @var string
|
||
*
|
||
* @since 5.1.0
|
||
*/
|
||
const FREE_VERSION_WHOLE_PLUGIN_NAME = 'wp-security-audit-log/wp-security-audit-log.php';
|
||
|
||
/**
|
||
* Contains a list of cleanup callbacks.
|
||
*
|
||
* @var callable[]
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
protected static $cleanup_hooks = array();
|
||
|
||
/**
|
||
* Keeps an instance of the class, for temporary purposes - before switching to entirely static methods
|
||
*
|
||
* @var WpSecurityAuditLog
|
||
*
|
||
* @since 5.1.0
|
||
*/
|
||
private static $instance = null;
|
||
|
||
/**
|
||
* Standard singleton pattern.
|
||
*
|
||
* WARNING! To ensure the system always works as expected, AVOID using this method.
|
||
* Instead, make use of the plugin instance provided by 'wsal_init' action.
|
||
*
|
||
* @return WpSecurityAuditLog Returns the current plugin instance.
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function get_instance() {
|
||
if ( ! self::$instance ) {
|
||
global $wsal_class;
|
||
if ( null !== $wsal_class ) {
|
||
self::$instance = $wsal_class;
|
||
|
||
} else {
|
||
self::$instance = new self();
|
||
}
|
||
}
|
||
return self::$instance;
|
||
}
|
||
|
||
/**
|
||
* That is for backward compatibilities - probably it can be removed now
|
||
*
|
||
* @return \WpSecurityAuditLog
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function getInstance() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
|
||
if ( method_exists( 'WSAL\Controllers\Plugin_Extensions', 'deactivate_plugins' ) ) {
|
||
Plugin_Extensions::deactivate_plugins();
|
||
} else {
|
||
set_transient( 'wsal_deactivate_plugins', true );
|
||
}
|
||
|
||
static $instance = null;
|
||
if ( ! $instance ) {
|
||
$instance = new self();
|
||
}
|
||
return $instance;
|
||
}
|
||
|
||
/**
|
||
* Initialize plugin.
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public function __construct() {
|
||
|
||
$bootstrap_hook = array( 'plugins_loaded', 9 );
|
||
|
||
\add_action( $bootstrap_hook[0], array( Sensors_Load_Manager::class, 'load_early_sensors' ), $bootstrap_hook[1] );
|
||
|
||
\add_action( $bootstrap_hook[0], array( __CLASS__, 'setup' ), $bootstrap_hook[1] );
|
||
|
||
// Register plugin specific activation hook.
|
||
\register_activation_hook( WSAL_BASE_NAME, array( __CLASS__, 'install' ) );
|
||
|
||
// Plugin Deactivation Actions.
|
||
\register_deactivation_hook( WSAL_BASE_NAME, array( __CLASS__, 'deactivate_actions' ) );
|
||
|
||
// @free:start
|
||
\register_uninstall_hook( WSAL_BASE_NAME, array( Uninstall_Helper::class, 'uninstall' ) );
|
||
// @free:end
|
||
|
||
|
||
MainWP_Addon::init();
|
||
|
||
// Register hooks for plugin active cache invalidation (for multisite performance).
|
||
WP_Helper::register_is_plugin_active_cache_hooks();
|
||
|
||
// Hide all unrelated to the plugin notices on the plugin admin pages.
|
||
\add_action( 'admin_print_scripts', array( WP_Helper::class, 'hide_unrelated_notices' ) );
|
||
|
||
\add_action(
|
||
'after_setup_theme',
|
||
function () {
|
||
Migration::migrate();
|
||
|
||
self::init_freemius();
|
||
self::init();
|
||
|
||
Alert_Manager::init();
|
||
Sensors_Load_Manager::load_sensors();
|
||
self::load_defaults();
|
||
},
|
||
0
|
||
);
|
||
|
||
\add_action( 'admin_init', array( __CLASS__, 'wsal_plugin_redirect' ) );
|
||
|
||
\add_action( 'admin_init', array( __CLASS__, 'maybe_sync_premium_freemius' ) );
|
||
}
|
||
|
||
/**
|
||
* Whether the current request is a REST API request.
|
||
*
|
||
* @return bool
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function is_rest_api() {
|
||
if (
|
||
( defined( 'REST_REQUEST' ) && REST_REQUEST )
|
||
|| ! empty( $_GET['rest_route'] ) // phpcs:ignore
|
||
) {
|
||
return true;
|
||
}
|
||
|
||
if ( ! get_option( 'permalink_structure' ) ) {
|
||
return false;
|
||
}
|
||
|
||
/*
|
||
* This is needed because, if called early, global $wp_rewrite is not defined but required
|
||
* by get_rest_url(). WP will reuse what we set here, or in worst case will replace, but no
|
||
* consequences for us in any case.
|
||
*/
|
||
if ( empty( $GLOBALS['wp_rewrite'] ) ) {
|
||
$GLOBALS['wp_rewrite'] = new \WP_Rewrite(); // phpcs:ignore -- WordPress.WP.GlobalVariablesOverride.Prohibited
|
||
}
|
||
|
||
$current_path = trim( (string) parse_url( (string) add_query_arg( array() ), PHP_URL_PATH ), '/' ) . '/'; // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url
|
||
$rest_path = trim( (string) parse_url( (string) get_rest_url(), PHP_URL_PATH ), '/' ) . '/'; // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url
|
||
|
||
return strpos( $current_path, $rest_path ) === 0;
|
||
}
|
||
|
||
/**
|
||
* Whether the current request is a frontend request.
|
||
*
|
||
* @return bool
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function is_frontend() {
|
||
return ! is_admin()
|
||
&& ! WP_Helper::is_login_screen()
|
||
&& ( ! defined( 'WP_CLI' ) || ! \WP_CLI )
|
||
&& ( ! defined( 'DOING_CRON' ) || ! DOING_CRON )
|
||
&& ! self::is_rest_api()
|
||
&& ! self::is_admin_blocking_plugins_support_enabled();
|
||
}
|
||
|
||
/**
|
||
* Decides if the plugin should run, sets up constants, includes, inits hooks, etc.
|
||
*
|
||
* @return bool
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function setup() {
|
||
if ( ! self::should_load() ) {
|
||
return;
|
||
}
|
||
|
||
self::includes();
|
||
|
||
if ( \class_exists( 'WSAL\Migration\Metadata_Migration_440' ) && ! empty( WP_Helper::get_global_option( Metadata_Migration_440::OPTION_NAME_MIGRATION_INFO, array() ) ) ) {
|
||
|
||
// ( new Metadata_Migration_440( 'local' ) )->task(['connection'=>'local','batch_size'=>50,'processed_events_count'=>0]);
|
||
new Metadata_Migration_440( 'local' );
|
||
|
||
new Metadata_Migration_440( 'external' );
|
||
new Metadata_Migration_440( 'archive' );
|
||
|
||
$get_migration_connections = (array) WP_Helper::get_global_option( Metadata_Migration_440::OPTION_NAME_MIGRATION_INFO, array() );
|
||
|
||
foreach ( array_keys( $get_migration_connections ) as $connection_name ) {
|
||
if ( true === in_array( $connection_name, array( 'local', 'external', 'archive' ), true ) ) {
|
||
continue;
|
||
}
|
||
|
||
new Metadata_Migration_440( $connection_name );
|
||
}
|
||
|
||
\add_action( 'all_admin_notices', array( Metadata_Migration_440::class, 'maybe_display_progress_admin_notice' ) );
|
||
}
|
||
|
||
self::init_hooks();
|
||
|
||
\add_action( 'after_setup_theme', array( __CLASS__, 'load_wsal' ) );
|
||
}
|
||
|
||
/**
|
||
* Returns whether the plugin should load.
|
||
*
|
||
* @return bool Whether the plugin should load.
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
private static function should_load() {
|
||
// Always load on the admin, except for the scenario when this plugin is being updated.
|
||
if ( \is_admin() ) {
|
||
$acceptable_slugs = array(
|
||
'wp-security-audit-log',
|
||
'wp-activity-log',
|
||
);
|
||
|
||
// Check if this plugin is being updated from the plugin list.
|
||
if ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['slug'] ) && 'update-plugin' === trim( \sanitize_text_field( \wp_unslash( $_REQUEST['action'] ) ) )
|
||
&& in_array( trim( \sanitize_text_field( \wp_unslash( $_REQUEST['slug'] ) ) ), $acceptable_slugs ) ) {
|
||
return false;
|
||
}
|
||
|
||
// Check if this plugin is being updated using the file upload method.
|
||
if ( isset( $_REQUEST['action'] ) && 'upload-plugin' === trim( \sanitize_text_field( \wp_unslash( $_REQUEST['action'] ) ) )
|
||
&& isset( $_REQUEST['overwrite'] ) && 'update-plugin' === trim( \sanitize_text_field( \wp_unslash( $_REQUEST['overwrite'] ) ) )
|
||
&& isset( $_REQUEST['package'] ) ) {
|
||
/**
|
||
* Request doesn't contain the file name, but a numeric package ID.
|
||
*
|
||
* @see File_Upload_Upgrader::__construct()
|
||
*/
|
||
$post_id = (int) $_REQUEST['package'];
|
||
$attachment = \get_post( $post_id );
|
||
if ( ! empty( $attachment ) ) {
|
||
$filename = $attachment->post_title;
|
||
foreach ( $acceptable_slugs as $acceptable_slug ) {
|
||
if ( false !== strpos( $filename, $acceptable_slug ) ) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Check if this plugin is being updated from the WordPress updated screen (update-core.php).
|
||
if ( isset( $_REQUEST['action'] ) && 'do-plugin-upgrade' === trim( \sanitize_text_field( \wp_unslash( $_REQUEST['action'] ) ) ) ) {
|
||
if ( isset( $_REQUEST['checked'] ) ) {
|
||
$selected_plugins = $_REQUEST['checked']; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||
if ( ! empty( $selected_plugins ) ) {
|
||
foreach ( $selected_plugins as $selected_plugin ) {
|
||
if ( 'wp-security-audit-log.php' === basename( trim( \sanitize_text_field( \wp_unslash( $selected_plugin ) ) ) ) ) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
// Check conditions for frontend.
|
||
if ( self::is_frontend() && ! \is_user_logged_in() && ! self::should_load_frontend() ) {
|
||
// User isn't logged in, and we aren't logging visitor events on front-end.
|
||
return false;
|
||
}
|
||
|
||
// Other contexts/scenarios.
|
||
if ( self::is_rest_api() ) {
|
||
return \is_user_logged_in();
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Checks to see if WSAL should be loaded for register, login, and comment events.
|
||
*
|
||
* @return bool
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function should_load_frontend() {
|
||
$frontend_events = Settings_Helper::get_frontend_events();
|
||
$should_load = ! empty( $frontend_events['register'] ) || ! empty( $frontend_events['login'] ) || ! empty( $frontend_events['woocommerce'] || ! empty( $frontend_events['gravityforms'] ) );
|
||
|
||
// Allow extensions to manually allow a sensor to load.
|
||
return apply_filters( 'wsal_load_on_frontend', $should_load, $frontend_events );
|
||
}
|
||
|
||
/**
|
||
* Include Plugin Files.
|
||
|
||
* Initialize Plugin Hooks.
|
||
*
|
||
* @since 3.3
|
||
*/
|
||
private static function init_hooks() {
|
||
|
||
// Setup screen options. Needs to be here as admin_init hook it too late.
|
||
\add_filter( 'set-screen-option', array( List_Events::class, 'set_screen_option' ), 10, 3 );
|
||
|
||
\add_action( 'current_screen', array( Upgrade_Notice::class, 'init' ) );
|
||
|
||
// Listen for cleanup event.
|
||
\add_action( 'wsal_cleanup', array( __CLASS__, 'clean_up' ) );
|
||
|
||
\add_action( 'shutdown', array( __CLASS__, 'close_external_connection' ), 999 );
|
||
|
||
// Render wsal footer.
|
||
\add_action( 'admin_footer', array( __CLASS__, 'render_footer' ) );
|
||
|
||
// Handle admin Disable Custom Field.
|
||
\add_action( 'wp_ajax_AjaxDisableCustomField', array( __CLASS__, 'ajax_disable_custom_field' ) );
|
||
|
||
// Handle admin Disable Alerts.
|
||
\add_action( 'wp_ajax_AjaxDisableByCode', array( __CLASS__, 'ajax_disable_by_code' ) );
|
||
|
||
// Render Login Page Notification.
|
||
\add_filter( 'login_message', array( __CLASS__, 'render_login_page_message' ), 10, 1 );
|
||
|
||
\add_filter( 'mainwp_child_extra_execution', array( '\WSAL\MainWP\MainWP_API', 'retrieve_info_call_back' ), 10, 2 );
|
||
|
||
\add_action( 'wsal_freemius_loaded', array( __CLASS__, 'adjust_freemius_strings' ) );
|
||
|
||
add_filter( 'plugins_api_result', array( __CLASS__, 'filter_default_no_plugin_error' ), 10, 3 );
|
||
|
||
Cron_Jobs::init();
|
||
|
||
// Extensions which are only admin based.
|
||
if ( \is_admin() ) {
|
||
Plugin_Installer::init();
|
||
|
||
Feedback_Form::init();
|
||
}
|
||
|
||
Plugin_Extensions::init();
|
||
|
||
Notices::init_ajax_hooks();
|
||
|
||
// Dequeue conflicting scripts.
|
||
\add_action( 'wp_print_scripts', array( __CLASS__, 'dequeue_conflicting_scripts' ) );
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* Load Freemius SDK.
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function load_freemius() {
|
||
if ( file_exists( WSAL_BASE_DIR . '/sdk/wsal-freemius.php' ) ) {
|
||
require_once WSAL_BASE_DIR . '/sdk/wsal-freemius.php';
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check if MainWP plugin is active or not.
|
||
*
|
||
* @return boolean
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function is_mainwp_active() {
|
||
$active = WP_Helper::is_plugin_active( 'mainwp-child/mainwp-child.php' );
|
||
|
||
if ( WP_Helper::is_multisite() ) {
|
||
// Check if the plugin is active on the main site.
|
||
if ( ! defined( '\MAINWP_CHILD_URL' ) ) {
|
||
$active = false;
|
||
} else {
|
||
$active = true;
|
||
}
|
||
}
|
||
|
||
return $active;
|
||
}
|
||
|
||
/**
|
||
* Initializes Freemius and its hooks, conditionally.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
private static function init_freemius() {
|
||
|
||
$is_admin_blocking_plugins_support_enabled = self::is_admin_blocking_plugins_support_enabled();
|
||
if ( self::is_frontend() && self::is_premium_freemius() && file_exists( WSAL_BASE_DIR . '/extensions/class-wsal-extension-manager.php' ) ) {
|
||
|
||
if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
|
||
\WSAL_Extension_Manager::include_extension( 'reports' );
|
||
\WSAL_Extension_Manager::include_extension( 'usersessions' );
|
||
\WSAL_Extension_Manager::include_extension( 'external-db' );
|
||
} elseif ( self::should_load() ) {
|
||
\WSAL_Extension_Manager::include_extension( 'notifications' );
|
||
\WSAL_Extension_Manager::include_extension( 'external-db' );
|
||
}
|
||
|
||
if ( ! $is_admin_blocking_plugins_support_enabled ) {
|
||
// We only stop here if the support for admin blocking plugins is enabled.
|
||
return;
|
||
}
|
||
}
|
||
|
||
if ( $is_admin_blocking_plugins_support_enabled || is_admin() || WP_Helper::is_login_screen() || self::is_rest_api() || ( defined( 'DOING_CRON' ) && DOING_CRON ) || ( defined( 'WP_CLI' ) && \WP_CLI ) ) {
|
||
|
||
self::load_freemius();
|
||
|
||
if ( ! apply_filters( 'wsal_disable_freemius_sdk', false ) ) {
|
||
// Add filters to customize freemius welcome message.
|
||
wsal_freemius()->add_filter( 'connect_message', array( __CLASS__, 'wsal_freemius_connect_message' ), 10, 6 );
|
||
wsal_freemius()->add_filter( 'connect_message_on_update', array( __CLASS__, 'wsal_freemius_update_connect_message' ), 10, 6 );
|
||
wsal_freemius()->add_filter( 'show_admin_notice', array( __CLASS__, 'freemius_show_admin_notice' ), 10, 2 );
|
||
wsal_freemius()->add_filter( 'show_delegation_option', '__return_false' );
|
||
wsal_freemius()->add_filter( 'enable_per_site_activation', '__return_false' );
|
||
wsal_freemius()->add_filter( 'show_trial', '__return_false' );
|
||
wsal_freemius()->add_filter( 'opt_in_error_message', array( __CLASS__, 'limited_license_activation_error' ), 10, 1 );
|
||
wsal_freemius()->add_action( 'after_account_plan_sync', array( __CLASS__, 'sync_premium_freemius' ), 10, 1 );
|
||
wsal_freemius()->add_action( 'after_premium_version_activation', array( __CLASS__, 'sync_premium_freemius' ) );
|
||
wsal_freemius()->add_filter(
|
||
'plugin_icon',
|
||
function ( $plugin_icon ) {
|
||
return WSAL_BASE_DIR . 'img/wsal-logo@2x.png';
|
||
}
|
||
);
|
||
wsal_freemius()->add_action( 'is_submenu_visible', array( __CLASS__, 'hide_freemius_submenu_items' ), 10, 2 );
|
||
wsal_freemius()->add_filter(
|
||
'freemius_pricing_js_path',
|
||
function ( $default_pricing_js_path ) {
|
||
return WSAL_BASE_DIR . 'js/freemius-pricing/freemius-pricing.js';
|
||
}
|
||
);
|
||
wsal_freemius()->add_filter( 'default_to_anonymous_feedback', '__return_true' );
|
||
wsal_freemius()->add_filter( 'show_deactivation_feedback_form', '__return_false' );
|
||
|
||
wsal_freemius()->add_filter(
|
||
'pricing_url',
|
||
function ( $url ) {
|
||
return 'https://melapress.com/wordpress-activity-log/pricing/?&utm_source=plugin&utm_medium=link&utm_campaign=wsal';
|
||
}
|
||
);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Method: WSAL plugin redirect.
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function wsal_plugin_redirect() {
|
||
// Plugin redirect on activation.
|
||
|
||
if ( false === Settings_Helper::get_option_value( 'redirect_on_activate', false ) ) {
|
||
return;
|
||
}
|
||
|
||
$restrict_to = Settings_Helper::get_option_value( 'restrict-plugin-settings', 'only_admins' );
|
||
|
||
if ( ( 'only_admins' === $restrict_to && \current_user_can( 'manage_options' ) ) || ( 'only_me' === $restrict_to && (int) Settings_Helper::get_option_value( 'only-me-user-id' ) === (int) get_current_user_id() ) ) {
|
||
// WSAL State.
|
||
$wsal_state = Settings_Helper::get_option_value( 'freemius_state', 'anonymous' );
|
||
|
||
if (
|
||
in_array( $wsal_state, array( 'anonymous', 'skipped' ), true ) && Settings_Helper::get_option_value( 'redirect_on_activate', false ) // Redirect flag.
|
||
) {
|
||
// If the redirect option is true, then continue.
|
||
Settings_Helper::delete_option_value( 'wsal_redirect_on_activate' ); // Delete redirect option.
|
||
|
||
// Redirect URL.
|
||
$redirect = '';
|
||
|
||
// Otherwise, redirect to main audit log view.
|
||
$redirect = self::get_plugin_admin_url_page();
|
||
|
||
\wp_safe_redirect( $redirect );
|
||
exit();
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Method: Include extensions for premium version.
|
||
*
|
||
* @since 2.7.0
|
||
*/
|
||
private static function include_extensions__premium_only() {
|
||
// Initiate the extensions' manager.
|
||
\WSAL_Extension_Manager::init();
|
||
}
|
||
|
||
/**
|
||
* Customize Freemius connect message for new users.
|
||
*
|
||
* @param string $message - Connect message.
|
||
* @param string $user_first_name - User first name.
|
||
* @param string $plugin_title - Plugin title.
|
||
* @param string $user_login - Username.
|
||
* @param string $site_link - Site link.
|
||
* @param string $_freemius_link - Freemius link.
|
||
*
|
||
* @return string
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function wsal_freemius_connect_message( $message, $user_first_name, $plugin_title, $user_login, $site_link, $_freemius_link ) {
|
||
$result = sprintf(
|
||
/* translators: User's first name */
|
||
esc_html__( 'Hey %s', 'wp-security-audit-log' ),
|
||
$user_first_name
|
||
);
|
||
$result .= ',<br>';
|
||
$result .= esc_html__( 'Never miss an important update! Opt-in to our security and feature updates notifications, and non-sensitive diagnostic tracking with freemius.com.', 'wp-security-audit-log' ) .
|
||
$result .= '<br /><br /><strong>' . esc_html__( 'Note: ', 'wp-security-audit-log' ) . '</strong>';
|
||
$result .= esc_html__( 'NO ACTIVITY LOG ACTIVITY & DATA IS SENT BACK TO OUR SERVERS.', 'wp-security-audit-log' );
|
||
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Customize Freemius connect message on update.
|
||
*
|
||
* @param string $message - Connect message.
|
||
* @param string $user_first_name - User first name.
|
||
* @param string $plugin_title - Plugin title.
|
||
* @param string $user_login - Username.
|
||
* @param string $site_link - Site link.
|
||
* @param string $_freemius_link - Freemius link.
|
||
*
|
||
* @return string
|
||
*
|
||
* @since 4.3.4
|
||
*/
|
||
public static function wsal_freemius_update_connect_message( $message, $user_first_name, $plugin_title, $user_login, $site_link, $_freemius_link ) {
|
||
$result = sprintf(
|
||
/* tranxslators: User's first name */
|
||
esc_html__( 'Hey %s', 'wp-security-audit-log' ),
|
||
$user_first_name
|
||
);
|
||
$result .= ',<br>';
|
||
$result .= sprintf(
|
||
/* translators: 1: Plugin name. 2: Plugin name. 2: Freemius link. 4: Plugin name. */
|
||
esc_html__( 'Please help us improve %1$s! If you opt-in, some non-sensitive data about your usage of %2$s will be sent to %3$s, a diagnostic tracking service we use. If you skip this, that\'s okay! %2$s will still work just fine.', 'wp-security-audit-log' ) .
|
||
'<strong>' . $plugin_title . '</strong>',
|
||
'<strong>' . $plugin_title . '</strong>',
|
||
'<a href="https://melapress.com/support/kb/non-sensitive-diagnostic-data/" target="_blank" tabindex="1">freemius.com</a>',
|
||
'<strong>' . $plugin_title . '</strong>'
|
||
);
|
||
$result .= '<br /><br /><strong>' . esc_html__( 'Note: ', 'wp-security-audit-log' ) . '</strong>';
|
||
$result .= esc_html__( 'NO ACTIVITY LOG ACTIVITY & DATA IS SENT BACK TO OUR SERVERS.', 'wp-security-audit-log' );
|
||
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Freemius Admin Notice View Permission.
|
||
*
|
||
* Check to see if the user has permission to view Freemius admin notices or not.
|
||
*
|
||
* @param bool $show – If show then set to true, otherwise false.
|
||
* @param array $msg Message related data.
|
||
*
|
||
* @return bool
|
||
*
|
||
* @since 3.3
|
||
*/
|
||
public static function freemius_show_admin_notice( $show, $msg ) {
|
||
if ( Settings_Helper::current_user_can( 'edit' ) ) {
|
||
return $show;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Changes some of the strings that Freemius outputs with our own.
|
||
*
|
||
* @method adjust_freemius_strings
|
||
*
|
||
* @since 4.0.0
|
||
*/
|
||
public static function adjust_freemius_strings() {
|
||
// only update these messages if using premium plugin.
|
||
if ( ( ! wsal_freemius()->is_premium() ) || ( ! method_exists( wsal_freemius(), 'override_il8n' ) ) ) {
|
||
return;
|
||
}
|
||
|
||
wsal_freemius()->override_i18n(
|
||
array(
|
||
'few-plugin-tweaks' =>
|
||
// translators: The license key.
|
||
esc_html__(
|
||
'You need to activate the license key to use WP Activity Log Premium. %s',
|
||
'wp-security-audit-log'
|
||
),
|
||
'optin-x-now' => esc_html__( 'Activate the license key now', 'wp-security-audit-log' ),
|
||
)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Limited License Activation Error.
|
||
*
|
||
* @param string $error - Error Message.
|
||
*
|
||
* @return string
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function limited_license_activation_error( $error ) {
|
||
// We only process error if it's some sort of string message.
|
||
if ( ! is_string( $error ) ) {
|
||
return $error;
|
||
}
|
||
|
||
$site_count = null;
|
||
preg_match( '!\d+!', $error, $site_count );
|
||
|
||
// Check if this is an expired error.
|
||
if ( strpos( $error, 'expired' ) !== false ) {
|
||
/* Translators: Expired message and time */
|
||
$error = sprintf( esc_html__( '%s You need to renew your license to continue using premium features.', 'wp-security-audit-log' ), preg_replace( '/\([^)]+\)/', '', $error ) );
|
||
} elseif ( ! empty( $site_count[0] ) ) {
|
||
/* Translators: Number of sites */
|
||
$error = sprintf( esc_html__( 'The license is limited to %s sub-sites. You need to upgrade your license to cover all the sub-sites on this network.', 'wp-security-audit-log' ), $site_count[0] );
|
||
}
|
||
|
||
return $error;
|
||
}
|
||
|
||
/**
|
||
* Start to trigger the events after installation.
|
||
*
|
||
* @internal
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
private static function init() {
|
||
|
||
if ( \is_admin() ) {
|
||
View_Manager::init();
|
||
|
||
Widget_Manager::init();
|
||
}
|
||
|
||
// Reports.
|
||
if ( \class_exists( Notifications::class ) ) {
|
||
Notifications::init();
|
||
}
|
||
|
||
if ( \is_admin() ) {
|
||
|
||
// Hide plugin.
|
||
if ( Settings_Helper::get_boolean_option_value( 'hide-plugin' ) ) {
|
||
\add_action( 'admin_head', array( __CLASS__, 'hide_plugin' ) );
|
||
\add_filter( 'all_plugins', array( __CLASS__, 'wsal_hide_plugin' ) );
|
||
}
|
||
}
|
||
|
||
global $wsal_class;
|
||
|
||
/**
|
||
* Action: `wsal_init`
|
||
*
|
||
* Action hook to mark that WSAL has initialized.
|
||
*
|
||
* @param WpSecurityAuditLog $this – Instance of main plugin class.
|
||
*/
|
||
\do_action( 'wsal_init', $wsal_class );
|
||
|
||
// \add_action( 'init', array( Migration::class, 'migrate' ), PHP_INT_MAX );
|
||
|
||
if ( defined( '\WP_CLI' ) && \WP_CLI ) {
|
||
\WP_CLI::add_command( 'wsal_cli_commands', '\WSAL\Controllers\WP_CLI\WP_CLI_Commands' );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Plugin Deactivation Actions.
|
||
*
|
||
* This function runs on plugin deactivation.
|
||
*
|
||
* @param bool $network_wide - Whether the plugin is being deactivated for the entire network.
|
||
*
|
||
* @return void
|
||
*
|
||
* @since 3.3.1
|
||
* @since 5.6.2 Unschedule all cron jobs on deactivation, including per-site on multisite.
|
||
*/
|
||
public static function deactivate_actions( $network_wide = false ) {
|
||
|
||
Cron_Jobs::unschedule_all_cron_jobs( $network_wide );
|
||
|
||
/**
|
||
* Allow short-circuiting of the deactivation email sending by using
|
||
* this filter to return true here instead of default false.
|
||
*
|
||
* @since 3.5.2
|
||
*
|
||
* @var bool
|
||
*/
|
||
if ( apply_filters( 'wsal_filter_prevent_deactivation_email_delivery', false ) ) {
|
||
return;
|
||
}
|
||
|
||
// Send deactivation email.
|
||
if ( \class_exists( '\WSAL\Helpers\Email_Helper', false ) ) {
|
||
// Get email template.
|
||
Email_Helper::send_deactivation_email();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Disable Custom Field through ajax.
|
||
*
|
||
* @internal
|
||
*
|
||
* @since 5.0.0
|
||
* @since 5.6.0 - Return JSON payload instead of HTML.
|
||
*/
|
||
public static function ajax_disable_custom_field() {
|
||
if ( ! Settings_Helper::current_user_can( 'edit' ) ) {
|
||
\wp_send_json_error(
|
||
array(
|
||
'message' => \esc_html__( 'Error: You do not have sufficient permissions to disable this custom field.', 'wp-security-audit-log' ),
|
||
),
|
||
403
|
||
);
|
||
}
|
||
|
||
$notice = \sanitize_text_field( \wp_unslash( $_POST['notice'] ?? '' ) );
|
||
|
||
$nonce_is_valid = \check_ajax_referer( 'disable-custom-nonce' . $notice, 'disable_nonce', false );
|
||
|
||
if ( false === $nonce_is_valid ) {
|
||
\wp_send_json_error(
|
||
array(
|
||
'message' => \esc_html__( 'Error: Invalid nonce.', 'wp-security-audit-log' ),
|
||
),
|
||
403
|
||
);
|
||
}
|
||
|
||
$notice = \str_replace( array( "'", '"', ',' ), '', $notice );
|
||
|
||
// Validate object type.
|
||
$object_type_post = \sanitize_text_field( \wp_unslash( $_POST['object_type'] ?? '' ) );
|
||
$object_type = ( 'user' === $object_type_post ) ? 'user' : 'post';
|
||
$excluded_meta = array();
|
||
|
||
// Get current excluded meta fields.
|
||
if ( 'post' === $object_type ) {
|
||
$excluded_meta = Settings_Helper::get_excluded_post_meta_fields();
|
||
} elseif ( 'user' === $object_type ) {
|
||
$excluded_meta = Settings_Helper::get_excluded_user_meta_fields();
|
||
}
|
||
|
||
// Add the new field to the array.
|
||
if ( ! \in_array( $notice, $excluded_meta, true ) ) {
|
||
$excluded_meta[] = $notice;
|
||
}
|
||
|
||
// Save updated excluded meta fields.
|
||
if ( 'post' === $object_type ) {
|
||
Settings_Helper::set_excluded_post_meta_fields( $excluded_meta );
|
||
} elseif ( 'user' === $object_type ) {
|
||
Settings_Helper::set_excluded_user_meta_fields( $excluded_meta );
|
||
}
|
||
|
||
/**
|
||
* Build response messages. These will end up inside <p> tags on the JS side.
|
||
*/
|
||
// Message 1: "Custom field [FIELD_NAME] is no longer being monitored.".
|
||
/* translators: %s: Custom field name */
|
||
$message_1 = \esc_html__( 'Custom field %s is no longer being monitored.', 'wp-security-audit-log' );
|
||
$p1_parts = \explode( '%s', $message_1, 2 );
|
||
$p1_parts = ( 2 === count( $p1_parts ) ) ? $p1_parts : array( $message_1, '' );
|
||
|
||
// Message 2: "Enable monitoring again from the [TAB_NAME] tab in settings.".
|
||
/* translators: %s: Settings tab name */
|
||
$message_2 = \esc_html__( 'Enable the monitoring of this custom field again from the %s tab in the plugin settings.', 'wp-security-audit-log' );
|
||
$p2_parts = \explode( '%s', $message_2, 2 );
|
||
$p2_parts = ( 2 === count( $p2_parts ) ) ? $p2_parts : array( $message_2, '' );
|
||
|
||
// Exclude object settings link.
|
||
$exclude_objects_link = \add_query_arg(
|
||
array(
|
||
'page' => 'wsal-settings',
|
||
'tab' => 'exclude-objects',
|
||
),
|
||
\network_admin_url( 'admin.php' )
|
||
);
|
||
|
||
\wp_send_json_success(
|
||
array(
|
||
'notice' => $notice,
|
||
'settings_url' => \esc_url_raw( $exclude_objects_link ),
|
||
'tab_label' => \esc_html__( 'Excluded Objects', 'wp-security-audit-log' ),
|
||
'p1_parts' => $p1_parts,
|
||
'p2_parts' => $p2_parts,
|
||
)
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Disable Alert through ajax.
|
||
*
|
||
* @internal
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function ajax_disable_by_code() {
|
||
// Die if user does not have permission to disable.
|
||
if ( ! Settings_Helper::current_user_can( 'edit' ) ) {
|
||
echo '<p>' . esc_html__( 'Error: You do not have sufficient permissions to disable this alert.', 'wp-security-audit-log' ) . '</p>';
|
||
die();
|
||
}
|
||
|
||
$disable_nonce = ( isset( $_POST['disable_nonce'] ) ) ? \sanitize_text_field( \wp_unslash( $_POST['disable_nonce'] ) ) : null;
|
||
$code = ( isset( $_POST['code'] ) ) ? \sanitize_text_field( \wp_unslash( $_POST['code'] ) ) : null;
|
||
|
||
if ( ! isset( $disable_nonce ) || ! \wp_verify_nonce( $disable_nonce, 'disable-alert-nonce' . $code ) ) {
|
||
die();
|
||
}
|
||
|
||
$s_alerts = Settings_Helper::get_option_value( 'disabled-alerts' );
|
||
|
||
if ( is_string( $s_alerts ) ) {
|
||
$s_alerts = \array_filter( \array_map( 'trim', \explode( ',', $s_alerts ) ) );
|
||
}
|
||
|
||
if ( isset( $s_alerts ) && '' !== $s_alerts ) {
|
||
$s_alerts[] = (int) esc_html( $code );
|
||
|
||
Settings_Helper::set_disabled_alerts( $s_alerts );
|
||
}
|
||
|
||
echo wp_sprintf(
|
||
// translators: Alert code which is no longer monitored.
|
||
'<p>' . esc_html__( 'Alert %1$s is no longer being monitored. %2$s', 'wp-security-audit-log' ) . '</p>',
|
||
\esc_html( $code ),
|
||
'<br />' . esc_html__( 'You can enable this alert again from the Enable/Disable Alerts node in the plugin menu.', 'wp-security-audit-log' )
|
||
);
|
||
die;
|
||
}
|
||
|
||
/**
|
||
* Render plugin stuff in page footer.
|
||
*
|
||
* @internal
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function render_footer() {
|
||
// File is not there / deleted during upgrade ? either way stop the execution.
|
||
if ( ! file_exists( WSAL_BASE_DIR . '/js/common.js' ) ) {
|
||
return;
|
||
}
|
||
|
||
// Register common script.
|
||
wp_register_script(
|
||
'wsal-common',
|
||
WSAL_BASE_URL . 'js/common.js',
|
||
array( 'jquery' ),
|
||
WSAL_VERSION,
|
||
true
|
||
);
|
||
|
||
// Live events disabled in free version of the plugin.
|
||
$live_events_enabled = false;
|
||
// Set data array for common script.
|
||
$script_data = array(
|
||
'ajaxURL' => \admin_url( 'admin-ajax.php' ),
|
||
'liveEvents' => $live_events_enabled,
|
||
'installing' => esc_html__( 'Installing, please wait', 'wp-security-audit-log' ),
|
||
'already_installed' => esc_html__( 'Already installed', 'wp-security-audit-log' ),
|
||
'installed' => esc_html__( 'Extension installed', 'wp-security-audit-log' ),
|
||
'activated' => esc_html__( 'Extension activated', 'wp-security-audit-log' ),
|
||
'failed' => esc_html__( 'Install failed', 'wp-security-audit-log' ),
|
||
'reloading_page' => esc_html__( 'Reloading page', 'wp-security-audit-log' ),
|
||
'dismissNoticeNonce' => \wp_create_nonce( 'wsal-dismiss-notice' ),
|
||
);
|
||
|
||
|
||
\wp_localize_script( 'wsal-common', 'wsalCommonData', $script_data );
|
||
|
||
// Enqueue script.
|
||
\wp_enqueue_script( 'wsal-common' );
|
||
|
||
?>
|
||
<style>
|
||
.toplevel_page_wsal-auditlog.menu-top div.wp-menu-image.svg {
|
||
opacity: 0.6;
|
||
}
|
||
|
||
.toplevel_page_wsal-auditlog.menu-top.wp-has-current-submenu div.wp-menu-image.svg,
|
||
.toplevel_page_wsal-auditlog.menu-top.wp-has-submenu:hover div.wp-menu-image.svg {
|
||
opacity: 1;
|
||
}
|
||
</style>
|
||
<?php
|
||
}
|
||
|
||
/**
|
||
* Load the rest of the system.
|
||
*
|
||
* @internal
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function load_wsal() {
|
||
|
||
// if ( is_admin() ) {
|
||
|
||
// Load translations.
|
||
load_plugin_textdomain( 'wp-security-audit-log', false, WSAL_BASE_DIR . '/languages/' );
|
||
// }
|
||
}
|
||
|
||
/**
|
||
* Installs all assets required for a usable system.
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function install() {
|
||
$installation_errors = false;
|
||
|
||
// Check for minimum PHP version.
|
||
if ( version_compare( PHP_VERSION, self::MIN_PHP_VERSION ) < 0 ) {
|
||
/* Translators: %s: PHP Version */
|
||
$installation_errors = sprintf( \esc_html__( 'You are using a version of PHP that is older than %s, which is no longer supported.', 'wp-security-audit-log' ), \esc_html( self::MIN_PHP_VERSION ) );
|
||
$installation_errors .= '<br />';
|
||
$installation_errors .= __( 'Contact us on <a href="mailto:plugins@melapress.com">plugins@melapress.com</a> to help you switch the version of PHP you are using.', 'wp-security-audit-log' );
|
||
}
|
||
|
||
if ( $installation_errors ) {
|
||
?>
|
||
<html>
|
||
<head><style>body{margin:0;}.warn-icon-tri{top:7px;left:5px;position:absolute;border-left:16px solid #FFF;border-right:16px solid #FFF;border-bottom:28px solid #C33;height:3px;width:4px}.warn-icon-chr{top:10px;left:18px;position:absolute;color:#FFF;font:26px Georgia}.warn-icon-cir{top:4px;left:0;position:absolute;overflow:hidden;border:6px solid #FFF;border-radius:32px;width:34px;height:34px}.warn-wrap{position:relative;font-size:13px;font-family:sans-serif;padding:6px 48px;line-height:1.4;}</style></head>
|
||
<body><div class="warn-wrap"><div class="warn-icon-tri"></div><div class="warn-icon-chr">!</div><div class="warn-icon-cir"></div><span><?php echo $installation_errors; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span></div></body>
|
||
</html>
|
||
<?php
|
||
die( 1 );
|
||
}
|
||
|
||
// Update licensing info in case we're swapping from free to premium or vice-versa.
|
||
self::sync_premium_freemius();
|
||
|
||
// Disable database sensor during the creation of tables.
|
||
WP_Database_Sensor::set_enabled( false );
|
||
|
||
// WSAL Audit Log page redirect option in anonymous mode.
|
||
if ( 'anonymous' === Settings_Helper::get_option_value( 'freemius_state', 'anonymous' ) ) {
|
||
Settings_Helper::set_option_value( 'redirect_on_activate', true );
|
||
}
|
||
|
||
// Run on each install to check MainWP Child plugin.
|
||
Plugin_Settings_Helper::set_mainwp_child_stealth_mode();
|
||
|
||
// Re-enable the database sensor after the tables are created.
|
||
WP_Database_Sensor::set_enabled( true );
|
||
}
|
||
|
||
/**
|
||
* To be called in admin header for hiding plugin form Plugins list.
|
||
*
|
||
* @internal
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function hide_plugin() {
|
||
if ( ! Settings_Helper::current_user_can( 'edit' ) ) {
|
||
$selectr = '';
|
||
$plugins = array( 'wp-security-audit-log', 'wp-security-audit-log-premium' );
|
||
foreach ( $plugins as $value ) {
|
||
$selectr .= '.wp-list-table.plugins tr[data-slug="' . $value . '"], ';
|
||
}
|
||
?>
|
||
<style type="text/css">
|
||
<?php echo \esc_attr( rtrim( $selectr, ', ' ) ); ?> { display: none; }
|
||
</style>
|
||
<?php
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Run cleanup routines.
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function clean_up() {
|
||
foreach ( self::$cleanup_hooks as $hook ) {
|
||
call_user_func( $hook );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Add callback to be called when a cleanup operation is required.
|
||
*
|
||
* @param callable $hook - Hook name.
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function add_cleanup_hook( $hook ) {
|
||
self::$cleanup_hooks[] = $hook;
|
||
}
|
||
|
||
/**
|
||
* Remove a callback from the cleanup callbacks list.
|
||
*
|
||
* @param callable $hook - Hook name.
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function remove_cleanup_hook( $hook ) {
|
||
while ( ( $pos = array_search( $hook, self::$cleanup_hooks ) ) !== false ) {
|
||
unset( self::$cleanup_hooks[ $pos ] );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Load default configuration / data.
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function load_defaults() {
|
||
Constants::init();
|
||
|
||
require_once WSAL_BASE_DIR . 'defaults.php';
|
||
}
|
||
|
||
/**
|
||
* Method: Render login page message.
|
||
*
|
||
* @param string $message - Login message.
|
||
*
|
||
* @return string
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function render_login_page_message( $message ) {
|
||
// Check if the option is enabled.
|
||
$login_message_enabled = Settings_Helper::get_boolean_option_value( 'login_page_notification', false );
|
||
if ( $login_message_enabled ) {
|
||
// Get login message.
|
||
$message = Settings_Helper::get_option_value( 'login_page_notification_text', false );
|
||
|
||
// Default message.
|
||
if ( ! $message ) {
|
||
$message = '<p class="message">' . wp_kses( __( 'For security and auditing purposes, a record of all of your logged-in actions and changes within the WordPress dashboard will be recorded in an activity log with the <a href="https://melapress.com/" target="_blank">WP Activity Log plugin</a>. The audit log also includes the IP address where you accessed this site from.', 'wp-security-audit-log' ), Plugin_Settings_Helper::get_allowed_html_tags() ) . '</p>';
|
||
} else {
|
||
$message = '<p class="message">' . $message . '</p>';
|
||
}
|
||
}
|
||
|
||
// Return message.
|
||
return $message;
|
||
}
|
||
|
||
/**
|
||
* Function runs Freemius license check only if our Freemius licensing transient has already expired. This is
|
||
* intended to run on admin_init action.
|
||
*
|
||
* @since 4.3.0
|
||
*/
|
||
public static function maybe_sync_premium_freemius() {
|
||
// We don't want to slow down any AJAX requests.
|
||
if ( \wp_doing_ajax() ) {
|
||
return;
|
||
}
|
||
|
||
$freemius_transient = WP_Helper::get_transient( 'fs_wsalp' );
|
||
if ( false === $freemius_transient || ! in_array( $freemius_transient, array( 'yes', 'no' ), true ) ) {
|
||
// Transient expired or invalid.
|
||
self::sync_premium_freemius();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Runs Freemius license check, updates our db option if necessary and creates/extends a transient we use to
|
||
* optimize the check. Should run only on couple of Freemius actions related to account sync and plugin activation.
|
||
*
|
||
* It might be also called by WpSecurityAuditLog::maybe_sync_premium_freemius() if the transient is not set or valid.
|
||
*
|
||
* @see WpSecurityAuditLog::maybe_sync_premium_freemius()
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function sync_premium_freemius() {
|
||
$option_name = 'fs_wsalp';
|
||
$old_value = \get_site_option( $option_name );
|
||
|
||
// Determine new value via Freemius SDK.
|
||
$new_value = wsal_freemius()->has_active_valid_license() ? 'yes' : 'no';
|
||
|
||
// Update the db option only if the value changed.
|
||
if ( $new_value !== $old_value ) {
|
||
\update_site_option( $option_name, $new_value );
|
||
}
|
||
|
||
// Always update the transient to extend the expiration window.
|
||
WP_Helper::set_transient( $option_name, $new_value, DAY_IN_SECONDS );
|
||
}
|
||
|
||
/**
|
||
* Resource cautious function to check if the premium license is active and valid. It only checks if WordPress
|
||
* option "fs_wsalp" is present and set to true.
|
||
*
|
||
* Function is intended for quick check during initial stages of plugin bootstrap, especially on front-end.
|
||
*
|
||
* @see WpSecurityAuditLog::sync_premium_freemius()
|
||
*
|
||
* @return boolean
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function is_premium_freemius() {
|
||
return 'yes' === \get_site_option( 'fs_wsalp' );
|
||
}
|
||
|
||
/**
|
||
* Hide WSAL plugin from plugin list
|
||
*
|
||
* @param array $plugins All plugins.
|
||
*
|
||
* @return array
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function wsal_hide_plugin( $plugins ) {
|
||
global $pagenow;
|
||
|
||
// Check current page, bail early if this isn't the plugins page.
|
||
if ( 'plugins.php' !== $pagenow
|
||
&& ! ( \wp_doing_ajax() && isset( $_REQUEST['pagenow'] ) && 'plugins' === $_REQUEST['pagenow'] ) ) {
|
||
|
||
return $plugins;
|
||
}
|
||
|
||
$predefined_plugins = Plugins_Helper::get_installable_plugins();
|
||
|
||
$main_plugins = array(
|
||
'premium' => self::PREMIUM_VERSION_WHOLE_PLUGIN_NAME,
|
||
'nofs' => self::NOFS_VERSION_WHOLE_PLUGIN_NAME,
|
||
'free' => self::FREE_VERSION_WHOLE_PLUGIN_NAME,
|
||
);
|
||
|
||
foreach ( $main_plugins as $plugin_slug ) {
|
||
// Find WSAL by plugin basename.
|
||
if ( array_key_exists( $plugin_slug, $plugins ) ) {
|
||
// Remove WSAL plugin from plugin list page.
|
||
|
||
$current_version = $plugins[ $plugin_slug ]['Version'];
|
||
$latest_version = $current_version;
|
||
|
||
$update_plugins = get_site_transient( 'update_plugins' );
|
||
if ( isset( $update_plugins->response ) ) {
|
||
$plugins_to_update = (array) $update_plugins->response;
|
||
|
||
if ( isset( $plugins_to_update[ $plugin_slug ] ) ) {
|
||
$latest_version = $plugins_to_update[ $plugin_slug ]->new_version;
|
||
}
|
||
}
|
||
|
||
if ( ! version_compare( $current_version, $latest_version, '<' ) ) {
|
||
|
||
unset( $plugins[ $plugin_slug ] );
|
||
} else {
|
||
$restrict_to = Settings_Helper::get_option_value( 'restrict-plugin-settings', 'only_admins' );
|
||
|
||
$must_hide = true;
|
||
|
||
if ( ( 'only_admins' === $restrict_to && \current_user_can( 'manage_options' ) ) || ( 'only_me' === $restrict_to && (int) Settings_Helper::get_option_value( 'only-me-user-id' ) === (int) get_current_user_id() ) ) {
|
||
$must_hide = false;
|
||
}
|
||
|
||
if ( $must_hide ) {
|
||
unset( $plugins[ $plugin_slug ] );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Add the software libs to the plugins for hiding.
|
||
$predefined_plugins[] = array( 'plugin_slug' => 'wsal-external-libraries/wsal-external-libraries.php' );
|
||
|
||
// Find and hide addons.
|
||
foreach ( $predefined_plugins as $extension_plugin ) {
|
||
if ( array_key_exists( $extension_plugin['plugin_slug'], $plugins ) ) {
|
||
if ( 'website-file-changes-monitor/website-file-changes-monitor.php' !== $extension_plugin['plugin_slug'] ) {
|
||
unset( $plugins[ $extension_plugin['plugin_slug'] ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
return $plugins;
|
||
}
|
||
|
||
/**
|
||
* Use filter to hide freemius submenu items.
|
||
*
|
||
* @param boolean $is_visible Default visibility.
|
||
* @param string $submenu_id Menu slug.
|
||
*
|
||
* @return boolean New visibility.
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function hide_freemius_submenu_items( $is_visible, $submenu_id ) {
|
||
if ( 'contact' === $submenu_id ) {
|
||
$is_visible = false;
|
||
}
|
||
if ( 'pricing' === $submenu_id ) {
|
||
$is_visible = false;
|
||
}
|
||
return $is_visible;
|
||
}
|
||
|
||
/**
|
||
* Checks if the admin blocking plugins support is enabled.
|
||
*
|
||
* @see https://trello.com/c/1OCd5iKc/589-wieserdk-al4mwp-cannot-retrieve-events-when-admin-url-is-changed
|
||
* @return bool
|
||
*/
|
||
private static function is_admin_blocking_plugins_support_enabled() {
|
||
|
||
// Only meant for 404 pages, but may run before is_404 can be used.
|
||
$is_404 = ! did_action( 'wp' ) || is_404();
|
||
if ( ! $is_404 ) {
|
||
return false;
|
||
}
|
||
|
||
/*
|
||
* We assume settings have already been migrated (in version 4.1.3) to WordPress options table. We might
|
||
* miss some 404 events until the plugin upgrade runs, but that is a very rare edge case. The same applies
|
||
* to loading of 'admin-blocking-plugins-support' option further down.
|
||
*
|
||
* We do not need to worry about the missed 404s after version 4.1.5 as they were completely removed.
|
||
*/
|
||
$is_stealth_mode = Settings_Helper::get_option_value( 'mwp-child-stealth-mode', 'no' );
|
||
|
||
if ( 'yes' !== $is_stealth_mode ) {
|
||
// Only intended if MainWP stealth mode is active.
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Dequeue JS files which have been added by other plugin to all admin pages and cause conflicts.
|
||
* See https://github.com/WPWhiteSecurity/wp-security-audit-log-premium/issues/1246 and
|
||
* https://trello.com/c/pWrQn1Be/742-koenhavelaertsflintgrpcom-reports-ui-does-not-load-with-plugin-installed
|
||
*
|
||
* @since 4.1.5
|
||
*/
|
||
public static function dequeue_conflicting_scripts() {
|
||
global $current_screen;
|
||
// Only dequeue on our admin pages.
|
||
if ( isset( $current_screen->base ) && strpos( $current_screen->base, 'wp-activity-log' ) === 0 ) {
|
||
wp_deregister_script( 'dateformat' );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Closes external connection if it's being used.
|
||
*
|
||
* @since 4.3.1
|
||
*/
|
||
public static function close_external_connection() {
|
||
// If the adapter type options is not empty, it means we're using the external database.
|
||
$database_type = Settings_Helper::get_option_value( 'adapter-type' );
|
||
if ( ! is_null( $database_type ) ) {
|
||
if ( strlen( $database_type ) > 0 ) {
|
||
Connection::close_connection();
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Include Plugin Files.
|
||
*
|
||
* @since 5.0.0
|
||
*/
|
||
public static function includes() {
|
||
|
||
// Require Composer autoloader if it exists.
|
||
if ( file_exists( plugin_dir_path( __FILE__ ) . 'vendor/autoload.php' ) ) {
|
||
require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';
|
||
}
|
||
if ( file_exists( plugin_dir_path( __FILE__ ) . 'third-party/vendor/autoload.php' ) ) {
|
||
require_once plugin_dir_path( __FILE__ ) . 'third-party/vendor/autoload.php';
|
||
}
|
||
|
||
|
||
// Load action scheduler for event mirroring.
|
||
$action_scheduler_file_path = WSAL_BASE_DIR . implode(
|
||
DIRECTORY_SEPARATOR,
|
||
array(
|
||
'third-party',
|
||
'woocommerce',
|
||
'action-scheduler',
|
||
'action-scheduler.php',
|
||
)
|
||
);
|
||
|
||
if ( file_exists( $action_scheduler_file_path ) ) {
|
||
require_once $action_scheduler_file_path;
|
||
}
|
||
|
||
if ( WP_Helper::is_multisite() ) {
|
||
if ( WP_Helper::conditions() ) {
|
||
/*
|
||
* The option doesn't yet exist or it is not fresh so record CPTs
|
||
* and fire off a late storage method.
|
||
*/
|
||
WP_Helper::actions();
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Returns the the URL for the plugin admin main view - log view.
|
||
*
|
||
* @return string
|
||
*
|
||
* @since 5.1.1
|
||
*/
|
||
public static function get_plugin_admin_url_page() {
|
||
return \add_query_arg( 'page', 'wsal-auditlog', \network_admin_url( 'admin.php' ) );
|
||
}
|
||
|
||
/**
|
||
* This method tries to guess the version of the plugin based on different conditions.
|
||
*
|
||
* @return string
|
||
*
|
||
* @since 5.1.1
|
||
*/
|
||
public static function get_plugin_version(): string {
|
||
if ( defined( 'WSAL_NOFS_TOOL_PATH' ) ) {
|
||
return 'NOFS';
|
||
}
|
||
if ( function_exists( 'wsal_freemius' ) && wsal_freemius()->has_active_valid_license() ) {
|
||
return 'premium';
|
||
}
|
||
|
||
return 'free';
|
||
}
|
||
|
||
/**
|
||
* Returns an array of all plugin screens (pages).
|
||
*
|
||
* @return array
|
||
*
|
||
* @since 5.1.1
|
||
*/
|
||
public static function get_plugin_screens_array(): array {
|
||
return array(
|
||
'toplevel_page_wsal-auditlog',
|
||
'wp-activity-log_page_wsal-usersessions-views',
|
||
'wp-activity-log_page_wsal-np-notifications',
|
||
'wp-activity-log_page_wsal-rep-views-main',
|
||
'toplevel_page_wsal-auditlog-network',
|
||
'wp-activity-log_page_wsal-usersessions-views-network',
|
||
'wp-activity-log_page_wsal-np-notifications-network',
|
||
'wp-activity-log_page_wsal-rep-views-main-network',
|
||
'wp-activity-log_page_wsal-settings',
|
||
'wp-activity-log_page_wsal-settings-network',
|
||
'wp-activity-log_page_wsal-togglealerts',
|
||
'wp-activity-log_page_wsal-togglealerts-network',
|
||
'wp-activity-log_page_wsal-help',
|
||
'wp-activity-log_page_wsal-help-network',
|
||
'wp-activity-log_page_wsal-wsal-views-premium-features',
|
||
'wp-activity-log_page_wsal-wsal-views-premium-features-network',
|
||
'wp-activity-log_page_wsal-reports-new',
|
||
'wp-activity-log_page_wsal-reports-new-network',
|
||
'wp-activity-log_page_wsal-ext-settings',
|
||
'wp-activity-log_page_wsal-ext-settings-network',
|
||
'wp-activity-log_page_wsal-nofs-license',
|
||
'wp-activity-log_page_wsal-nofs-license-network',
|
||
'wp-activity-log_page_wsal-notifications',
|
||
'wp-activity-log_page_wsal-notifications-network',
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Check and filter the error screen when a plugin information is not found.
|
||
* Plugin information are not found when:
|
||
* - The plugin is not in the official WP plugin repository and is disabled.
|
||
* - The plugin is not in the official WP plugin repository and does not include a plugin information screen.
|
||
*
|
||
* This hook should filter only error screens for URLs like:
|
||
*
|
||
* /wp-admin/plugin-install.php?tab=plugin-information&plugin=plugin-slug-here&TB_iframe=true&width=640&height=600
|
||
*
|
||
* @param object|\WP_Error $result - Response object or WP_Error.
|
||
* @param string $action - The type of information being requested from the Plugin Installation API.
|
||
* @param object $args - Plugin API arguments.
|
||
*/
|
||
public static function filter_default_no_plugin_error( $result, $action, $args ) {
|
||
if ( 'plugin_information' !== $action ) {
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Proceed only if the request is coming from our plugin page.
|
||
*/
|
||
$requested_from_page = isset( $_SERVER['HTTP_REFERER'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : '';
|
||
|
||
if ( false === strpos( $requested_from_page, 'page=wsal-auditlog' ) ) {
|
||
return $result;
|
||
}
|
||
|
||
if ( is_wp_error( $result ) ) {
|
||
$error_plugin_api_failed = $result->get_error_messages( 'plugins_api_failed' );
|
||
|
||
$wsal_message = 'This plugin was not found on the repository. Most probably this is a premium plugin or a plugin that is not on the WordPress.org repository.';
|
||
$wsal_message .= '<br><br><a href="https://melapress.com/wordpress-activity-log/?utm_source=plugin&utm_medium=wsal&utm_campaign=plugin-not-found-message" target="_blank">WP Activity Log plugin</a>';
|
||
|
||
if ( $error_plugin_api_failed && trim( $error_plugin_api_failed[0] ) === 'Plugin not found.' ) {
|
||
$result->errors['plugins_api_failed'][0] = $wsal_message;
|
||
}
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
}
|
||
}
|