mainwp-child/modules/changes-logs/classes/class-changes-handle-wp-content.php

1388 lines
50 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Logger: Content
*
* Content logger class file.
*
* @since 5.5
* @package mainwp/child
*/
namespace MainWP\Child\Changes;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WordPress contents (posts, pages and custom posts).
*/
class Changes_Handle_WP_Content { //phpcs:ignore --NOSONAR -complex class.
/**
* The name of the meta used to setting the lock status of the post
*/
const LOCK_META_NAME = '_edit_lock';
/**
* Old post.
*
* @var stdClass
*/
private static $old_post = null;
/**
* Old permalink.
*
* @var string
*/
private static $old_link = null;
/**
* Old categories.
*
* @var array
*/
private static $old_cats = null;
/**
* Old tags.
*
* @var array
*/
private static $old_tags = null;
/**
* Old path to file.
*
* @var string
*/
private static $old_tmpl = null;
/**
* Old post is marked as sticky.
*
* @var boolean
*/
private static $old_sticky = null;
/**
* Old Post Status.
*
* @var string
*/
private static $old_status = null;
/**
* Old Post Meta.
*
* @var string
*/
private static $old_meta = null;
/**
* Inits the main hooks
*
* @return void
*/
public static function init_hooks() {
\add_filter( 'add_post_metadata', array( __CLASS__, 'callback_change_check_added_meta' ), 10, 5 );
\add_action( 'admin_action_edit', array( __CLASS__, 'callback_change_edit_post_in_gutenberg' ), 10 );
\add_action( 'create_category', array( __CLASS__, 'callback_change_category_creation' ), 10, 1 );
\add_filter( 'delete_post_metadata', array( __CLASS__, 'callback_change_check_deleted_meta' ), 10, 5 );
\add_action( 'delete_post', array( __CLASS__, 'callback_change_post_deleted' ), 10, 1 );
\add_filter( 'post_edit_form_tag', array( __CLASS__, 'callback_change_edit_post_in_classic' ), 10, 1 );
\add_action( 'future_to_publish', array( __CLASS__, 'callback_change_publish_future' ), 10, 1 );
\add_action( 'post_stuck', array( __CLASS__, 'callback_change_post_stuck_event' ), 10, 1 );
\add_action( 'post_unstuck', array( __CLASS__, 'callback_change_post_unstuck_event' ), 10, 1 );
\add_action( 'pre_delete_term', array( __CLASS__, 'callback_change_check_taxonomy_term_deletion' ), 10, 2 );
\add_action( 'pre_post_update', array( __CLASS__, 'change_before_post_edit_data' ), 10, 2 );
\add_action( 'save_post', array( __CLASS__, 'callback_change_post_changed' ), 10, 3 );
\add_action( 'set_object_terms', array( __CLASS__, 'callback_change_post_terms_changed' ), 10, 4 );
\add_action( 'untrash_post', array( __CLASS__, 'callback_change_post_untrashed' ) );
\add_filter( 'wp_update_term_data', array( __CLASS__, 'callback_change_update_term_data' ), 10, 4 );
\add_action( 'update_post_meta', array( __CLASS__, 'callback_change_before_changing_meta' ), 10, 4 );
\add_action( 'updated_post_meta', array( __CLASS__, 'callback_change_check_changed_meta' ), 10, 4 );
\add_action( 'wp_head', array( __CLASS__, 'callback_change_viewing_post' ), 10 );
\add_action( 'wp_trash_post', array( __CLASS__, 'callback_change_post_trashed' ), 10, 1 );
\add_action( 'create_post_tag', array( __CLASS__, 'callback_change_tag_creation' ), 10, 1 );
\add_action( 'pre_delete_term', array( __CLASS__, 'callback_change_taxonomy_term_deletion' ), 10, 2 );
}
/**
* Get Post Data.
*
* @param int $post_id - Post ID.
*/
public static function change_before_post_edit_data( $post_id ) {
$post_id = (int) $post_id;
$post = \get_post( $post_id );
if ( ! empty( $post ) && $post instanceof \WP_Post ) {
self::$old_post = $post;
self::$old_link = get_permalink( $post_id );
self::$old_tmpl = self::change_get_post_template( self::$old_post );
self::$old_cats = self::change_get_post_categories( self::$old_post );
self::$old_tags = self::change_get_post_tags( self::$old_post );
self::$old_sticky = in_array( $post_id, (array) 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.
*/
public static function callback_change_post_changed( $post_id, $post, $update ) { //phpcs:ignore --NOSONAR -complex.
if ( empty( $post->post_type ) || 'revision' === $post->post_type || 'trash' === $post->post_status || null === self::$old_post ) {
return;
}
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
if ( self::$old_post && 'auto-draft' === self::$old_post->post_status && 'draft' === $post->post_status ) {
static::change_post_creation( self::$old_post, $post );
}
return;
}
if ( Changes_Logs_Logger::is_disabled_post_type( $post->post_type ) ) {
return;
}
/**
* Post Changed.
*
* Only pass these requests:
*/
if ( ! defined( 'REST_REQUEST' ) && ! defined( 'DOING_AJAX' ) && ! isset( $_REQUEST['classic-editor'] ) ) {
// Either Gutenberg's second post request or classic editor's request.
$editor_replace = get_option( 'classic-editor-replace', 'classic' );
$allow_users = get_option( 'classic-editor-allow-users', 'disallow' );
if ( ( 'block' === $editor_replace && 'disallow' === $allow_users ) || 'allow' === $allow_users ) {
return;
}
}
if ( $update ) {
$status_event = self::change_post_status( self::$old_post, $post );
if ( 1205 !== $status_event && 'auto-draft' !== self::$old_post->post_status ) {
$changes = 0;
$changes = static::change_post_author( self::$old_post, $post )
+ static::change_post_parent( self::$old_post, $post )
+ static::change_post_visibility( self::$old_post, $post, self::$old_status, $post->post_status )
+ static::change_post_date( self::$old_post, $post )
+ static::change_post_permalink( self::$old_link, get_permalink( $post->ID ), $post )
+ static::change_comments_pings( self::$old_post, $post );
$changes = $status_event ? true : $changes;
if ( '1' === $changes ) {
remove_action( 'save_post', array( __CLASS__, 'callback_change_post_changed' ), 10, 3 );
}
static::change_post_modification( $post->ID, self::$old_post, $post, $changes );
}
} else {
static::change_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.
*/
public static function callback_change_post_terms_changed( $post_id, $terms, $tt_ids, $taxonomy ) { //phpcs:ignore --NOSONAR -requires params.
$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 ( 'post_tag' === $taxonomy ) {
self::change_check_post_tags( self::$old_tags, self::change_get_post_tags( $post ), $post );
} else {
self::change_post_categories( self::$old_cats, self::change_get_post_categories( $post ), $post );
}
}
/**
* Post Stuck Event.
*
* @param integer $post_id - Post ID.
*/
public static function callback_change_post_stuck_event( $post_id ) {
self::change_post_sticky( $post_id, 1265 );
}
/**
* Post Unstuck Event.
*
* @param integer $post_id - Post ID.
*/
public static function callback_change_post_unstuck_event( $post_id ) {
self::change_post_sticky( $post_id, 1270 );
}
/**
* Post permanently deleted.
*
* @param integer $post_id - Post ID.
*/
public static function callback_change_post_deleted( $post_id ) {
$post = get_post( $post_id );
$type_id = 1215;
if ( 'auto-draft' === $post->post_title || 'Auto Draft' === $post->post_title ) {
return;
}
$log_data = static::change_post_changes_data( $post );
$request_params = Changes_Helper::get_filtered_request_data();
if ( empty( $request_params['action'] ) && isset( $request_params['page'] ) ) {
$type_id = 1220;
$log_data = array(
'postid' => $post->ID,
'posttype' => $post->post_type,
'posttitle' => $post->post_title,
'poststatus' => $post->post_status,
'username' => 'Plugins',
);
}
Changes_Logs_Logger::log_change( $type_id, $log_data );
}
/**
* Post moved to the trash.
*
* @param integer $post_id - Post ID.
*/
public static function callback_change_post_trashed( $post_id ) {
$post = get_post( $post_id );
$log_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 ),
);
Changes_Logs_Logger::log_change( 1225, $log_data );
}
/**
* Post restored from trash.
*
* @param integer $post_id - Post ID.
*/
public static function callback_change_post_untrashed( $post_id ) {
$post = get_post( $post_id );
$log_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 ),
);
Changes_Logs_Logger::log_change( 1230, $log_data );
remove_action( 'save_post', array( __CLASS__, 'callback_change_post_changed' ), 10, 3 );
}
/**
* Post future publishing.
*
* @param integer $post_id - Post ID.
*/
public static function callback_change_publish_future( $post_id ) {
$post = get_post( $post_id );
$log_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 ),
);
Changes_Logs_Logger::log_change( 1205, $log_data );
remove_action( 'save_post', array( __CLASS__, 'callback_change_post_changed' ), 10, 3 );
}
/**
* Log for Editing of Posts and Custom Post Types in Gutenberg.
*/
public static function callback_change_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;
if ( empty( $post_id ) ) {
return;
}
if ( is_user_logged_in() && is_admin() ) {
$post = get_post( $post_id );
self::change_opened_post_editor( $post );
}
}
/**
* Logs for Editing of Posts, Pages and Custom Post Types.
*
* @param WP_Post $post - Post.
*/
public static function callback_change_edit_post_in_classic( $post ) {
if ( is_user_logged_in() && is_admin() ) {
// Log event.
self::change_opened_post_editor( $post );
}
return $post;
}
/**
* Post View Event.
*
* Logs for Viewing of Posts and Custom Post Types.
*/
public static function callback_change_viewing_post() { //phpcs:ignore --NOSONAR -complex.
$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 )
) {
return;
}
if ( ! empty( $post->post_title ) ) {
$post_data = self::change_post_changes_data( $post );
if ( Changes_Helper::is_multisite() && ! is_subdomain_install() ) {
$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 );
}
}
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 );
}
Changes_Logs_Logger::log_change( 1315, $post_data );
}
}
}
/**
* New category created.
*
* @param integer $category_id - Category ID.
*/
public static function callback_change_category_creation( $category_id ) {
$category = get_category( $category_id );
$log_data = array(
'categoryname' => $category->name,
'slug' => $category->slug,
);
Changes_Logs_Logger::log_change( 1370, $log_data );
}
/**
* Taxonomy Terms Deleted Events.
*
* @param integer $term_id - Term ID.
* @param string $taxonomy - Taxonomy Name.
*/
public static function callback_change_check_taxonomy_term_deletion( $term_id, $taxonomy ) {
if ( 'category' === $taxonomy ) {
$category = get_category( $term_id );
$log_data = array(
'categoryid' => $term_id,
'categoryname' => $category->cat_name,
'slug' => $category->slug,
);
Changes_Logs_Logger::log_change( 1375, $log_data );
}
}
/**
* 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().
*/
public static function callback_change_update_term_data( $data, $term_id, $taxonomy, $args ) { //phpcs:ignore --NOSONAR -complex.
$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;
$term = get_term( $term_id, $taxonomy );
$old_name = $term->name;
$old_slug = $term->slug;
$old_desc = $term->description;
$old_parent = $term->parent;
if ( 'post_tag' === $taxonomy ) {
if ( $old_name !== $new_name ) {
$log_data = array(
'old_name' => $old_name,
'new_name' => $new_name,
'slug' => $new_slug,
);
Changes_Logs_Logger::log_change( 1405, $log_data );
}
if ( $old_slug !== $new_slug ) {
$log_data = array(
'tag' => $new_name,
'old_slug' => $old_slug,
'new_slug' => $new_slug,
);
Changes_Logs_Logger::log_change( 1410, $log_data );
}
if ( $old_desc !== $new_desc ) {
$log_data = array(
'tag' => $new_name,
'old_desc' => $old_desc,
'new_desc' => $new_desc,
);
Changes_Logs_Logger::log_change( 1415, $log_data );
}
} elseif ( 'category' === $taxonomy ) { // The taxonomy is `category`.
if ( $old_name !== $new_name ) {
$log_data = array(
'old_name' => $old_name,
'new_name' => $new_name,
'slug' => $new_slug,
);
Changes_Logs_Logger::log_change( 1385, $log_data );
}
if ( $old_slug !== $new_slug ) {
$log_data = array(
'categoryname' => $new_name,
'old_slug' => $old_slug,
'new_slug' => $new_slug,
);
Changes_Logs_Logger::log_change( 1390, $log_data );
}
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 ) {
$log_data = array(
'categoryname' => $new_name,
'oldparent' => $old_parent_name,
'newparent' => $new_parent_name,
'slug' => $new_slug,
);
Changes_Logs_Logger::log_change( 1380, $log_data );
}
}
return $data;
}
/**
* Checks if selected metadata items have changed.
*
* @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.
*/
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 metadata entry.
*/
public static function callback_change_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.
*
* @return bool|null Whether to allow metadata deletion.
*/
public static function callback_change_check_deleted_meta( $delete, $object_id, $meta_key, $meta_value ) {
return self::check_selected_meta_change( $object_id, $meta_key, $meta_value, $delete );
}
/**
* Check Page Template Update.
*
* @param null|bool $check Whether to allow adding metadata.
* @param int $object_id ID of the object metadata.
* @param string $meta_key Metadata key.
* @param mixed $meta_value Metadata value..
*
* @return bool|null Whether to allow metadata addition.
*/
public static function callback_change_check_added_meta( $check, $object_id, $meta_key, $meta_value ) {
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.
*/
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', 'mainwp-child' );
$new_tmpl = ( $meta_value ) ? ucwords( str_replace( array( '-', '_' ), ' ', basename( $meta_value ) ) ) : __( 'Default', 'mainwp-child' );
if ( $old_tmpl !== $new_tmpl ) {
$log_data = 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,
);
Changes_Logs_Logger::log_change( 1260, $log_data );
}
}
/**
* Fires immediately before updating a post's metadata.
*
* @param int $meta_id ID of metadata to update.
* @param int $object_id Post ID.
* @param string $meta_key Metadata key.
* @param mixed $meta_value Metadata value.
*/
public static function callback_change_before_changing_meta( $meta_id, $object_id, $meta_key, $meta_value ) { //phpcs:ignore --NOSONAR -requires params.
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.
*
* @return void
*/
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'; // NOSONAR - WP compatible.
}
$user_id = \wp_check_post_lock( $post_id );
if ( $user_id ) {
$lock = explode( ':', $meta_value );
$new_user_id = $lock[1];
if ( $new_user_id && get_userdata( $new_user_id ) ) { //phpcs:ignore
$post = get_post( $post_id );
$log_data = array(
'postid' => $post->ID,
'posttype' => $post->post_type,
'posttitle' => $post->post_title,
'poststatus' => $post->post_status,
'user' => get_userdata( $user_id )->display_name,
);
Changes_Logs_Logger::log_change( 1340, $log_data );
}
}
}
}
/**
* Check Post Featured Image Update.
*
* @param int $post_id Post ID.
* @param mixed $meta_value Meta value.
*/
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;
}
$action_name = 'updated ';
if ( empty( $previous_featured_image['file'] ) && ! empty( $new_featured_image['file'] ) ) {
$action_name = 'added';
} elseif ( ! empty( $previous_featured_image['file'] ) && empty( $new_featured_image['file'] ) ) {
$action_name = 'removed';
}
$previous_image = is_array( $previous_featured_image ) && array_key_exists( 'file', $previous_featured_image ) ? $previous_featured_image['file'] : __( 'No previous image', 'mainwp-child' );
$new_image = is_array( $new_featured_image ) && array_key_exists( 'file', $new_featured_image ) ? $new_featured_image['file'] : __( 'No image', 'mainwp-child' );
$post = get_post( $post_id );
$log_data = 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,
'actionname' => $action_name,
);
Changes_Logs_Logger::log_change( 1335, $log_data );
}
/**
* Get the template path.
*
* @param WP_Post $post - The post.
* @return string - Full path to file.
*/
private static function change_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.
*/
private static function change_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.
*/
private static function change_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.
*/
private static function change_post_creation( $old_post, $new_post ) { //phpcs:ignore --NOSONAR -complex.
if ( ! empty( $new_post ) && $new_post instanceof \WP_Post && 'shop_coupon' !== $new_post->post_type ) {
$event = 0;
$is_scheduled = false;
switch ( $new_post->post_status ) {
case 'publish':
$event = 1205;
break;
case 'draft':
$event = 1200;
break;
case 'future':
$event = 1285;
$is_scheduled = true;
break;
case 'pending':
$event = 1280;
break;
default:
break;
}
if ( $event ) {
$log_data = self::change_post_changes_data( $new_post );
if ( $is_scheduled ) {
$log_data['publishingdate'] = $new_post->post_date;
Changes_Logs_Logger::log_change( $event, $log_data );
} else {
$request_params = Changes_Helper::get_filtered_request_data();
if ( array_key_exists( 'plugin', $request_params ) && ! empty( $request_params['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 );
$log_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',
);
}
Changes_Logs_Logger::log_change( $event, $log_data );
}
}
}
}
/**
* Return Post Event Data.
*
* @param WP_Post $post - WP Post object.
* @return array
*/
public static function change_post_changes_data( $post ) {
if ( ! empty( $post ) && $post instanceof \WP_Post ) {
return 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 array();
}
/**
* Author changed.
*
* @param stdClass $oldpost - Old post.
* @param stdClass $newpost - New post.
*/
private static function change_post_author( $oldpost, $newpost ) {
if ( $oldpost->post_author !== $newpost->post_author ) {
$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';
$log_data = 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,
);
Changes_Logs_Logger::log_change( 1245, $log_data );
return 1;
}
}
/**
* Status changed.
*
* @param stdClass $oldpost - Old post.
* @param stdClass $newpost - New post.
*
* @return integer
*/
private static function change_post_status( $oldpost, $newpost ) { //phpcs:ignore --NOSONAR -complex.
if ( $oldpost->post_status !== $newpost->post_status && 'shop_coupon' !== $newpost->post_type ) {
$event = 0;
$is_scheduled = false;
if ( 'auto-draft' === $oldpost->post_status && 'draft' === $newpost->post_status ) {
$event = 1200;
} elseif ( 'publish' === $newpost->post_status ) {
$event = 1205;
} elseif ( 'pending' === $newpost->post_status ) {
$event = 1280;
} elseif ( 'future' === $newpost->post_status ) {
$event = 1285;
$is_scheduled = true;
} else {
$event = 1250;
}
if ( $event ) {
$log_data = self::change_post_changes_data( $newpost );
if ( $is_scheduled ) {
$log_data['publishingdate'] = $newpost->post_date;
Changes_Logs_Logger::log_change( $event, $log_data );
} elseif ( 1250 === $event ) {
$log_data['oldstatus'] = $oldpost->post_status;
$log_data['newstatus'] = $newpost->post_status;
Changes_Logs_Logger::log_change( $event, $log_data );
} else {
Changes_Logs_Logger::log_change_save_delay( $event, $log_data );
}
}
return $event;
}
}
/**
* Post parent changed.
*
* @param stdClass $oldpost - Old post.
* @param stdClass $newpost - New post.
*/
private static function change_post_parent( $oldpost, $newpost ) {
if ( $oldpost->post_parent !== $newpost->post_parent && 'page' === $newpost->post_type ) {
$log_data = 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',
);
Changes_Logs_Logger::log_change( 1255, $log_data );
return 1;
}
}
/**
* Permalink changed.
*
* @param string $old_link - Old permalink.
* @param string $new_link - New permalink.
*
* @param stdClass $post - The post.
*/
private static function change_post_permalink( $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 ) {
$log_data = 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,
);
Changes_Logs_Logger::log_change( 1240, $log_data );
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.
*/
private static function change_post_visibility( $oldpost, $newpost, $old_status, $new_status ) { //phpcs:ignore --NOSONAR -requires params.
$old_visibility = '';
$new_visibility = '';
if ( $oldpost->post_password ) {
$old_visibility = esc_html__( 'Password Protected', 'mainwp-child' );
} elseif ( 'private' === $oldpost->post_status ) {
$old_visibility = esc_html__( 'Private', 'mainwp-child' );
} else {
$old_visibility = esc_html__( 'Public', 'mainwp-child' );
}
if ( $newpost->post_password ) {
$new_visibility = esc_html__( 'Password Protected', 'mainwp-child' );
} elseif ( 'private' === $newpost->post_status ) {
$new_visibility = esc_html__( 'Private', 'mainwp-child' );
} else {
$new_visibility = esc_html__( 'Public', 'mainwp-child' );
}
if ( $old_visibility && $new_visibility && ( $old_visibility !== $new_visibility ) ) {
$log_data = 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,
);
Changes_Logs_Logger::log_change( 1290, $log_data );
return 1;
}
}
/**
* Post date changed.
*
* @param \WP_Post $oldpost - Old post.
* @param \WP_Post $newpost - New post.
*/
private static function change_post_date( $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;
}
if ( self::is_post_draft_resave( $oldpost, $newpost ) ) {
return 0;
}
if ( $from !== $to ) {
$log_data = 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,
);
Changes_Logs_Logger::log_change( 1295, $log_data );
return 1;
}
return 0;
}
/**
* Comments/Trackbacks and Pingbacks check.
*
* @param stdClass $oldpost - Old post.
* @param stdClass $newpost - New post.
*/
private static function change_comments_pings( $oldpost, $newpost ) {
$result = 0;
// Comments.
if ( $oldpost->comment_status !== $newpost->comment_status ) {
$type_id = 1320;
if ( 'open' !== $newpost->comment_status ) {
$type_id = 1321;
}
$log_data = 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 ),
);
Changes_Logs_Logger::log_change( $type_id, $log_data );
$result = 1;
}
// Trackbacks and Pingbacks.
if ( $oldpost->ping_status !== $newpost->ping_status ) {
$type_id = 1325;
if ( 'open' !== $newpost->ping_status ) {
$type_id = 1326;
}
$log_data = 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 ),
);
Changes_Logs_Logger::log_change( $type_id, $log_data );
$result = 1;
}
return $result;
}
/**
* Categories changed.
*
* @param array $old_cats - Old categories.
* @param array $new_cats - New categories.
* @param WP_Post $post - The post.
*/
private static function change_post_categories( $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 ) {
$log_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',
);
Changes_Logs_Logger::log_change( 1235, $log_data );
}
}
/**
* Reports tags change event. This could be tags addition, removal and possibly other in the future.
*
* @param int $log_code Event code.
* @param WP_Post $post WordPress post object.
* @param string[] $tags_changed Changed tags.
*/
private static function change_post_tags( $log_code, $post, $tags_changed ) {
$log_data = 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', 'mainwp-child' ),
);
Changes_Logs_Logger::log_change( $log_code, $log_data );
}
/**
* Tags changed.
*
* @param array $old_tags - Old tags.
* @param array $new_tags - New tags.
* @param WP_Post $post - The post.
*/
private static function change_check_post_tags( $old_tags, $new_tags, $post ) {
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 ) ) {
return;
}
$added_tags = array_diff( (array) $new_tags, (array) $old_tags );
if ( ! empty( $added_tags ) ) {
self::change_post_tags( 1395, $post, $added_tags );
}
$removed_tags = array_diff( (array) $old_tags, (array) $new_tags );
if ( ! empty( $removed_tags ) ) {
self::change_post_tags( 1400, $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
*/
public static function change_post_modification( $post_id, $oldpost, $newpost, $modified ) { //phpcs:ignore --NOSONAR -complex.
self::change_post_title( $oldpost, $newpost );
$content_changed = $oldpost->post_content !== $newpost->post_content;
if ( ! $content_changed && self::is_post_draft_resave( $oldpost, $newpost ) ) {
return;
}
if ( $oldpost->post_modified !== $newpost->post_modified ) {
$event = 0;
if ( $content_changed ) {
$event = 1300;
} elseif ( ! $modified ) {
$event = 1210;
}
if ( $event ) {
$log_data = self::change_post_changes_data( $oldpost );
$old_post_excerpt = $oldpost->post_excerpt;
$post_excerpt = get_post_field( 'post_excerpt', $post_id );
if ( empty( $old_post_excerpt ) && ! empty( $post_excerpt ) ) {
$log_data['actionname'] = 'added';
} elseif ( ! empty( $old_post_excerpt ) && empty( $post_excerpt ) ) {
$log_data['actionname'] = 'removed';
} elseif ( $old_post_excerpt !== $post_excerpt ) {
$log_data['actionname'] = 'updated';
}
if ( $old_post_excerpt !== $post_excerpt ) {
$event = 1330;
$log_data['old_post_excerpt'] = ( $old_post_excerpt ) ? $old_post_excerpt : ' ';
$log_data['post_excerpt'] = ( $post_excerpt ) ? $post_excerpt : ' ';
}
if ( 1210 === $event ) {
Changes_Logs_Logger::log_change_save_delay( $event, $log_data );
} else {
Changes_Logs_Logger::log_change( $event, $log_data );
}
}
}
}
/**
* Changed title of a post.
*
* @param stdClass $oldpost - Old post.
* @param stdClass $newpost - New post.
*/
private static function change_post_title( $oldpost, $newpost ) {
if ( $oldpost->post_title !== $newpost->post_title ) {
$log_data = 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,
);
Changes_Logs_Logger::log_change( 1305, $log_data );
return 1;
}
return 0;
}
/**
* Log post stuck/unstuck events.
*
* @param integer $post_id - Post ID.
* @param integer $event - Event ID.
*/
private static function change_post_sticky( $post_id, $event ) {
$post = get_post( $post_id );
if ( is_wp_error( $post ) ) {
return;
}
$log_data = self::change_post_changes_data( $post );
Changes_Logs_Logger::log_change( $event, $log_data );
}
/**
* Post Opened for Editing in WP Editors.
*
* @param WP_Post $post Post object.
*/
public static function change_opened_post_editor( $post ) { //phpcs:ignore --NOSONAR --compatible return values.
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;
if ( ! empty( $referrer ) ) {
$parsed_url = wp_parse_url( $referrer );
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.
return $post;
}
if ( ! empty( $post->post_title ) ) {
$event = 1310;
if ( ! Changes_Logs_Logger::was_handled( $event ) ) {
$log_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 ),
);
Changes_Logs_Logger::log_change( $event, $log_data );
}
}
}
/**
* Returns true if this looks like a re-save on a draft.
*
* @method is_post_draft_resave
*
* @param \WP_Post $oldpost The old post object if one exists.
* @param \WP_Post $newpost The new post object.
*
* @return boolean
*/
private static function is_post_draft_resave( $oldpost, $newpost ) {
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;
}
}
/**
* Tag created callback.
*
* @param int $tag_id - Tag ID.
*/
public static function callback_change_tag_creation( $tag_id ) {
$tag = get_tag( $tag_id );
Changes_Logs_Logger::log_change(
1406,
array(
'tagname' => $tag->name,
'slug' => $tag->slug,
)
);
}
/**
* Taxonomy Terms Deleted callback.
*
* @param integer $term_id - Term ID.
* @param string $taxonomy - Taxonomy Name.
*/
public static function callback_change_taxonomy_term_deletion( $term_id, $taxonomy ) {
if ( 'post_tag' === $taxonomy ) {
$tag = get_tag( $term_id );
Changes_Logs_Logger::log_change(
1407,
array(
'tagid' => $term_id,
'tagname' => $tag->name,
'slug' => $tag->slug,
)
);
} elseif ( 'category' === $taxonomy ) {
$category = get_category( $term_id );
Changes_Logs_Logger::log_change(
1375,
array(
'categoryid' => $term_id,
'categoryname' => $category->cat_name,
'slug' => $category->slug,
)
);
}
}
}