settings();
}
}
/**
* Return the settings object, lazily instantiating, if needed.
*
* @return WSAL_Settings
*
* @since 5.0.0
*/
public function settings() {
if ( ! isset( $this->settings ) ) {
$this->settings = new WSAL_Settings( $this );
}
return $this->settings;
}
/**
* Whether the current request is a REST API request.
*
* @return bool
*
* @since 5.0.0
*/
public static function is_rest_api() {
$is_rest = false;
if ( ! empty( $_SERVER['REQUEST_URI'] ) ) {
$rest_url_path = trim( parse_url( home_url( '/wp-json/' ), PHP_URL_PATH ), '/' );
$request_path = trim( \sanitize_text_field( \wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' );
/*
* If we have both a url and a request patch check if this is
* a rest request.
*
* @since 4.0.3
*/
if ( $rest_url_path && $request_path ) {
$is_rest = ( strpos( $request_path, $rest_url_path ) === 0 ) || isset( $_GET['rest_route'] );
}
}
return $is_rest;
}
/**
* 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();
}
/**
* Whether the current request is a frontend request.
*
* @return bool
*
* @since 5.0.0
*/
public static function is_frontend_page() {
return self::is_frontend();
}
/**
* Decides if the plugin should run, sets up constants, includes, inits hooks, etc.
*
* @return bool
*
* @since 5.0.0
*/
public 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' );
add_action( 'all_admin_notices', array( 'WSAL\Migration\Metadata_Migration_440', 'maybe_display_progress_admin_notice' ) );
}
$this->init_hooks();
self::load_defaults();
$this->load_wsal();
$this->init();
}
/**
* 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;
}
}
}
}
}
// @codingStandardsIgnoreEnd
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
*/
public function init_hooks() {
// Setup screen options. Needs to be here as admin_init hook it too late.
add_filter( 'set-screen-option', array( '\WSAL\ListAdminEvents\List_Events', 'set_screen_option' ), 10, 3 );
add_action( 'current_screen', array( '\WSAL\Helpers\Upgrade_Notice', '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 );
// Cron job to delete alert 1003 for the last day.
add_action( 'wsal_delete_logins', array( __CLASS__, 'delete_failed_logins' ) );
if ( ! wp_next_scheduled( 'wsal_delete_logins' ) ) {
wp_schedule_event( time(), 'daily', 'wsal_delete_logins' );
}
add_filter( 'mainwp_child_extra_execution', array( '\WSAL\MainWP\MainWP_API', 'retrieve_info_call_back' ), 10, 2 );
// add_filter( 'mainwp_child_extra_execution', array( new WSAL_MainWpApi( $this ), 'handle_callback' ), 10, 2 );
add_action( 'wsal_freemius_loaded', array( $this, 'adjust_freemius_strings' ) );
self::init_freemius();
// Extensions which are only admin based.
if ( is_admin() ) {
Plugin_Installer::init();
}
Plugin_Extensions::init();
Notices::init_ajax_hooks();
// Dequeue conflicting scripts.
add_action( 'wp_print_scripts', array( __CLASS__, 'dequeue_conflicting_scripts' ) );
// phpcs:disable
// phpcs:enable
}
// phpcs:disable
// phpcs:enable
/**
* Load Freemius SDK.
*
* @since 5.0.0
*/
public static function load_freemius() {
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() {
return WP_Helper::is_plugin_active( 'mainwp-child/mainwp-child.php' );
}
/**
* Check if MainWP Server plugin is active or not.
*
* @return boolean
*
* @since 5.0.0
*/
public static function is_mainwp_server_active() {
return WP_Helper::is_plugin_active( 'mainwp/mainwp.php' );
}
/**
* 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();
// phpcs:disable
// phpcs:enable
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(
'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.
$restrict_to = Settings_Helper::get_option_value( 'restrict-plugin-settings', 'only_admins' );
if ( 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 = add_query_arg( 'page', 'wsal-auditlog', \network_admin_url( 'admin.php' ) );
wp_safe_redirect( $redirect );
exit();
}
}
}
// phpcs:disable
/**
* 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 .= ',
';
$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 .= '
' . esc_html__( 'Note: ', 'wp-security-audit-log' ) . '';
$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(
/* translators: User's first name */
esc_html__( 'Hey %s', 'wp-security-audit-log' ),
$user_first_name
);
$result .= ',
';
$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' ) .
'' . $plugin_title . '',
'' . $plugin_title . '',
'freemius.com',
'' . $plugin_title . ''
);
$result .= '
' . esc_html__( 'Note: ', 'wp-security-audit-log' ) . '';
$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 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 licence 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
*/
public function init() {
if ( is_admin() ) {
View_Manager::init();
Widget_Manager::init();
}
if ( is_admin() ) {
// phpcs:disable
// 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' ) );
}
}
Constants::init();
/**
* Action: `wsal_init`
*
* Action hook to mark that WSAL has initialized.
*
* @param WpSecurityAuditLog $this – Instance of main plugin class.
*/
do_action( 'wsal_init', $this );
// Allow registration of custom alert formatters (must be called after wsal_init action).
WSAL_AlertFormatterFactory::bootstrap();
Migration::migrate();
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 to send
* deactivation email.
*
* @since 3.3.1
*/
public function deactivate_actions() {
/**
* 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_Utilities_Emailer' ) ) {
// Get email template.
Email_Helper::send_deactivation_email();
}
}
/**
* Disable Custom Field through ajax.
*
* @internal
*
* @since 5.0.0
*/
public static function ajax_disable_custom_field() {
// Die if user does not have permission to disable.
if ( ! Settings_Helper::current_user_can( 'edit' ) ) {
echo '
' . esc_html__( 'Error: You do not have sufficient permissions to disable this custom field.', 'wp-security-audit-log' ) . '
'; die(); } // Filter $_POST array for security. $post_array = filter_input_array( INPUT_POST ); $disable_nonce = ( isset( $_POST['disable_nonce'] ) ) ? \sanitize_text_field( \wp_unslash( $_POST['disable_nonce'] ) ) : null; $notice = ( isset( $_POST['notice'] ) ) ? \sanitize_text_field( \wp_unslash( $_POST['notice'] ) ) : null; $object_type_post = ( isset( $_POST['object_type'] ) ) ? \sanitize_text_field( \wp_unslash( $_POST['object_type'] ) ) : null; if ( ! isset( $disable_nonce ) || ! wp_verify_nonce( $disable_nonce, 'disable-custom-nonce' . $notice ) ) { die(); } $object_type = 'post'; if ( array_key_exists( 'object_type', $post_array ) && 'user' === $object_type_post ) { $object_type = 'user'; } $excluded_meta = array(); 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(); } array_push( $excluded_meta, esc_html( $notice ) ); if ( 'post' === $object_type ) { $excluded_meta = Settings_Helper::set_excluded_post_meta_fields( $excluded_meta ); } elseif ( 'user' === $object_type ) { $excluded_meta = Settings_Helper::set_excluded_user_meta_fields( $excluded_meta ); } // Exclude object link. $exclude_objects_link = add_query_arg( array( 'page' => 'wsal-settings', 'tab' => 'exclude-objects', ), network_admin_url( 'admin.php' ) ); echo wp_sprintf( /* translators: name of meta field (in bold) */ '' . esc_html__( 'Custom field %s is no longer being monitored.', 'wp-security-audit-log' ) . '
', '' . $notice . '' // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ); echo wp_sprintf( /* translators: setting tab name "Excluded Objects" */ '' . esc_html__( 'Enable the monitoring of this custom field again from the %s tab in the plugin settings.', 'wp-security-audit-log' ) . '
', '' . esc_html__( 'Excluded Objects', 'wp-security-audit-log' ) . '' ); die; } /** * 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 '' . esc_html__( 'Error: You do not have sufficient permissions to disable this alert.', 'wp-security-audit-log' ) . '
'; 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 ( isset( $s_alerts ) && '' !== $s_alerts ) { $s_alerts .= ',' . esc_html( $code ); } else { $s_alerts = esc_html( $code ); } Settings_Helper::set_option_value( 'disabled-alerts', $s_alerts ); echo wp_sprintf( // translators: Alert code which is no longer monitored. '' . esc_html__( 'Alert %1$s is no longer being monitored. %2$s', 'wp-security-audit-log' ) . '
', \esc_html( $code ), '