ors: 1: Blog name, 2: Source of action. For e.g. Hub or a logged-in user, 3: Post type, 4: Post title */ esc_html__( '%1$s %2$s drafted %3$s "%4$s"', 'wpdef' ), '{{blog_name}}', '{{wp_user}}', '{{post_type_label}}', '{{post_title}}' ), '{{new_status}}', 'draft', '==', ), array( sprintf( /* translators: 1: Blog name, 2: Source of action. For e.g. Hub or a logged-in user, 3: Post type, 4: Post title, 5: Old status, 6: New status */ esc_html__( '%1$s %2$s changed %3$s "%4$s" status from %5$s to %6$s', 'wpdef' ), '{{blog_name}}', '{{wp_user}}', '{{post_type_label}}', '{{post_title}}', '{{old_status}}', '{{new_status}}' ), '{{new_status}}', '{{new_status}}', '==', ), ), 'program_args' => array( 'post_type_label' => array( 'callable' => 'get_post_type_object', 'params' => array( '{{post->post_type}}' ), 'result_property' => 'labels->singular_name', ), ), 'custom_args' => array( 'post_title' => '{{post->post_title}}', ), 'context' => '{{post_type_label}}', ), 'delete_post' => array( 'args' => array( 'post_ID' ), 'event_type' => Audit_Log::EVENT_TYPE_CONTENT, 'action_type' => self::ACTION_DELETED, 'text' => sprintf( /* translators: 1: Blog name, 2: Source of action. For e.g. Hub or a logged-in user, 3: Post type, 4: Post title */ esc_html__( '%1$s %2$s deleted %3$s "%4$s"', 'wpdef' ), '{{blog_name}}', '{{wp_user}}', '{{post_type_label}}', '{{post_title}}' ), 'program_args' => array( 'post' => array( 'callable' => 'get_post', 'params' => array( '{{post_ID}}' ), ), 'post_type_label' => array( 'callable' => 'get_post_type_object', 'params' => array( '{{post->post_type}}' ), 'result_property' => 'labels->singular_name', ), 'post_title' => array( 'callable' => 'get_post', 'params' => array( '{{post_ID}}' ), 'result_property' => 'post_title', ), ), 'context' => '{{post_type_label}}', 'false_when' => array( array( '{{post->post_type}}', array_merge( array( 'attachment' ), $this->exclude_events() ), ), array( '{{post_type_label}}', '', ), ), ), 'untrashed_post' => array( 'args' => array( 'post_ID' ), 'action_type' => self::ACTION_RESTORED, 'event_type' => Audit_Log::EVENT_TYPE_CONTENT, 'text' => sprintf( /* translators: 1: Blog name, 2: Source of action. For e.g. Hub or a logged-in user, 3: Post type, 4: Post title */ esc_html__( '%1$s %2$s untrashed %3$s "%4$s"', 'wpdef' ), '{{blog_name}}', '{{wp_user}}', '{{post_type_label}}', '{{post_title}}' ), 'program_args' => array( 'post' => array( 'callable' => 'get_post', 'params' => array( '{{post_ID}}' ), ), 'post_type_label' => array( 'callable' => 'get_post_type_object', 'params' => array( '{{post->post_type}}' ), 'result_property' => 'labels->singular_name', ), 'post_title' => array( 'callable' => 'get_post', 'params' => array( '{{post_ID}}' ), 'result_property' => 'post_title', ), ), 'context' => '{{post_type_label}}', ), 'trashed_post' => array( 'args' => array( 'post_ID' ), 'action_type' => self::ACTION_TRASHED, 'event_type' => Audit_Log::EVENT_TYPE_CONTENT, 'text' => sprintf( /* translators: 1: Blog name, 2: Source of action. For e.g. Hub or a logged-in user, 3: Post type, 4: Post title */ esc_html__( '%1$s %2$s trashed %3$s "%4$s"', 'wpdef' ), '{{blog_name}}', '{{wp_user}}', '{{post_type_label}}', '{{post_title}}' ), 'program_args' => array( 'post' => array( 'callable' => 'get_post', 'params' => array( '{{post_ID}}' ), ), 'post_type_label' => array( 'callable' => 'get_post_type_object', 'params' => array( '{{post->post_type}}' ), 'result_property' => 'labels->singular_name', ), 'post_title' => array( 'callable' => 'get_post', 'params' => array( '{{post_ID}}' ), 'result_property' => 'post_title', ), ), 'context' => '{{post_type_label}}', ), ); } /** * Callback function for the save_post hook. It determines if a post has been updated and logs the appropriate * audit event. * * @return bool|array */ public function post_updated_callback() { if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return false; } $args = func_get_args(); $post = $args[1]['post']; if ( in_array( $post->post_status, array( 'trash', 'auto-draft' ), true ) ) { // Usually, wp adds :trash to the post name, so this case we just return. return false; } if ( in_array( $post->post_type, $this->exclude_events(), true ) ) { return false; } $post_type = get_post_type_object( $post->post_type ); if ( ! is_object( $post_type ) ) { return false; } $is_updated = $args[1]['is_updated']; $post_before = null; $cached = Array_Cache::get( 'post_updated', 'audit', array() ); foreach ( $cached as $post_arr ) { if ( $post->ID === $post_arr['post_id'] ) { $post_before = $post_arr['before']; break; } } $blog_name = is_multisite() ? '[' . get_bloginfo( 'name' ) . ']' : ''; if ( true === $is_updated ) { if ( ! is_null( $post_before ) ) { $post_after = $post->to_array(); $post_before = $post_before->to_array(); // Status transitions are handled via other hooks. if ( $post_before['post_status'] !== $post_after['post_status'] ) { return false; } // Unset the date modified, and post status, as we got another hook for that. unset( $post_after['post_modified'] ); unset( $post_after['post_modified_gmt'] ); unset( $post_after['post_status'] ); unset( $post_before['post_modified'] ); unset( $post_before['post_modified_gmt'] ); unset( $post_before['post_status'] ); if ( wp_json_encode( $post_before ) !== wp_json_encode( $post_after ) ) { $item_changed_count = count( self::array_recursive_diff( $post_before, $post_after ) ); if ( $post_before['post_title'] !== $post_after['post_title'] && 1 === $item_changed_count ) { $text = sprintf( /* translators: 1: Blog name, 2: User's display name, 3: Post type, 4: Post ID, 5: Old post title, 6: New post title */ esc_html__( '%1$s %2$s updated %3$s ID %4$d, title from "%5$s" to "%6$s"', 'wpdef' ), $blog_name, $this->get_user_display( get_current_user_id() ), $post_type->labels->singular_name, $post_after['ID'], $post_before['post_title'], $post_after['post_title'] ); } elseif ( $post_before['post_name'] !== $post_after['post_name'] && 1 === $item_changed_count ) { $text = sprintf( /* translators: 1: Blog name, 2: User's display name, 3: Post type, 4: Post ID, 5: Old post slug, 6: New post slug */ esc_html__( '%1$s %2$s updated %3$s ID %4$d, slug from "%5$s" to "%6$s"', 'wpdef' ), $blog_name, $this->get_user_display( get_current_user_id() ), $post_type->labels->singular_name, $post_after['ID'], $post_before['post_name'], $post_after['post_name'] ); } elseif ( $post_before['post_author'] !== $post_after['post_author'] && 1 === $item_changed_count ) { $text = sprintf( /* translators: 1: Blog name, 2: User's display name, 3: Post type, 4: Post ID, 5: Old author name, 6: New author name */ esc_html__( '%1$s %2$s updated %3$s ID %4$d, author from "%5$s" to "%6$s"', 'wpdef' ), $blog_name, $this->get_user_display( get_current_user_id() ), $post_type->labels->singular_name, $post_after['ID'], $this->get_user_display( $post_before['post_author'] ), $this->get_user_display( $post_after['post_author'] ) ); } else { $text = sprintf( /* translators: 1: Blog name, 2: User's display name, 3: Post type, 4: Post title */ esc_html__( '%1$s %2$s updated %3$s "%4$s"', 'wpdef' ), $blog_name, $this->get_user_display( get_current_user_id() ), $post_type->labels->singular_name, $post_after['post_title'] ); } return array( $text, $post_type->labels->singular_name, ); } } } elseif ( is_null( $post_before ) ) { $text = sprintf( /* translators: 1: Blog name, 2: User's display name, 3: Post type, 4: Post title */ esc_html__( '%1$s %2$s added new %3$s "%4$s"', 'wpdef' ), $blog_name, $this->get_user_display( get_current_user_id() ), $post_type->labels->singular_name, $post->post_title ); return array( $text, $post_type->labels->singular_name, ); } return false; } /** * Provides a dictionary or glossary that could be used for translating or explaining terms. Currently, returns an * empty array. * * @return array */ public function dictionary(): array { return array(); } }