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();
}
}