Submit
Path:
~
/
home
/
getwphos
/
www
/
deerguard
/
wp-content
/
plugins
/
wp-security-audit-log
/
classes
/
WPSensors
/
File Content:
class-wp-content-sensor.php
<?php /** * Sensor: Content * * Content sensor class file. * * @since 4.6.0 * @package wsal * @subpackage sensors */ declare(strict_types=1); namespace WSAL\WP_Sensors; use WSAL\Helpers\WP_Helper; use WSAL\Helpers\Settings_Helper; use WSAL\Controllers\Alert_Manager; // Exit if accessed directly. if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! class_exists( '\WSAL\WP_Sensors\WP_Content_Sensor' ) ) { /** * WordPress contents (posts, pages and custom posts). * * Apart from some other events, the following were migrated from plugins & themes sensor: * 5019 A plugin created a post * 5025 A plugin deleted a post * * @package wsal * @subpackage sensors * * @since 4.5.0 */ class WP_Content_Sensor { /** * Holds the name of the meta used to setting the lock status of the post */ const LOCK_META_NAME = '_edit_lock'; /** * Old post. * * @var stdClass * * @since 4.5.0 */ private static $old_post = null; /** * Old permalink. * * @var string * * @since 4.5.0 */ private static $old_link = null; /** * Old categories. * * @var array * * @since 4.5.0 */ private static $old_cats = null; /** * Old tags. * * @var array * * @since 4.5.0 */ private static $old_tags = null; /** * Old path to file. * * @var string * * @since 4.5.0 */ private static $old_tmpl = null; /** * Old post is marked as sticky. * * @var boolean * * @since 4.5.0 */ private static $old_sticky = null; /** * Old Post Status. * * @var string * * @since 4.5.0 */ private static $old_status = null; /** * Old Post Meta. * * @var string * * @since 4.5.0 */ private static $old_meta = null; /** * Inits the main hooks * * @return void * * @since 4.5.0 */ public static function init() { \add_action( 'pre_post_update', array( __CLASS__, 'get_before_post_edit_data' ), 10, 2 ); \add_action( 'save_post', array( __CLASS__, 'post_changed' ), 10, 3 ); \add_action( 'set_object_terms', array( __CLASS__, 'post_terms_changed' ), 10, 4 ); \add_action( 'post_stuck', array( __CLASS__, 'post_stuck_event' ), 10, 1 ); \add_action( 'post_unstuck', array( __CLASS__, 'post_unstuck_event' ), 10, 1 ); \add_action( 'delete_post', array( __CLASS__, 'event_post_deleted' ), 10, 1 ); \add_action( 'wp_trash_post', array( __CLASS__, 'event_post_trashed' ), 10, 1 ); \add_action( 'untrash_post', array( __CLASS__, 'event_post_untrashed' ) ); \add_action( 'future_to_publish', array( __CLASS__, 'event_publish_future' ), 10, 1 ); \add_action( 'admin_action_edit', array( __CLASS__, 'edit_post_in_gutenberg' ), 10 ); \add_filter( 'post_edit_form_tag', array( __CLASS__, 'edit_post_in_classic' ), 10, 1 ); \add_action( 'wp_head', array( __CLASS__, 'viewing_post' ), 10 ); \add_action( 'create_category', array( __CLASS__, 'event_category_creation' ), 10, 1 ); \add_action( 'create_post_tag', array( __CLASS__, 'event_tag_creation' ), 10, 1 ); \add_action( 'pre_delete_term', array( __CLASS__, 'check_taxonomy_term_deletion' ), 10, 2 ); \add_filter( 'wp_update_term_data', array( __CLASS__, 'event_update_term_data' ), 10, 4 ); \add_filter( 'add_post_metadata', array( __CLASS__, 'check_added_meta' ), 10, 5 ); \add_filter( 'delete_post_metadata', array( __CLASS__, 'check_deleted_meta' ), 10, 5 ); \add_action( 'update_post_meta', array( __CLASS__, 'before_changing_meta' ), 10, 4 ); \add_action( 'updated_post_meta', array( __CLASS__, 'check_changed_meta' ), 10, 4 ); // Check if MainWP Child Plugin exists. if ( \WpSecurityAuditLog::is_mainwp_active() ) { \add_action( 'mainwp_before_post_update', array( __CLASS__, 'event_mainwp_init' ), 10, 2 ); } } /** * Get Post Data. * * Collect old post data before post update event. * * @param int $post_id - Post ID. * * @since 5.0.0 */ public static function get_before_post_edit_data( $post_id ) { $post_id = (int) $post_id; // Making sure that the post id is integer. $post = \get_post( $post_id ); // Get post. // If post exists. if ( ! empty( $post ) && $post instanceof \WP_Post ) { self::$old_post = $post; self::$old_link = get_permalink( $post_id ); self::$old_tmpl = self::get_post_template( self::$old_post ); self::$old_cats = self::get_post_categories( self::$old_post ); self::$old_tags = self::get_post_tags( self::$old_post ); self::$old_sticky = in_array( $post_id, get_option( 'sticky_posts' ), true ); self::$old_status = $post->post_status; self::$old_meta = get_post_meta( $post_id ); } } /** * Check all the post changes. * * @param integer $post_id - Post ID. * @param WP_Post $post - WP Post object. * @param boolean $update - True if post update, false if post is new. * * @since 4.5.0 */ public static function post_changed( $post_id, $post, $update ) { // Ignore if post type is empty, revision or trash. if ( empty( $post->post_type ) || 'revision' === $post->post_type || 'trash' === $post->post_status ) { return; } if ( null === self::$old_post ) { return; } // Ignorable states. if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { // Check post creation event. if ( self::$old_post && 'auto-draft' === self::$old_post->post_status && 'draft' === $post->post_status ) { self::check_post_creation( self::$old_post, $post ); } return; } if ( Alert_Manager::is_disabled_post_type( $post->post_type ) ) { return; } /** * Post Changed. * * Don't let the second request for meta update from Gutenberg pass this checkpoint. * * Only pass these requests: * 1. Rest request from Gutenberg. * 2. Classic editor request. * 3. Quick edit ajax request. * * @since 3.4 */ if ( ! defined( 'REST_REQUEST' ) && ! defined( 'DOING_AJAX' ) ) { // Either Gutenberg's second post request or classic editor's request. if ( ! isset( $_REQUEST['classic-editor'] ) ) { $editor_replace = get_option( 'classic-editor-replace', 'classic' ); $allow_users = get_option( 'classic-editor-allow-users', 'disallow' ); // If block editor is selected and users are not allowed to switch editors then it is Gutenberg's second request. if ( 'block' === $editor_replace && 'disallow' === $allow_users ) { return; } if ( 'allow' === $allow_users ) { // if users are allowed to switch then it is Gutenberg's second request. return; } } } if ( $update ) { $status_event = self::check_status_change( self::$old_post, $post ); if ( 2001 !== $status_event && 'auto-draft' !== self::$old_post->post_status ) { // Handle update post events. $changes = 0; $changes = self::check_author_change( self::$old_post, $post ) + self::check_parent_change( self::$old_post, $post ) + self::check_visibility_change( self::$old_post, $post, self::$old_status, $post->post_status ) + self::check_date_change( self::$old_post, $post ) + self::check_permalink_change( self::$old_link, get_permalink( $post->ID ), $post ) + self::check_comments_pings( self::$old_post, $post ); // If a status change event has occurred, then don't log event 2002 (post modified). $changes = $status_event ? true : $changes; if ( '1' === $changes ) { remove_action( 'save_post', array( __CLASS__, 'post_changed' ), 10, 3 ); } self::check_modification_change( $post->ID, self::$old_post, $post, $changes ); } } else { // If not update then check post creation. self::check_post_creation( self::$old_post, $post ); } } /** * Check if post terms changed via Gutenberg. * * @param int $post_id - Post ID. * @param array $terms - Array of terms. * @param array $tt_ids - Array of taxonomy term ids. * @param string $taxonomy - Taxonomy slug. * * @since 4.5.0 */ public static function post_terms_changed( $post_id, $terms, $tt_ids, $taxonomy ) { $post = get_post( $post_id ); if ( is_wp_error( $post ) ) { return; } if ( null === $post ) { return; } if ( 'auto-draft' === $post->post_status ) { return; } // Support for Admin Columns Pro plugin and its add-on. if ( isset( $_POST['_ajax_nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_ajax_nonce'] ) ), 'ac-ajax' ) ) { return; } if ( isset( $_POST['action'] ) && 'acp_editing_single_request' === sanitize_text_field( wp_unslash( $_POST['action'] ) ) ) { return; } if ( null === self::$old_post && null === self::$old_tags && null === self::$old_cats ) { self::get_before_post_edit_data( $post->ID ); } if ( 'post_tag' === $taxonomy ) { // Check tags change event. self::check_tags_change( self::$old_tags, self::get_post_tags( $post ), $post ); } else { // Check categories change event. self::check_categories_change( self::$old_cats, self::get_post_categories( $post ), $post ); } } /** * Post Stuck Event. * * @param integer $post_id - Post ID. * * @since 4.5.0 */ public static function post_stuck_event( $post_id ) { self::log_sticky_post_event( $post_id, 2049 ); } /** * Post Unstuck Event. * * @param integer $post_id - Post ID. * * @since 4.5.0 */ public static function post_unstuck_event( $post_id ) { self::log_sticky_post_event( $post_id, 2050 ); } /** * Post permanently deleted. * * @param integer $post_id - Post ID. * * @since 4.5.0 */ public static function event_post_deleted( $post_id ) { // Exclude CPTs from external plugins. $post = get_post( $post_id ); $event = 2008; // Check WordPress backend operations. if ( self::check_auto_draft( $event, $post->post_title ) ) { return; } $event_data = self::get_post_event_data( $post ); // Get event data. // Check if this was initiated by a plugin. $request_params = \WSAL\Helpers\PHP_Helper::get_filtered_request_data(); if ( empty( $request_params['action'] ) && isset( $request_params['page'] ) ) { $event = 5025; $event_data = array( 'PostID' => $post->ID, 'PostType' => $post->post_type, 'PostTitle' => $post->post_title, 'PostStatus' => $post->post_status, 'Username' => 'Plugins', ); } Alert_Manager::trigger_event( $event, $event_data ); // Log event. } /** * Post moved to the trash. * * @param integer $post_id - Post ID. * * @since 4.5.0 */ public static function event_post_trashed( $post_id ) { $post = get_post( $post_id ); $editor_link = self::get_editor_link( $post_id ); Alert_Manager::trigger_event( 2012, array( 'PostID' => $post->ID, 'PostType' => $post->post_type, 'PostTitle' => $post->post_title, 'PostStatus' => $post->post_status, 'PostDate' => $post->post_date, 'PostUrl' => get_permalink( $post->ID ), $editor_link['name'] => $editor_link['value'], ) ); } /** * Post restored from trash. * * @param integer $post_id - Post ID. * * @since 4.5.0 */ public static function event_post_untrashed( $post_id ) { $post = get_post( $post_id ); $editor_link = self::get_editor_link( $post_id ); Alert_Manager::trigger_event( 2014, array( 'PostID' => $post->ID, 'PostType' => $post->post_type, 'PostTitle' => $post->post_title, 'PostStatus' => $post->post_status, 'PostDate' => $post->post_date, 'PostUrl' => get_permalink( $post->ID ), $editor_link['name'] => $editor_link['value'], ) ); remove_action( 'save_post', array( __CLASS__, 'post_changed' ), 10, 3 ); } /** * Post future publishing. * * @param integer $post_id - Post ID. * * @since 4.5.0 */ public static function event_publish_future( $post_id ) { $post = get_post( $post_id ); $editor_link = self::get_editor_link( $post_id ); Alert_Manager::trigger_event( 2001, array( 'PostID' => $post->ID, 'PostType' => $post->post_type, 'PostTitle' => $post->post_title, 'PostStatus' => $post->post_status, 'PostDate' => $post->post_date, 'PostUrl' => get_permalink( $post->ID ), $editor_link['name'] => $editor_link['value'], ) ); remove_action( 'save_post', array( __CLASS__, 'post_changed' ), 10, 3 ); } /** * Alert for Editing of Posts and Custom Post Types in Gutenberg. * * @since 4.5.0 */ public static function edit_post_in_gutenberg() { global $pagenow; if ( 'post.php' !== $pagenow ) { return; } $post_id = isset( $_GET['post'] ) ? (int) sanitize_text_field( wp_unslash( $_GET['post'] ) ) : false; // Check post id. if ( empty( $post_id ) ) { return; } if ( is_user_logged_in() && is_admin() ) { // Get post. $post = get_post( $post_id ); // Log event. self::post_opened_in_editor( $post ); } } /** * Alerts for Editing of Posts, Pages and Custom Post Types. * * @param WP_Post $post - Post. * * @since 4.5.0 */ public static function edit_post_in_classic( $post ) { if ( is_user_logged_in() && is_admin() ) { // Log event. self::post_opened_in_editor( $post ); } return $post; } /** * Post View Event. * * Alerts for Viewing of Posts and Custom Post Types. * * @since 4.5.0 */ public static function viewing_post() { // Retrieve the current post object. $post = get_queried_object(); if ( is_user_logged_in() && ! is_admin() ) { $current_path = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : false; if ( ! empty( $_SERVER['HTTP_REFERER'] ) && ! empty( $current_path ) && false !== strpos( sanitize_text_field( wp_unslash( $_SERVER['HTTP_REFERER'] ) ), $current_path ) ) { // Ignore this if we were on the same page so we avoid double audit entries. return; } if ( ! empty( $post->post_title ) ) { $edit_link = self::get_editor_link( $post->ID ); // Get editor link. $post_data = self::get_post_event_data( $post ); // Get event post data. // Update post URL based on current actual path. if ( WP_Helper::is_multisite() && ! is_subdomain_install() ) { // For multisite using subfolders, remove the subfolder. $subdir_path = parse_url( home_url(), PHP_URL_PATH ); // phpcs:ignore if ( ! is_null( $subdir_path ) ) { $escaped = str_replace( '/', '\/', preg_quote( $subdir_path ) ); // phpcs:ignore $current_path = preg_replace( '/' . $escaped . '/', '', $current_path ); } } // Bail if this don't have this, as it's probably an archive. if ( ! isset( $post_data['PostUrl'] ) ) { return; } $full_current_path = home_url( $current_path ); if ( $full_current_path !== $post_data['PostUrl'] ) { $post_data['PostUrl'] = esc_url( $full_current_path ); } // Set editor link. $post_data[ $edit_link['name'] ] = $edit_link['value']; Alert_Manager::trigger_event( 2101, $post_data ); } } } /** * New category created. * * @param integer $category_id - Category ID. * * @since 4.5.0 */ public static function event_category_creation( $category_id ) { $category = get_category( $category_id ); $category_link = self::get_taxonomy_edit_link( $category_id, 'category' ); Alert_Manager::trigger_event( 2023, array( 'CategoryName' => $category->name, 'Slug' => $category->slug, 'CategoryLink' => $category_link, ) ); } /** * New tag created. * * @param int $tag_id - Tag ID. * * @since 4.5.0 */ public static function event_tag_creation( $tag_id ) { $tag = get_tag( $tag_id ); $tag_link = self::get_taxonomy_edit_link( $tag_id ); Alert_Manager::trigger_event( 2121, array( 'TagName' => $tag->name, 'Slug' => $tag->slug, 'TagLink' => $tag_link, ) ); } /** * Taxonomy Terms Deleted Events. * * @param integer $term_id - Term ID. * @param string $taxonomy - Taxonomy Name. * * @since 4.5.0 */ public static function check_taxonomy_term_deletion( $term_id, $taxonomy ) { if ( 'post_tag' === $taxonomy ) { $tag = get_tag( $term_id ); Alert_Manager::trigger_event( 2122, array( 'TagID' => $term_id, 'TagName' => $tag->name, 'Slug' => $tag->slug, ) ); } elseif ( 'category' === $taxonomy ) { $category = get_category( $term_id ); $category_link = self::get_taxonomy_edit_link( $term_id, $taxonomy ); Alert_Manager::trigger_event( 2024, array( 'CategoryID' => $term_id, 'CategoryName' => $category->cat_name, 'Slug' => $category->slug, 'CategoryLink' => $category_link, ) ); } } /** * Triggered when term data is updated. * * @param array $data Term data to be updated. * @param int $term_id Term ID. * @param string $taxonomy Taxonomy slug. * @param array $args Arguments passed to wp_update_term(). * * @since 4.5.0 */ public static function event_update_term_data( $data, $term_id, $taxonomy, $args ) { // Get new data. $new_name = isset( $data['name'] ) ? $data['name'] : false; $new_slug = isset( $data['slug'] ) ? $data['slug'] : false; $new_desc = isset( $args['description'] ) ? $args['description'] : false; $new_parent = isset( $args['parent'] ) ? $args['parent'] : false; // Get old data. $term = get_term( $term_id, $taxonomy ); $old_name = $term->name; $old_slug = $term->slug; $old_desc = $term->description; $old_parent = $term->parent; $term_link = self::get_taxonomy_edit_link( $term_id, $taxonomy ); // Check if the taxonomy is `post tag`. if ( 'post_tag' === $taxonomy ) { // Update if both names are not same. if ( $old_name !== $new_name ) { Alert_Manager::trigger_event( 2123, array( 'old_name' => $old_name, 'new_name' => $new_name, 'TagLink' => $term_link, 'Slug' => $new_slug, ) ); } // Update if both slugs are not same. if ( $old_slug !== $new_slug ) { Alert_Manager::trigger_event( 2124, array( 'tag' => $new_name, 'old_slug' => $old_slug, 'new_slug' => $new_slug, 'TagLink' => $term_link, ) ); } // Update if both descriptions are not same. if ( $old_desc !== $new_desc ) { Alert_Manager::trigger_event( 2125, array( 'tag' => $new_name, 'TagLink' => $term_link, 'old_desc' => $old_desc, 'new_desc' => $new_desc, ) ); } } elseif ( 'category' === $taxonomy ) { // Check if the taxonomy is `category`. // Log event if both names are not same. if ( $old_name !== $new_name ) { Alert_Manager::trigger_event( 2127, array( 'old_name' => $old_name, 'new_name' => $new_name, 'slug' => $new_slug, 'cat_link' => $term_link, ) ); } // Log event if both slugs are not same. if ( $old_slug !== $new_slug ) { Alert_Manager::trigger_event( 2128, array( 'CategoryName' => $new_name, 'old_slug' => $old_slug, 'new_slug' => $new_slug, 'cat_link' => $term_link, ) ); } if ( 0 !== $old_parent ) { $old_parent_obj = get_category( $old_parent ); $old_parent_name = empty( $old_parent_obj ) ? 'no parent' : $old_parent_obj->name; } else { $old_parent_name = 'no parent'; } if ( 0 !== $new_parent ) { $new_parent_obj = get_category( $new_parent ); $new_parent_name = empty( $new_parent_obj ) ? 'no parent' : $new_parent_obj->name; } else { $new_parent_name = 'no parent'; } if ( $old_parent_name !== $new_parent_name ) { Alert_Manager::trigger_event( 2052, array( 'CategoryName' => $new_name, 'OldParent' => $old_parent_name, 'NewParent' => $new_parent_name, 'CategoryLink' => $term_link, 'Slug' => $new_slug, ) ); } } return $data; // Return data for the filter. } /** * Checks if selected metadata items have changed. Function is called from different contexts. * * @param int $post_id Post ID. * @param string $meta_key Meta key. * @param mixed $meta_value Meta value. * @param mixed $default_result Default result. The name is misleading - it holds the meta ID value. * * @return int - The meta ID. * * @since 4.5.0 */ private static function check_selected_meta_change( $post_id, $meta_key, $meta_value, $default_result ) { if ( ! $post_id ) { return $default_result; } switch ( $meta_key ) { case '_wp_page_template': self::check_template_change( $post_id, $meta_value ); break; case '_thumbnail_id': self::check_featured_image_change( $post_id, $meta_value ); break; default: return $default_result; } return $default_result; } /** * Check Page Template Update. * * @param int $meta_id ID of updated metadata entry. * @param int $post_id Post ID. * @param string $meta_key Meta key. * @param mixed $meta_value Meta value. * * @return int ID of updated metadata entry. * * @since 4.5.0 */ public static function check_changed_meta( $meta_id, $post_id, $meta_key, $meta_value ) { return self::check_selected_meta_change( $post_id, $meta_key, $meta_value, $meta_id ); } /** * Check Page Template Update for deletions. * * @param null|bool $delete Whether to allow metadata deletion of the given type. * @param int $object_id ID of the object metadata is for. * @param string $meta_key Metadata key. * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. * @param bool $delete_all Whether to delete the matching metadata entries * for all objects, ignoring the specified $object_id. * Default false. * * @return bool|null Whether to allow metadata deletion of the given type. * * @since 4.5.0 */ public static function check_deleted_meta( $delete, $object_id, $meta_key, $meta_value, $delete_all ) { return self::check_selected_meta_change( $object_id, $meta_key, $meta_value, $delete ); } /** * Check Page Template Update for additions. * * @param null|bool $check Whether to allow adding metadata for the given type. * @param int $object_id ID of the object metadata is for. * @param string $meta_key Metadata key. * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. * @param bool $unique Whether the specified meta key should be unique for the object. * * @return bool|null Whether to allow metadata addition of the given type. * * @since 4.5.0 */ public static function check_added_meta( $check, $object_id, $meta_key, $meta_value, $unique ) { return self::check_selected_meta_change( $object_id, $meta_key, $meta_value, $check ); } /** * Check Page Template Update. * * @param int $post_id Post ID. * @param mixed $meta_value Meta value. * * @since 4.5.0 */ public static function check_template_change( $post_id, $meta_value ) { $post = get_post( $post_id ); $old_tmpl = ( self::$old_tmpl && 'page' !== basename( self::$old_tmpl, '.php' ) ) ? ucwords( str_replace( array( '-', '_' ), ' ', basename( self::$old_tmpl, '.php' ) ) ) : __( 'Default template', 'wp-security-audit-log' ); $new_tmpl = ( $meta_value ) ? ucwords( str_replace( array( '-', '_' ), ' ', basename( $meta_value ) ) ) : __( 'Default', 'wp-security-audit-log' ); if ( $old_tmpl !== $new_tmpl ) { $editor_link = self::get_editor_link( $post_id ); Alert_Manager::trigger_event( 2048, array( 'PostID' => $post->ID, 'PostType' => $post->post_type, 'PostTitle' => $post->post_title, 'PostStatus' => $post->post_status, 'PostDate' => $post->post_date, 'OldTemplate' => $old_tmpl, 'NewTemplate' => $new_tmpl, $editor_link['name'] => $editor_link['value'], ) ); } } /** * Fires immediately before updating a post's metadata. * * @param int $meta_id ID of metadata entry to update. * @param int $object_id Post ID. * @param string $meta_key Metadata key. * @param mixed $meta_value Metadata value. This will be a PHP-serialized string representation of the value * if the value is an array, an object, or itself a PHP-serialized string. * * @since 4.5.0 */ public static function before_changing_meta( $meta_id, $object_id, $meta_key, $meta_value ) { if ( self::LOCK_META_NAME === $meta_key ) { self::fire_lock_change( (int) $object_id, (string) $meta_value ); } } /** * Fires lock owner changing. * * @param integer $post_id - The ID of the post. * @param string $meta_value - The meta value - that is in format "1649934679:2" * where the "1649934679" is the timestamp of the locking * and "2" is the ID of the \WP_User which currently editing the post. * * @return void * * @since 4.5.0 */ public static function fire_lock_change( int $post_id, string $meta_value ) { if ( $meta_value ) { if ( ! function_exists( 'wp_check_post_lock' ) ) { require_once ABSPATH . 'wp-admin/includes/post.php'; } $user_id = \wp_check_post_lock( $post_id ); // The id of the user currently editing the post. /** * The post is currently edited by someone - proceed with extracting the new user editor */ if ( $user_id ) { $lock = explode( ':', $meta_value ); $new_user_id = $lock[1]; if ( $new_user_id ) { if ( $new_editor_user = get_userdata( $new_user_id ) ) { //phpcs:ignore $post = get_post( $post_id ); $editor_link = self::get_editor_link( $post_id ); Alert_Manager::trigger_event( 2133, array( 'PostID' => $post->ID, 'PostType' => $post->post_type, 'PostTitle' => $post->post_title, 'PostStatus' => $post->post_status, $editor_link['name'] => $editor_link['value'], 'user' => get_userdata( $user_id )->display_name, ) ); } } } } } /** * Check Post Featured Image Update. * * @param int $post_id Post ID. * @param mixed $meta_value Meta value. * * @since 4.5.0 */ public static function check_featured_image_change( $post_id, $meta_value ) { $previous_featured_image = ( isset( self::$old_meta['_thumbnail_id'][0] ) ) ? wp_get_attachment_metadata( self::$old_meta['_thumbnail_id'][0] ) : false; $new_featured_image = wp_get_attachment_metadata( $meta_value ); if ( empty( $new_featured_image['file'] ) && empty( $previous_featured_image['file'] ) ) { return; } $event_type = 'modified'; if ( empty( $previous_featured_image['file'] ) && ! empty( $new_featured_image['file'] ) ) { $event_type = 'added'; } elseif ( ! empty( $previous_featured_image['file'] ) && empty( $new_featured_image['file'] ) ) { $event_type = 'removed'; } $previous_image = is_array( $previous_featured_image ) && array_key_exists( 'file', $previous_featured_image ) ? $previous_featured_image['file'] : __( 'No previous image', 'wp-security-audit-log' ); $new_image = is_array( $new_featured_image ) && array_key_exists( 'file', $new_featured_image ) ? $new_featured_image['file'] : __( 'No image', 'wp-security-audit-log' ); $post = get_post( $post_id ); $editor_link = self::get_editor_link( $post_id ); Alert_Manager::trigger_event( 2130, array( 'PostID' => $post->ID, 'PostType' => $post->post_type, 'PostTitle' => $post->post_title, 'PostStatus' => $post->post_status, 'PostDate' => $post->post_date, 'previous_image' => $previous_image, 'new_image' => $new_image, $editor_link['name'] => $editor_link['value'], 'EventType' => $event_type, ) ); } /** * Collect old post data before MainWP Post update event. * * @param array $new_post - Array of new post data. * @param array $post_custom - Array of data related to MainWP. * * @since 4.5.0 */ public static function event_mainwp_init( $new_post, $post_custom ) { // Get post id. $post_id = isset( $post_custom['_mainwp_edit_post_id'][0] ) ? $post_custom['_mainwp_edit_post_id'][0] : false; $post_id = (int) $post_id; // Check if ID exists. if ( $post_id ) { // Get post. $post = get_post( $post_id ); // If post exists. if ( ! empty( $post ) ) { self::$old_post = $post; self::$old_link = get_permalink( $post_id ); self::$old_tmpl = self::get_post_template( self::$old_post ); self::$old_cats = self::get_post_categories( self::$old_post ); self::$old_tags = self::get_post_tags( self::$old_post ); self::$old_sticky = in_array( $post_id, get_option( 'sticky_posts' ), true ); } } } /** * Get the template path. * * @param WP_Post $post - The post. * @return string - Full path to file. * * @since 4.5.0 */ private static function get_post_template( $post ) { if ( ! isset( $post->ID ) ) { return ''; } $id = $post->ID; $template = get_page_template_slug( $id ); $pagename = $post->post_name; $templates = array(); if ( $template && 0 === validate_file( $template ) ) { $templates[] = $template; } if ( $pagename ) { $templates[] = "page-$pagename.php"; } if ( $id ) { $templates[] = "page-$id.php"; } $templates[] = 'page.php'; return get_query_template( 'page', $templates ); } /** * Get post categories (array of category names). * * @param stdClass $post - The post. * @return array - List of categories. * * @since 4.5.0 */ private static function get_post_categories( $post ) { return ! isset( $post->ID ) ? array() : wp_get_post_categories( $post->ID, array( 'fields' => 'names' ) ); } /** * Get post tags (array of tag names). * * @param stdClass $post - The post. * @return array - List of tags. * * @since 4.5.0 */ private static function get_post_tags( $post ) { return ! isset( $post->ID ) ? array() : wp_get_post_tags( $post->ID, array( 'fields' => 'names' ) ); } /** * Check post creation. * * @global array $_POST * * @param WP_Post $old_post - Old post. * @param WP_Post $new_post - New post. * * @since 4.5.0 */ private static function check_post_creation( $old_post, $new_post ) { if ( ! empty( $new_post ) && $new_post instanceof \WP_Post ) { $event = 0; $is_scheduled = false; switch ( $new_post->post_status ) { case 'publish': $event = 2001; break; case 'draft': $event = 2000; break; case 'future': $event = 2074; $is_scheduled = true; break; case 'pending': $event = 2073; break; default: break; } if ( $event ) { $editor_link = self::get_editor_link( $new_post->ID ); // Editor link. $event_data = self::get_post_event_data( $new_post ); // Post event data. // Set editor link in the event data. $event_data[ $editor_link['name'] ] = $editor_link['value']; if ( $is_scheduled ) { $event_data['PublishingDate'] = $new_post->post_date; Alert_Manager::trigger_event( $event, $event_data ); } else { // So far we assume that the action is initiated by a user, let's check if it was actually initiated // by a plugin. $request_params = \WSAL\Helpers\PHP_Helper::get_filtered_request_data(); if ( array_key_exists( 'plugin', $request_params ) && ! empty( $request_params['plugin'] ) ) { // Event initiated by a plugin. $plugin_name = $request_params['plugin']; if ( \is_wp_error( \validate_plugin( $plugin_name ) ) ) { return; } $plugin_data = get_plugin_data( trailingslashit( WP_PLUGIN_DIR ) . $plugin_name ); $event_data = array( 'PluginName' => ( $plugin_data && isset( $plugin_data['Name'] ) ) ? $plugin_data['Name'] : false, 'PostID' => $new_post->ID, 'PostType' => $new_post->post_type, 'PostTitle' => $new_post->post_title, 'PostStatus' => $new_post->post_status, 'Username' => 'Plugins', $editor_link['name'] => $editor_link['value'], ); } Alert_Manager::trigger_event( $event, $event_data ); } } } } /** * Get editor link. * * @param int $post_id - The \WP_Post post ID. * * @return array $editor_link - Name and value link. * * @since 4.5.0 */ public static function get_editor_link( $post_id ): array { $post_id = \is_object( $post_id ) ? $post_id->ID : (int) $post_id; return array( 'name' => 'EditorLinkPost', 'value' => \get_edit_post_link( $post_id ), ); } /** * Return Post Event Data. * * @param WP_Post $post - WP Post object. * @return array * * @since 4.5.0 */ public static function get_post_event_data( $post ) { if ( ! empty( $post ) && $post instanceof \WP_Post ) { $event_data = array( 'PostID' => $post->ID, 'PostType' => $post->post_type, 'PostTitle' => $post->post_title, 'PostStatus' => $post->post_status, 'PostDate' => $post->post_date, 'PostUrl' => get_permalink( $post->ID ), ); return $event_data; } return array(); } /** * Author changed. * * @param stdClass $oldpost - Old post. * @param stdClass $newpost - New post. * * @since 4.5.0 */ private static function check_author_change( $oldpost, $newpost ) { if ( $oldpost->post_author !== $newpost->post_author ) { $editor_link = self::get_editor_link( $oldpost->ID ); $old_author = get_userdata( $oldpost->post_author ); $old_author = ( is_object( $old_author ) ) ? $old_author->user_login : 'N/A'; $new_author = get_userdata( $newpost->post_author ); $new_author = ( is_object( $new_author ) ) ? $new_author->user_login : 'N/A'; Alert_Manager::trigger_event( 2019, array( 'PostID' => $oldpost->ID, 'PostType' => $oldpost->post_type, 'PostTitle' => $oldpost->post_title, 'PostStatus' => $oldpost->post_status, 'PostDate' => $oldpost->post_date, 'PostUrl' => get_permalink( $oldpost->ID ), 'OldAuthor' => $old_author, 'NewAuthor' => $new_author, $editor_link['name'] => $editor_link['value'], ) ); return 1; } } /** * Status changed. * * @param stdClass $oldpost - Old post. * @param stdClass $newpost - New post. * * @return integer * * @since 4.5.0 */ private static function check_status_change( $oldpost, $newpost ) { if ( $oldpost->post_status !== $newpost->post_status ) { $event = 0; $is_scheduled = false; if ( 'auto-draft' === $oldpost->post_status && 'draft' === $newpost->post_status ) { $event = 2000; } elseif ( 'publish' === $newpost->post_status ) { $event = 2001; } elseif ( 'pending' === $newpost->post_status ) { $event = 2073; } elseif ( 'future' === $newpost->post_status ) { $event = 2074; $is_scheduled = true; } else { $event = 2021; } if ( $event ) { $editor_link = self::get_editor_link( $newpost->ID ); // Editor link. $event_data = self::get_post_event_data( $newpost ); // Post event data. // Set editor link in the event data. $event_data[ $editor_link['name'] ] = $editor_link['value']; if ( $is_scheduled ) { $event_data['PublishingDate'] = $newpost->post_date; Alert_Manager::trigger_event( $event, $event_data ); } elseif ( 2021 === $event ) { $event_data['OldStatus'] = $oldpost->post_status; $event_data['NewStatus'] = $newpost->post_status; Alert_Manager::trigger_event( $event, $event_data ); } else { // NOTE: this triggers if NOT firing event 5019. Alert_Manager::trigger_event_if( $event, $event_data, array( __CLASS__, 'plugin_not_created_post' ) ); } } return $event; } } /** * Post parent changed. * * @param stdClass $oldpost - Old post. * @param stdClass $newpost - New post. * * @since 4.5.0 */ private static function check_parent_change( $oldpost, $newpost ) { if ( $oldpost->post_parent !== $newpost->post_parent && 'page' === $newpost->post_type ) { $editor_link = self::get_editor_link( $oldpost->ID ); Alert_Manager::trigger_event( 2047, array( 'PostID' => $oldpost->ID, 'PostType' => $oldpost->post_type, 'PostTitle' => $oldpost->post_title, 'PostStatus' => $oldpost->post_status, 'PostDate' => $oldpost->post_date, 'OldParent' => $oldpost->post_parent, 'NewParent' => $newpost->post_parent, 'OldParentName' => $oldpost->post_parent ? get_the_title( $oldpost->post_parent ) : 'no parent', 'NewParentName' => $newpost->post_parent ? get_the_title( $newpost->post_parent ) : 'no parent', $editor_link['name'] => $editor_link['value'], ) ); return 1; } } /** * Permalink changed. * * @param string $old_link - Old permalink. * @param string $new_link - New permalink. * * @param stdClass $post - The post. * * @since 4.5.0 */ private static function check_permalink_change( $old_link, $new_link, $post ) { if ( in_array( $post->post_status, array( 'draft', 'pending' ), true ) ) { $old_link = self::$old_post->post_name; $new_link = $post->post_name; } if ( $old_link !== $new_link ) { $editor_link = self::get_editor_link( $post->ID ); Alert_Manager::trigger_event( 2017, array( 'PostID' => $post->ID, 'PostType' => $post->post_type, 'PostTitle' => $post->post_title, 'PostStatus' => $post->post_status, 'PostDate' => $post->post_date, 'OldUrl' => $old_link, 'NewUrl' => $new_link, $editor_link['name'] => $editor_link['value'], ) ); return 1; } return 0; } /** * Post visibility changed. * * @param WP_Post $oldpost - Old post. * @param WP_Post $newpost - New post. * @param string $old_status - Old status. * @param string $new_status - New status. * * @since 4.5.0 */ private static function check_visibility_change( $oldpost, $newpost, $old_status, $new_status ) { $old_visibility = ''; $new_visibility = ''; if ( $oldpost->post_password ) { $old_visibility = esc_html__( 'Password Protected', 'wp-security-audit-log' ); } elseif ( 'private' === $oldpost->post_status ) { $old_visibility = esc_html__( 'Private', 'wp-security-audit-log' ); } else { $old_visibility = esc_html__( 'Public', 'wp-security-audit-log' ); } if ( $newpost->post_password ) { $new_visibility = esc_html__( 'Password Protected', 'wp-security-audit-log' ); } elseif ( 'private' === $newpost->post_status ) { $new_visibility = esc_html__( 'Private', 'wp-security-audit-log' ); } else { $new_visibility = esc_html__( 'Public', 'wp-security-audit-log' ); } if ( $old_visibility && $new_visibility && ( $old_visibility !== $new_visibility ) ) { $editor_link = self::get_editor_link( $oldpost->ID ); Alert_Manager::trigger_event( 2025, array( 'PostID' => $oldpost->ID, 'PostType' => $oldpost->post_type, 'PostTitle' => $oldpost->post_title, 'PostStatus' => $newpost->post_status, 'PostDate' => $oldpost->post_date, 'PostUrl' => get_permalink( $oldpost->ID ), 'OldVisibility' => $old_visibility, 'NewVisibility' => $new_visibility, $editor_link['name'] => $editor_link['value'], ) ); return 1; } } /** * Post date changed. * * @param \WP_Post $oldpost - Old post. * @param \WP_Post $newpost - New post. * * @since 4.5.0 */ private static function check_date_change( $oldpost, $newpost ) { $from = 0; $to = 0; if ( isset( $oldpost->post_date ) && null !== $oldpost->post_date ) { $from = strtotime( $oldpost->post_date ); } if ( isset( $newpost->post_date ) && null !== $newpost->post_date ) { $to = strtotime( $newpost->post_date ); } if ( 'pending' === $oldpost->post_status ) { return 0; } /* * Return early if this looks like a re-save on a draft. */ if ( self::is_draft_resave( $oldpost, $newpost ) ) { return 0; } if ( $from !== $to ) { $editor_link = self::get_editor_link( $oldpost->ID ); Alert_Manager::trigger_event( 2027, array( 'PostID' => $oldpost->ID, 'PostType' => $oldpost->post_type, 'PostTitle' => $oldpost->post_title, 'PostStatus' => $oldpost->post_status, 'PostDate' => $newpost->post_date, 'PostUrl' => get_permalink( $oldpost->ID ), 'OldDate' => $oldpost->post_date, 'NewDate' => $newpost->post_date, $editor_link['name'] => $editor_link['value'], ) ); return 1; } return 0; } /** * Comments/Trackbacks and Pingbacks check. * * @param stdClass $oldpost - Old post. * @param stdClass $newpost - New post. * * @since 4.5.0 */ private static function check_comments_pings( $oldpost, $newpost ) { $result = 0; $editor_link = self::get_editor_link( $newpost->ID ); // Comments. if ( $oldpost->comment_status !== $newpost->comment_status ) { Alert_Manager::trigger_event( 2111, array( 'PostID' => $newpost->ID, 'PostType' => $newpost->post_type, 'PostStatus' => $newpost->post_status, 'PostDate' => $newpost->post_date, 'PostTitle' => $newpost->post_title, 'PostUrl' => get_permalink( $newpost->ID ), $editor_link['name'] => $editor_link['value'], 'EventType' => 'open' === $newpost->comment_status ? 'enabled' : 'disabled', ) ); $result = 1; } // Trackbacks and Pingbacks. if ( $oldpost->ping_status !== $newpost->ping_status ) { Alert_Manager::trigger_event( 2112, array( 'PostID' => $newpost->ID, 'PostType' => $newpost->post_type, 'PostTitle' => $newpost->post_title, 'PostStatus' => $newpost->post_status, 'PostDate' => $newpost->post_date, 'PostUrl' => get_permalink( $newpost->ID ), $editor_link['name'] => $editor_link['value'], 'EventType' => 'open' === $newpost->ping_status ? 'enabled' : 'disabled', ) ); $result = 1; } return $result; } /** * Categories changed. * * @param array $old_cats - Old categories. * @param array $new_cats - New categories. * @param WP_Post $post - The post. * * @since 4.5.0 */ private static function check_categories_change( $old_cats, $new_cats, $post ) { $old_cats = implode( ', ', (array) $old_cats ); $new_cats = implode( ', ', (array) $new_cats ); if ( $old_cats !== $new_cats && 'page' !== $post->post_type ) { $editor_link = self::get_editor_link( $post->ID ); $alert_data = array( 'PostID' => $post->ID, 'PostType' => $post->post_type, 'PostTitle' => $post->post_title, 'PostStatus' => $post->post_status, 'PostDate' => $post->post_date, 'PostUrl' => get_permalink( $post->ID ), 'OldCategories' => $old_cats ? $old_cats : 'no categories', 'NewCategories' => $new_cats ? $new_cats : 'no categories', $editor_link['name'] => $editor_link['value'], ); Alert_Manager::trigger_event( 2016, $alert_data ); } } /** * Reports tags change event. This could be tags addition, removal and possibly other in the future. * * @param int $event_code Event code. * @param WP_Post $post WordPress post object. * @param string[] $tags_changed Changed tags. * * @since 4.5.0 */ private static function report_tags_change_event( $event_code, $post, $tags_changed ) { $editor_link = self::get_editor_link( $post->ID ); Alert_Manager::trigger_event( $event_code, array( 'PostID' => $post->ID, 'PostType' => $post->post_type, 'PostStatus' => $post->post_status, 'PostTitle' => $post->post_title, 'PostDate' => $post->post_date, 'PostUrl' => get_permalink( $post->ID ), 'tag' => ! empty( $tags_changed ) ? implode( ', ', $tags_changed ) : esc_html__( 'no tags', 'wp-security-audit-log' ), $editor_link['name'] => $editor_link['value'], ) ); } /** * Tags changed. * * @param array $old_tags - Old tags. * @param array $new_tags - New tags. * @param WP_Post $post - The post. * * @since 4.5.0 */ private static function check_tags_change( $old_tags, $new_tags, $post ) { // Ensure old_tags is not null. if ( ! $old_tags ) { $old_tags = array(); } $intersection = array_intersect( $old_tags, $new_tags ); if ( count( $intersection ) === count( $old_tags ) && count( $old_tags ) === count( $new_tags ) ) { // No change, let's leave. return; } // Check for added tags. $added_tags = array_diff( (array) $new_tags, (array) $old_tags ); if ( ! empty( $added_tags ) ) { self::report_tags_change_event( 2119, $post, $added_tags ); } // Check for removed tags. $removed_tags = array_diff( (array) $old_tags, (array) $new_tags ); if ( ! empty( $removed_tags ) ) { self::report_tags_change_event( 2120, $post, $removed_tags ); } } /** * Post modified content. * * @param integer $post_id – Post ID. * @param stdClass $oldpost – Old post. * @param stdClass $newpost – New post. * @param int $modified – Set to 0 if no changes done to the post. * * @return int|void * * @since 4.5.0 */ public static function check_modification_change( $post_id, $oldpost, $newpost, $modified ) { self::check_title_change( $oldpost, $newpost ); $content_changed = $oldpost->post_content !== $newpost->post_content; /* * If the content hasn't changed and this looks to be a draft resave * then we won't track anything for this modification. */ if ( ! $content_changed && self::is_draft_resave( $oldpost, $newpost ) ) { return; } if ( $oldpost->post_modified !== $newpost->post_modified ) { $event = 0; if ( $content_changed ) { // Check if content changed. $event = 2065; } elseif ( ! $modified ) { $event = 2002; } if ( $event ) { if ( 2002 === $event ) { // Get Yoast alerts. $yoast_alerts = Alert_Manager::get_alerts_by_category( 'Yoast SEO' ); $yoast_metabox_alerts = Alert_Manager::get_alerts_by_category( 'Yoast SEO Meta Box' ); $yoast_alerts = $yoast_alerts + $yoast_metabox_alerts; // Check all alerts. foreach ( $yoast_alerts as $alert_code => $alert ) { if ( Alert_Manager::will_or_has_triggered( $alert_code ) ) { return 0; // Return if any Yoast alert has or will trigger. } } } $event_data = self::get_post_event_data( $oldpost ); $editor_link = self::get_editor_link( $oldpost->ID ); $event_data[ $editor_link['name'] ] = $editor_link['value']; $event_data['RevisionLink'] = self::get_post_revision( $post_id, $oldpost, $event ); // Check excerpt change. $old_post_excerpt = $oldpost->post_excerpt; $post_excerpt = get_post_field( 'post_excerpt', $post_id ); if ( empty( $old_post_excerpt ) && ! empty( $post_excerpt ) ) { $event_data['EventType'] = 'added'; } elseif ( ! empty( $old_post_excerpt ) && empty( $post_excerpt ) ) { $event_data['EventType'] = 'removed'; } elseif ( $old_post_excerpt !== $post_excerpt ) { $event_data['EventType'] = 'modified'; } if ( $old_post_excerpt !== $post_excerpt ) { $event = 2129; // We are purposefully showing an empty, not NULL value. $event_data['old_post_excerpt'] = ( $old_post_excerpt ) ? $old_post_excerpt : ' '; $event_data['post_excerpt'] = ( $post_excerpt ) ? $post_excerpt : ' '; } if ( 2002 === $event ) { // If we reach this point, we no longer need to check if the content has changed as we already have // an event to handle it. So trigger 2002 regardless and "something" has changed in the post, we // just don't detect it elsewhere. Alert_Manager::trigger_event_if( $event, $event_data, array( __CLASS__, 'ignore_other_post_events' ) ); } else { Alert_Manager::trigger_event( $event, $event_data ); } } } } /** * Method: Ensure no other post-related events are being fired, or have recently been fired. * * @return bool * * @since 4.5.0 */ public static function ignore_other_post_events() { $post_events = array_keys( Alert_Manager::get_alerts_by_sub_category( 'Content' ) ); $post_events = array_merge( $post_events, array_keys( Alert_Manager::get_alerts_by_sub_category( 'Coupons' ) ) ); $post_events = array_merge( $post_events, array_keys( Alert_Manager::get_alerts_by_sub_category( 'Tags' ) ) ); $post_events = array_merge( $post_events, array_keys( Alert_Manager::get_alerts_by_sub_category( 'Categories' ) ) ); $post_events = array_merge( $post_events, array_keys( Alert_Manager::get_alerts_by_sub_category( 'Custom Fields' ) ) ); $post_events = array_merge( $post_events, array_keys( Alert_Manager::get_alerts_by_sub_category( 'Custom Fields (ACF)' ) ) ); $post_events = array_merge( $post_events, array_keys( Alert_Manager::get_alerts_by_sub_category( 'Comments' ) ) ); $post_events = array_merge( $post_events, array_keys( Alert_Manager::get_alerts_by_sub_category( 'Custom Post Types' ) ) ); $post_events = array_merge( $post_events, array_keys( Alert_Manager::get_alerts_by_sub_category( 'Pages' ) ) ); $post_events[] = 9159; foreach ( $post_events as $event ) { if ( Alert_Manager::will_or_has_triggered( $event ) || Alert_Manager::was_triggered_recently( $event ) ) { return false; } } return true; } /** * Changed title of a post. * * @param stdClass $oldpost - Old post. * @param stdClass $newpost - New post. * * @since 4.5.0 */ private static function check_title_change( $oldpost, $newpost ) { if ( $oldpost->post_title !== $newpost->post_title ) { $editor_link = self::get_editor_link( $oldpost->ID ); Alert_Manager::trigger_event( 2086, array( 'PostID' => $newpost->ID, 'PostType' => $newpost->post_type, 'PostTitle' => $newpost->post_title, 'PostStatus' => $newpost->post_status, 'PostDate' => $newpost->post_date, 'PostUrl' => get_permalink( $newpost->ID ), 'OldTitle' => $oldpost->post_title, 'NewTitle' => $newpost->post_title, $editor_link['name'] => $editor_link['value'], ) ); return 1; } return 0; } /** * Return post revision link. * * @param integer $post_id - Post ID. * @param WP_Post $post - WP Post object. * * @return string * * @since 4.5.0 */ public static function get_post_revision( $post_id, $post = null, $event = 0 ) { if ( \defined( 'WP_POST_REVISIONS' ) && ! WP_POST_REVISIONS ) { if ( 2065 === $event ) { // If the content changed and WP_POST_REVISIONS is set to false, we don't have a revision link. return ''; } } $revisions = \wp_get_post_revisions( $post_id ); if ( ! empty( $revisions ) ) { $revision = array_shift( $revisions ); return self::get_revision_link( $revision->ID ); } } /** * Builds revision link. * * @param integer $revision_id - Revision ID. * * @return string|null - Link. * * @since 4.5.0 */ private static function get_revision_link( $revision_id ) { if ( WP_Helper::is_multisite() ) { return ! empty( $revision_id ) ? \add_query_arg( 'revision', $revision_id, \get_admin_url( \get_current_blog_id(), 'revision.php' ) ) : null; } return ! empty( $revision_id ) ? \add_query_arg( 'revision', $revision_id, \network_admin_url( 'revision.php' ) ) : null; } /** * Log post stuck/unstuck events. * * @param integer $post_id - Post ID. * @param integer $event - Event ID. * * @since 4.5.0 */ private static function log_sticky_post_event( $post_id, $event ) { // Get post. $post = get_post( $post_id ); if ( is_wp_error( $post ) ) { return; } $editor_link = self::get_editor_link( $post_id ); // Editor link. $event_data = self::get_post_event_data( $post ); // Event data. $event_data[ $editor_link['name'] ] = $editor_link['value']; Alert_Manager::trigger_event( $event, $event_data ); } /** * Check auto draft and the setting: Hide Plugin in Plugins Page * * @param integer $code - Alert code. * @param string $title - Title. * * @return boolean * * @since 4.5.0 */ private static function check_auto_draft( $code, $title ) { $ignore = 0; if ( 2008 === $code && ( 'auto-draft' === $title || 'Auto Draft' === $title ) ) { $ignore = ! Settings_Helper::get_boolean_option_value( 'wp-backend' ); } return $ignore; } /** * Post Opened for Editing in WP Editors. * * @param WP_Post $post – Post object. * * @since 4.5.0 */ public static function post_opened_in_editor( $post ) { if ( empty( $post ) || ! $post instanceof \WP_Post ) { return; } $current_path = isset( $_SERVER['SCRIPT_NAME'] ) ? esc_url_raw( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ) . '?post=' . $post->ID : false; $referrer = isset( $_SERVER['HTTP_REFERER'] ) ? esc_url_raw( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : false; // Check referrer URL. if ( ! empty( $referrer ) ) { // Parse the referrer. $parsed_url = wp_parse_url( $referrer ); // If the referrer is post-new then we can ignore this one. if ( isset( $parsed_url['path'] ) && 'post-new' === basename( $parsed_url['path'], '.php' ) ) { return $post; } } if ( ! empty( $referrer ) && strpos( $referrer, $current_path ) !== false ) { // Ignore this if we were on the same page so we avoid double audit entries. return $post; } if ( ! empty( $post->post_title ) ) { $event = 2100; if ( ! Alert_Manager::was_triggered( $event ) ) { $editor_link = self::get_editor_link( $post->ID ); Alert_Manager::trigger_event( $event, array( 'PostID' => $post->ID, 'PostType' => $post->post_type, 'PostTitle' => $post->post_title, 'PostStatus' => $post->post_status, 'PostDate' => $post->post_date, 'PostUrl' => get_permalink( $post->ID ), $editor_link['name'] => $editor_link['value'], ) ); } } } /** * Builds category link. * * @param integer $tag_id - Tag ID. * @param string $taxonomy - Taxonomy. * * @return string|null - Link. * * @since 4.5.0 */ private static function get_taxonomy_edit_link( $tag_id, $taxonomy = 'post_tag' ) { $tag_args = array( 'taxonomy' => $taxonomy, 'tag_ID' => $tag_id, ); return ! empty( $tag_id ) ? add_query_arg( $tag_args, \network_admin_url( 'term.php' ) ) : null; } /** * Returns true if this looks like a re-save on a draft. * * @method is_draft_resave * * @param \WP_Post $oldpost The old post object if one exists. * @param \WP_Post $newpost The new post object. * * @return boolean * * @since 4.5.0 */ private static function is_draft_resave( $oldpost, $newpost ) { /* * If this is a 'draft' and used to be a 'draft' plus the gmt dates * match and it contains only characters that would appear in the * a default unpublished post then... */ if ( 'draft' === $oldpost->post_status && $oldpost->post_status === $newpost->post_status && $oldpost->post_date_gmt === $newpost->post_date_gmt && preg_match( '/^[0\-\ \:]+$/', $oldpost->post_date_gmt ) ) { // Don't track this as a date change. return true; } } /** * Callback to test if a post was just made by a plugin. * * NOTE: the return is flipped to handle a double NOT in _CommitItem(). * * @method plugin_not_created_post * * @return boolean * * @since 4.5.0 */ public static function plugin_not_created_post() { // Ensure no event for a WC coupon. if ( Alert_Manager::will_or_has_triggered( 9063 ) ) { return false; } $triggered = Alert_Manager::will_or_has_triggered( 5019 ); // inverting value here to account for the double NOT in _CommitItem(). return ! $triggered; } } }
Edit
Rename
Chmod
Delete
FILE
FOLDER
Name
Size
Permission
Action
Alerts
---
0755
Helpers
---
0755
.DS_Store
6148 bytes
0644
class-acf-meta-sensor.php
5398 bytes
0644
class-acf-sensor.php
18555 bytes
0644
class-bbpress-sensor.php
27193 bytes
0644
class-bbpress-system-sensor.php
3777 bytes
0644
class-bbpress-user-sensor.php
11135 bytes
0644
class-gravity-forms-sensor.php
49475 bytes
0644
class-main-wp-sensor.php
14131 bytes
0644
class-mainwp-server-sensor.php
26058 bytes
0644
class-memberpress-sensor.php
52670 bytes
0644
class-multisite-sign-up-sensor.php
3722 bytes
0644
class-rank-math-sensor.php
11911 bytes
0644
class-redirection-sensor.php
14254 bytes
0644
class-tablepress-sensor.php
17655 bytes
0644
class-termly-sensor.php
9341 bytes
0644
class-woocommerce-public-sensor.php
24098 bytes
0644
class-woocommerce-sensor-helper-second.php
103733 bytes
0644
class-woocommerce-sensor-helper-third.php
4406 bytes
0644
class-woocommerce-sensor-helper.php
98594 bytes
0644
class-woocommerce-sensor.php
48936 bytes
0644
class-wp-2fa-sensor.php
11628 bytes
0644
class-wp-comments-sensor.php
7104 bytes
0644
class-wp-content-sensor.php
58785 bytes
0644
class-wp-database-sensor.php
17912 bytes
0644
class-wp-files-sensor.php
4531 bytes
0644
class-wp-log-in-out-sensor.php
20101 bytes
0644
class-wp-menus-sensor.php
24986 bytes
0644
class-wp-metadata-sensor.php
23063 bytes
0644
class-wp-multisite-sensor.php
13562 bytes
0644
class-wp-plugins-themes-sensor.php
37203 bytes
0644
class-wp-register-sensor.php
3808 bytes
0644
class-wp-request-sensor.php
3390 bytes
0644
class-wp-system-sensor.php
45784 bytes
0644
class-wp-user-profile-sensor.php
21796 bytes
0644
class-wp-widgets-sensor.php
10878 bytes
0644
class-wpforms-sensor.php
52009 bytes
0644
class-yoast-seo-sensor.php
71603 bytes
0644
index.php
58 bytes
0644
N4ST4R_ID | Naxtarrr