diff -r 7b1b88e27a20 -r 48c4eec2b7e6 wp/wp-admin/includes/post.php
--- a/wp/wp-admin/includes/post.php Thu Sep 29 08:06:27 2022 +0200
+++ b/wp/wp-admin/includes/post.php Fri Sep 05 18:40:08 2025 +0200
@@ -72,7 +72,7 @@
}
}
- if ( isset( $post_data['user_ID'] ) && ( $post_data['post_author'] != $post_data['user_ID'] )
+ if ( isset( $post_data['user_ID'] ) && ( $post_data['post_author'] !== $post_data['user_ID'] )
&& ! current_user_can( $ptype->cap->edit_others_posts ) ) {
if ( $update ) {
@@ -135,8 +135,10 @@
$published_statuses = array( 'publish', 'future' );
- // Posts 'submitted for approval' are submitted to $_POST the same as if they were being published.
- // Change status from 'publish' to 'pending' if user lacks permissions to publish or to resave published posts.
+ /*
+ * Posts 'submitted for approval' are submitted to $_POST the same as if they were being published.
+ * Change status from 'publish' to 'pending' if user lacks permissions to publish or to resave published posts.
+ */
if ( isset( $post_data['post_status'] )
&& ( in_array( $post_data['post_status'], $published_statuses, true )
&& ! current_user_can( $ptype->cap->publish_posts ) )
@@ -163,7 +165,7 @@
}
foreach ( array( 'aa', 'mm', 'jj', 'hh', 'mn' ) as $timeunit ) {
- if ( ! empty( $post_data[ 'hidden_' . $timeunit ] ) && $post_data[ 'hidden_' . $timeunit ] != $post_data[ $timeunit ] ) {
+ if ( ! empty( $post_data[ 'hidden_' . $timeunit ] ) && $post_data[ 'hidden_' . $timeunit ] !== $post_data[ $timeunit ] ) {
$post_data['edit_date'] = '1';
break;
}
@@ -191,7 +193,19 @@
return new WP_Error( 'invalid_date', __( 'Invalid date.' ) );
}
- $post_data['post_date_gmt'] = get_gmt_from_date( $post_data['post_date'] );
+ /*
+ * Only assign a post date if the user has explicitly set a new value.
+ * See #59125 and #19907.
+ */
+ $previous_date = $post_id ? get_post_field( 'post_date', $post_id ) : false;
+ if ( $previous_date && $previous_date !== $post_data['post_date'] ) {
+ $post_data['edit_date'] = true;
+ $post_data['post_date_gmt'] = get_gmt_from_date( $post_data['post_date'] );
+ } else {
+ $post_data['edit_date'] = false;
+ unset( $post_data['post_date'] );
+ unset( $post_data['post_date_gmt'] );
+ }
}
if ( isset( $post_data['post_category'] ) ) {
@@ -252,8 +266,8 @@
// Clear out any data in internal vars.
unset( $post_data['filter'] );
- $post_ID = (int) $post_data['post_ID'];
- $post = get_post( $post_ID );
+ $post_id = (int) $post_data['post_ID'];
+ $post = get_post( $post_id );
$post_data['post_type'] = $post->post_type;
$post_data['post_mime_type'] = $post->post_mime_type;
@@ -267,7 +281,7 @@
}
$ptype = get_post_type_object( $post_data['post_type'] );
- if ( ! current_user_can( 'edit_post', $post_ID ) ) {
+ if ( ! current_user_can( 'edit_post', $post_id ) ) {
if ( 'page' === $post_data['post_type'] ) {
wp_die( __( 'Sorry, you are not allowed to edit this page.' ) );
} else {
@@ -277,7 +291,7 @@
if ( post_type_supports( $ptype->name, 'revisions' ) ) {
$revisions = wp_get_post_revisions(
- $post_ID,
+ $post_id,
array(
'order' => 'ASC',
'posts_per_page' => 1,
@@ -287,7 +301,7 @@
// Check if the revisions have been upgraded.
if ( $revisions && _wp_get_post_revision_version( $revision ) < 1 ) {
- _wp_upgrade_revisions_of_post( $post, wp_get_post_revisions( $post_ID ) );
+ _wp_upgrade_revisions_of_post( $post, wp_get_post_revisions( $post_id ) );
}
}
@@ -315,14 +329,14 @@
// Post formats.
if ( isset( $post_data['post_format'] ) ) {
- set_post_format( $post_ID, $post_data['post_format'] );
+ set_post_format( $post_id, $post_data['post_format'] );
}
$format_meta_urls = array( 'url', 'link_url', 'quote_source_url' );
foreach ( $format_meta_urls as $format_meta_url ) {
$keyed = '_format_' . $format_meta_url;
if ( isset( $post_data[ $keyed ] ) ) {
- update_post_meta( $post_ID, $keyed, wp_slash( esc_url_raw( wp_unslash( $post_data[ $keyed ] ) ) ) );
+ update_post_meta( $post_id, $keyed, wp_slash( sanitize_url( wp_unslash( $post_data[ $keyed ] ) ) ) );
}
}
@@ -332,15 +346,15 @@
$keyed = '_format_' . $key;
if ( isset( $post_data[ $keyed ] ) ) {
if ( current_user_can( 'unfiltered_html' ) ) {
- update_post_meta( $post_ID, $keyed, $post_data[ $keyed ] );
+ update_post_meta( $post_id, $keyed, $post_data[ $keyed ] );
} else {
- update_post_meta( $post_ID, $keyed, wp_filter_post_kses( $post_data[ $keyed ] ) );
+ update_post_meta( $post_id, $keyed, wp_filter_post_kses( $post_data[ $keyed ] ) );
}
}
}
if ( 'attachment' === $post_data['post_type'] && preg_match( '#^(audio|video)/#', $post_data['post_mime_type'] ) ) {
- $id3data = wp_get_attachment_metadata( $post_ID );
+ $id3data = wp_get_attachment_metadata( $post_id );
if ( ! is_array( $id3data ) ) {
$id3data = array();
}
@@ -350,7 +364,7 @@
$id3data[ $key ] = sanitize_text_field( wp_unslash( $post_data[ 'id3_' . $key ] ) );
}
}
- wp_update_attachment_metadata( $post_ID, $id3data );
+ wp_update_attachment_metadata( $post_id, $id3data );
}
// Meta stuff.
@@ -360,15 +374,23 @@
if ( ! $meta ) {
continue;
}
- if ( $meta->post_id != $post_ID ) {
+
+ if ( (int) $meta->post_id !== $post_id ) {
continue;
}
- if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'edit_post_meta', $post_ID, $meta->meta_key ) ) {
+
+ if ( is_protected_meta( $meta->meta_key, 'post' )
+ || ! current_user_can( 'edit_post_meta', $post_id, $meta->meta_key )
+ ) {
continue;
}
- if ( is_protected_meta( $value['key'], 'post' ) || ! current_user_can( 'edit_post_meta', $post_ID, $value['key'] ) ) {
+
+ if ( is_protected_meta( $value['key'], 'post' )
+ || ! current_user_can( 'edit_post_meta', $post_id, $value['key'] )
+ ) {
continue;
}
+
update_meta( $key, $value['key'], $value['value'] );
}
}
@@ -379,12 +401,17 @@
if ( ! $meta ) {
continue;
}
- if ( $meta->post_id != $post_ID ) {
+
+ if ( (int) $meta->post_id !== $post_id ) {
continue;
}
- if ( is_protected_meta( $meta->meta_key, 'post' ) || ! current_user_can( 'delete_post_meta', $post_ID, $meta->meta_key ) ) {
+
+ if ( is_protected_meta( $meta->meta_key, 'post' )
+ || ! current_user_can( 'delete_post_meta', $post_id, $meta->meta_key )
+ ) {
continue;
}
+
delete_meta( $key );
}
}
@@ -394,15 +421,15 @@
if ( isset( $post_data['_wp_attachment_image_alt'] ) ) {
$image_alt = wp_unslash( $post_data['_wp_attachment_image_alt'] );
- if ( get_post_meta( $post_ID, '_wp_attachment_image_alt', true ) !== $image_alt ) {
+ if ( get_post_meta( $post_id, '_wp_attachment_image_alt', true ) !== $image_alt ) {
$image_alt = wp_strip_all_tags( $image_alt, true );
// update_post_meta() expects slashed.
- update_post_meta( $post_ID, '_wp_attachment_image_alt', wp_slash( $image_alt ) );
+ update_post_meta( $post_id, '_wp_attachment_image_alt', wp_slash( $image_alt ) );
}
}
- $attachment_data = isset( $post_data['attachments'][ $post_ID ] ) ? $post_data['attachments'][ $post_ID ] : array();
+ $attachment_data = isset( $post_data['attachments'][ $post_id ] ) ? $post_data['attachments'][ $post_id ] : array();
/** This filter is documented in wp-admin/includes/media.php */
$translated = apply_filters( 'attachment_fields_to_save', $translated, $attachment_data );
@@ -419,13 +446,13 @@
}
}
- add_meta( $post_ID );
-
- update_post_meta( $post_ID, '_edit_last', get_current_user_id() );
+ add_meta( $post_id );
+
+ update_post_meta( $post_id, '_edit_last', get_current_user_id() );
$success = wp_update_post( $translated );
- // If the save failed, see if we can sanity check the main fields and try again.
+ // If the save failed, see if we can confidence check the main fields and try again.
if ( ! $success && is_callable( array( $wpdb, 'strip_invalid_text_for_column' ) ) ) {
$fields = array( 'post_title', 'post_content', 'post_excerpt' );
@@ -439,19 +466,19 @@
}
// Now that we have an ID we can fix any attachment anchor hrefs.
- _fix_attachment_links( $post_ID );
-
- wp_set_post_lock( $post_ID );
+ _fix_attachment_links( $post_id );
+
+ wp_set_post_lock( $post_id );
if ( current_user_can( $ptype->cap->edit_others_posts ) && current_user_can( $ptype->cap->publish_posts ) ) {
if ( ! empty( $post_data['sticky'] ) ) {
- stick_post( $post_ID );
+ stick_post( $post_id );
} else {
- unstick_post( $post_ID );
+ unstick_post( $post_id );
}
}
- return $post_ID;
+ return $post_id;
}
/**
@@ -489,7 +516,7 @@
}
}
- if ( -1 == $post_data['_status'] ) {
+ if ( '-1' === $post_data['_status'] ) {
$post_data['post_status'] = null;
unset( $post_data['post_status'] );
} else {
@@ -505,7 +532,7 @@
}
}
- $post_IDs = array_map( 'intval', (array) $post_data['post'] );
+ $post_ids = array_map( 'intval', (array) $post_data['post'] );
$reset = array(
'post_author',
@@ -523,7 +550,7 @@
);
foreach ( $reset as $field ) {
- if ( isset( $post_data[ $field ] ) && ( '' === $post_data[ $field ] || -1 == $post_data[ $field ] ) ) {
+ if ( isset( $post_data[ $field ] ) && ( '' === $post_data[ $field ] || '-1' === $post_data[ $field ] ) ) {
unset( $post_data[ $field ] );
}
}
@@ -542,6 +569,7 @@
if ( empty( $terms ) ) {
continue;
}
+
if ( is_taxonomy_hierarchical( $tax_name ) ) {
$tax_input[ $tax_name ] = array_map( 'absint', $terms );
} else {
@@ -576,29 +604,35 @@
$locked = array();
$shared_post_data = $post_data;
- foreach ( $post_IDs as $post_ID ) {
+ foreach ( $post_ids as $post_id ) {
// Start with fresh post data with each iteration.
$post_data = $shared_post_data;
- $post_type_object = get_post_type_object( get_post_type( $post_ID ) );
+ $post_type_object = get_post_type_object( get_post_type( $post_id ) );
if ( ! isset( $post_type_object )
- || ( isset( $children ) && in_array( $post_ID, $children, true ) )
- || ! current_user_can( 'edit_post', $post_ID )
+ || ( isset( $children ) && in_array( $post_id, $children, true ) )
+ || ! current_user_can( 'edit_post', $post_id )
) {
- $skipped[] = $post_ID;
+ $skipped[] = $post_id;
+ continue;
+ }
+
+ if ( wp_check_post_lock( $post_id ) ) {
+ $locked[] = $post_id;
continue;
}
- if ( wp_check_post_lock( $post_ID ) ) {
- $locked[] = $post_ID;
- continue;
- }
-
- $post = get_post( $post_ID );
+ $post = get_post( $post_id );
$tax_names = get_object_taxonomies( $post );
+
foreach ( $tax_names as $tax_name ) {
$taxonomy_obj = get_taxonomy( $tax_name );
+
+ if ( ! $taxonomy_obj->show_in_quick_edit ) {
+ continue;
+ }
+
if ( isset( $tax_input[ $tax_name ] ) && current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
$new_terms = $tax_input[ $tax_name ];
} else {
@@ -606,21 +640,34 @@
}
if ( $taxonomy_obj->hierarchical ) {
- $current_terms = (array) wp_get_object_terms( $post_ID, $tax_name, array( 'fields' => 'ids' ) );
+ $current_terms = (array) wp_get_object_terms( $post_id, $tax_name, array( 'fields' => 'ids' ) );
} else {
- $current_terms = (array) wp_get_object_terms( $post_ID, $tax_name, array( 'fields' => 'names' ) );
+ $current_terms = (array) wp_get_object_terms( $post_id, $tax_name, array( 'fields' => 'names' ) );
}
$post_data['tax_input'][ $tax_name ] = array_merge( $current_terms, $new_terms );
}
if ( isset( $new_cats ) && in_array( 'category', $tax_names, true ) ) {
- $cats = (array) wp_get_post_categories( $post_ID );
- $post_data['post_category'] = array_unique( array_merge( $cats, $new_cats ) );
+ $cats = (array) wp_get_post_categories( $post_id );
+
+ if (
+ isset( $post_data['indeterminate_post_category'] )
+ && is_array( $post_data['indeterminate_post_category'] )
+ ) {
+ $indeterminate_post_category = $post_data['indeterminate_post_category'];
+ } else {
+ $indeterminate_post_category = array();
+ }
+
+ $indeterminate_cats = array_intersect( $cats, $indeterminate_post_category );
+ $determinate_cats = array_diff( $new_cats, $indeterminate_post_category );
+ $post_data['post_category'] = array_unique( array_merge( $indeterminate_cats, $determinate_cats ) );
+
unset( $post_data['tax_input']['category'] );
}
- $post_data['post_ID'] = $post_ID;
+ $post_data['post_ID'] = $post_id;
$post_data['post_type'] = $post->post_type;
$post_data['post_mime_type'] = $post->post_mime_type;
@@ -632,31 +679,50 @@
$post_data = _wp_translate_postdata( true, $post_data );
if ( is_wp_error( $post_data ) ) {
- $skipped[] = $post_ID;
+ $skipped[] = $post_id;
continue;
}
$post_data = _wp_get_allowed_postdata( $post_data );
if ( isset( $shared_post_data['post_format'] ) ) {
- set_post_format( $post_ID, $shared_post_data['post_format'] );
+ set_post_format( $post_id, $shared_post_data['post_format'] );
}
// Prevent wp_insert_post() from overwriting post format with the old data.
unset( $post_data['tax_input']['post_format'] );
+ // Reset post date of scheduled post to be published.
+ if (
+ in_array( $post->post_status, array( 'future', 'draft' ), true ) &&
+ 'publish' === $post_data['post_status']
+ ) {
+ $post_data['post_date'] = current_time( 'mysql' );
+ $post_data['post_date_gmt'] = '';
+ }
+
$post_id = wp_update_post( $post_data );
update_post_meta( $post_id, '_edit_last', get_current_user_id() );
$updated[] = $post_id;
if ( isset( $post_data['sticky'] ) && current_user_can( $ptype->cap->edit_others_posts ) ) {
if ( 'sticky' === $post_data['sticky'] ) {
- stick_post( $post_ID );
+ stick_post( $post_id );
} else {
- unstick_post( $post_ID );
+ unstick_post( $post_id );
}
}
}
+ /**
+ * Fires after processing the post data for bulk edit.
+ *
+ * @since 6.3.0
+ *
+ * @param int[] $updated An array of updated post IDs.
+ * @param array $shared_post_data Associative array containing the post data.
+ */
+ do_action( 'bulk_edit_posts', $updated, $shared_post_data );
+
return array(
'updated' => $updated,
'skipped' => $skipped,
@@ -710,7 +776,7 @@
wp_schedule_event( time(), 'daily', 'wp_scheduled_auto_draft_delete' );
}
} else {
- $post = new stdClass;
+ $post = new stdClass();
$post->ID = 0;
$post->post_author = '';
$post->post_date = '';
@@ -881,25 +947,25 @@
$translated = _wp_get_allowed_postdata( $translated );
// Create the post.
- $post_ID = wp_insert_post( $translated );
- if ( is_wp_error( $post_ID ) ) {
- return $post_ID;
+ $post_id = wp_insert_post( $translated );
+ if ( is_wp_error( $post_id ) ) {
+ return $post_id;
}
- if ( empty( $post_ID ) ) {
+ if ( empty( $post_id ) ) {
return 0;
}
- add_meta( $post_ID );
-
- add_post_meta( $post_ID, '_edit_last', $GLOBALS['current_user']->ID );
+ add_meta( $post_id );
+
+ add_post_meta( $post_id, '_edit_last', $GLOBALS['current_user']->ID );
// Now that we have an ID we can fix any attachment anchor hrefs.
- _fix_attachment_links( $post_ID );
-
- wp_set_post_lock( $post_ID );
-
- return $post_ID;
+ _fix_attachment_links( $post_id );
+
+ wp_set_post_lock( $post_id );
+
+ return $post_id;
}
/**
@@ -927,11 +993,11 @@
*
* @since 1.2.0
*
- * @param int $post_ID
+ * @param int $post_id
* @return int|bool
*/
-function add_meta( $post_ID ) {
- $post_ID = (int) $post_ID;
+function add_meta( $post_id ) {
+ $post_id = (int) $post_id;
$metakeyselect = isset( $_POST['metakeyselect'] ) ? wp_unslash( trim( $_POST['metakeyselect'] ) ) : '';
$metakeyinput = isset( $_POST['metakeyinput'] ) ? wp_unslash( trim( $_POST['metakeyinput'] ) ) : '';
@@ -953,13 +1019,13 @@
$metakey = $metakeyinput; // Default.
}
- if ( is_protected_meta( $metakey, 'post' ) || ! current_user_can( 'add_post_meta', $post_ID, $metakey ) ) {
+ if ( is_protected_meta( $metakey, 'post' ) || ! current_user_can( 'add_post_meta', $post_id, $metakey ) ) {
return false;
}
$metakey = wp_slash( $metakey );
- return add_post_meta( $post_ID, $metakey, $metavalue );
+ return add_post_meta( $post_id, $metakey, $metavalue );
}
return false;
@@ -990,11 +1056,10 @@
global $wpdb;
$keys = $wpdb->get_col(
- "
- SELECT meta_key
- FROM $wpdb->postmeta
- GROUP BY meta_key
- ORDER BY meta_key"
+ "SELECT meta_key
+ FROM $wpdb->postmeta
+ GROUP BY meta_key
+ ORDER BY meta_key"
);
return $keys;
@@ -1019,7 +1084,7 @@
*
* @global wpdb $wpdb WordPress database abstraction object.
*
- * @param int $postid A post ID.
+ * @param int $post_id A post ID.
* @return array[] {
* Array of meta data arrays for the given post ID.
*
@@ -1033,7 +1098,7 @@
* }
* }
*/
-function has_meta( $postid ) {
+function has_meta( $post_id ) {
global $wpdb;
return $wpdb->get_results(
@@ -1041,7 +1106,7 @@
"SELECT meta_key, meta_value, meta_id, post_id
FROM $wpdb->postmeta WHERE post_id = %d
ORDER BY meta_key,meta_id",
- $postid
+ $post_id
),
ARRAY_A
);
@@ -1074,7 +1139,7 @@
* @since 2.3.0
* @access private
*
- * @param int|object $post Post ID or post object.
+ * @param int|WP_Post $post Post ID or post object.
* @return void|int|WP_Error Void if nothing fixed. 0 or WP_Error on update failure. The post ID on update success.
*/
function _fix_attachment_links( $post ) {
@@ -1106,7 +1171,7 @@
$url_id = (int) $url_match[2];
$rel_id = (int) $rel_match[1];
- if ( ! $url_id || ! $rel_id || $url_id != $rel_id || strpos( $url_match[0], $site_url ) === false ) {
+ if ( ! $url_id || ! $rel_id || $url_id != $rel_id || ! str_contains( $url_match[0], $site_url ) ) {
continue;
}
@@ -1134,9 +1199,9 @@
* @return string[] An array of all the statuses for the supplied post type.
*/
function get_available_post_statuses( $type = 'post' ) {
- $stati = wp_count_posts( $type );
-
- return array_keys( get_object_vars( $stati ) );
+ $statuses = wp_count_posts( $type );
+
+ return array_keys( get_object_vars( $statuses ) );
}
/**
@@ -1152,9 +1217,11 @@
if ( false === $q ) {
$q = $_GET;
}
- $q['m'] = isset( $q['m'] ) ? (int) $q['m'] : 0;
- $q['cat'] = isset( $q['cat'] ) ? (int) $q['cat'] : 0;
- $post_stati = get_post_stati();
+
+ $q['m'] = isset( $q['m'] ) ? (int) $q['m'] : 0;
+ $q['cat'] = isset( $q['cat'] ) ? (int) $q['cat'] : 0;
+
+ $post_statuses = get_post_stati();
if ( isset( $q['post_type'] ) && in_array( $q['post_type'], get_post_types(), true ) ) {
$post_type = $q['post_type'];
@@ -1166,7 +1233,7 @@
$post_status = '';
$perm = '';
- if ( isset( $q['post_status'] ) && in_array( $q['post_status'], $post_stati, true ) ) {
+ if ( isset( $q['post_status'] ) && in_array( $q['post_status'], $post_statuses, true ) ) {
$post_status = $q['post_status'];
$perm = 'readable';
}
@@ -1302,7 +1369,7 @@
// Filter query clauses to include filenames.
if ( isset( $q['s'] ) ) {
- add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+ add_filter( 'wp_allow_query_attachment_by_filename', '__return_true' );
}
return $q;
@@ -1337,7 +1404,7 @@
* @return string Space-separated string of class names.
*/
function postbox_classes( $box_id, $screen_id ) {
- if ( isset( $_GET['edit'] ) && $_GET['edit'] == $box_id ) {
+ if ( isset( $_GET['edit'] ) && $_GET['edit'] === $box_id ) {
$classes = array( '' );
} elseif ( get_user_option( 'closedpostboxes_' . $screen_id ) ) {
$closed = get_user_option( 'closedpostboxes_' . $screen_id );
@@ -1370,7 +1437,7 @@
*
* @since 2.5.0
*
- * @param int|WP_Post $id Post ID or post object.
+ * @param int|WP_Post $post Post ID or post object.
* @param string|null $title Optional. Title to override the post's current title
* when generating the post name. Default null.
* @param string|null $name Optional. Name to override the post name. Default null.
@@ -1381,8 +1448,9 @@
* @type string $1 The post name.
* }
*/
-function get_sample_permalink( $id, $title = null, $name = null ) {
- $post = get_post( $id );
+function get_sample_permalink( $post, $title = null, $name = null ) {
+ $post = get_post( $post );
+
if ( ! $post ) {
return array( '', '' );
}
@@ -1392,15 +1460,18 @@
$original_status = $post->post_status;
$original_date = $post->post_date;
$original_name = $post->post_name;
+ $original_filter = $post->filter;
// Hack: get_permalink() would return plain permalink for drafts, so we will fake that our post is published.
- if ( in_array( $post->post_status, array( 'draft', 'pending', 'future' ), true ) ) {
+ if ( in_array( $post->post_status, array( 'auto-draft', 'draft', 'pending', 'future' ), true ) ) {
$post->post_status = 'publish';
$post->post_name = sanitize_title( $post->post_name ? $post->post_name : $post->post_title, $post->ID );
}
- // If the user wants to set a new name -- override the current one.
- // Note: if empty name is supplied -- use the title instead, see #6072.
+ /*
+ * If the user wants to set a new name -- override the current one.
+ * Note: if empty name is supplied -- use the title instead, see #6072.
+ */
if ( ! is_null( $name ) ) {
$post->post_name = sanitize_title( $name ? $name : $title, $post->ID );
}
@@ -1436,7 +1507,7 @@
$post->post_status = $original_status;
$post->post_date = $original_date;
$post->post_name = $original_name;
- unset( $post->filter );
+ $post->filter = $original_filter;
/**
* Filters the sample permalink.
@@ -1462,13 +1533,14 @@
*
* @since 2.5.0
*
- * @param int|WP_Post $id Post ID or post object.
+ * @param int|WP_Post $post Post ID or post object.
* @param string|null $new_title Optional. New title. Default null.
* @param string|null $new_slug Optional. New slug. Default null.
* @return string The HTML of the sample permalink slug editor.
*/
-function get_sample_permalink_html( $id, $new_title = null, $new_slug = null ) {
- $post = get_post( $id );
+function get_sample_permalink_html( $post, $new_title = null, $new_slug = null ) {
+ $post = get_post( $post );
+
if ( ! $post ) {
return '';
}
@@ -1493,7 +1565,7 @@
}
// Permalinks without a post/page name placeholder don't have anything to edit.
- if ( false === strpos( $permalink, '%postname%' ) && false === strpos( $permalink, '%pagename%' ) ) {
+ if ( ! str_contains( $permalink, '%postname%' ) && ! str_contains( $permalink, '%pagename%' ) ) {
$return = '' . __( 'Permalink:' ) . "\n";
if ( false !== $view_link ) {
@@ -1505,7 +1577,7 @@
// Encourage a pretty permalink setting.
if ( ! get_option( 'permalink_structure' ) && current_user_can( 'manage_options' )
- && ! ( 'page' === get_option( 'show_on_front' ) && get_option( 'page_on_front' ) == $id )
+ && ! ( 'page' === get_option( 'show_on_front' ) && (int) get_option( 'page_on_front' ) === $post->ID )
) {
$return .= '' . __( 'Change Permalink Structure' ) . "\n";
}
@@ -1532,11 +1604,11 @@
* @since 2.9.0
* @since 4.4.0 Added `$post` parameter.
*
- * @param string $return Sample permalink HTML markup.
- * @param int $post_id Post ID.
- * @param string $new_title New sample permalink title.
- * @param string $new_slug New sample permalink slug.
- * @param WP_Post $post Post object.
+ * @param string $return Sample permalink HTML markup.
+ * @param int $post_id Post ID.
+ * @param string|null $new_title New sample permalink title.
+ * @param string|null $new_slug New sample permalink slug.
+ * @param WP_Post $post Post object.
*/
$return = apply_filters( 'get_sample_permalink_html', $return, $post->ID, $new_title, $new_slug, $post );
@@ -1622,24 +1694,26 @@
*
* @since 2.5.0
*
- * @param int|WP_Post $post_id ID or object of the post to check for editing.
+ * @param int|WP_Post $post ID or object of the post to check for editing.
* @return int|false ID of the user with lock. False if the post does not exist, post is not locked,
* the user with lock does not exist, or the post is locked by current user.
*/
-function wp_check_post_lock( $post_id ) {
- $post = get_post( $post_id );
+function wp_check_post_lock( $post ) {
+ $post = get_post( $post );
+
if ( ! $post ) {
return false;
}
$lock = get_post_meta( $post->ID, '_edit_lock', true );
+
if ( ! $lock ) {
return false;
}
$lock = explode( ':', $lock );
$time = $lock[0];
- $user = isset( $lock[1] ) ? $lock[1] : get_post_meta( $post->ID, '_edit_last', true );
+ $user = isset( $lock[1] ) ? (int) $lock[1] : (int) get_post_meta( $post->ID, '_edit_last', true );
if ( ! get_userdata( $user ) ) {
return false;
@@ -1648,7 +1722,7 @@
/** This filter is documented in wp-admin/includes/ajax-actions.php */
$time_window = apply_filters( 'wp_check_post_lock_window', 150 );
- if ( $time && $time > time() - $time_window && get_current_user_id() != $user ) {
+ if ( $time && $time > time() - $time_window && get_current_user_id() !== $user ) {
return $user;
}
@@ -1660,7 +1734,7 @@
*
* @since 2.5.0
*
- * @param int|WP_Post $post_id ID or object of the post being edited.
+ * @param int|WP_Post $post ID or object of the post being edited.
* @return array|false {
* Array of the lock time and user ID. False if the post does not exist, or there
* is no current user.
@@ -1669,14 +1743,16 @@
* @type int $1 The ID of the current user.
* }
*/
-function wp_set_post_lock( $post_id ) {
- $post = get_post( $post_id );
+function wp_set_post_lock( $post ) {
+ $post = get_post( $post );
+
if ( ! $post ) {
return false;
}
$user_id = get_current_user_id();
- if ( 0 == $user_id ) {
+
+ if ( 0 === $user_id ) {
return false;
}
@@ -1695,12 +1771,14 @@
*/
function _admin_notice_post_locked() {
$post = get_post();
+
if ( ! $post ) {
return;
}
$user = null;
$user_id = wp_check_post_lock( $post->ID );
+
if ( $user_id ) {
$user = get_userdata( $user_id );
}
@@ -1727,7 +1805,7 @@
}
$sendback = wp_get_referer();
- if ( $locked && $sendback && false === strpos( $sendback, 'post.php' ) && false === strpos( $sendback, 'post-new.php' ) ) {
+ if ( $locked && $sendback && ! str_contains( $sendback, 'post.php' ) && ! str_contains( $sendback, 'post-new.php' ) ) {
$sendback_text = __( 'Go back' );
} else {
@@ -1751,7 +1829,7 @@
if ( $locked ) {
$query_args = array();
if ( get_post_type_object( $post->post_type )->public ) {
- if ( 'publish' === $post->post_status || $user->ID != $post->post_author ) {
+ if ( 'publish' === $post->post_status || $user->ID !== (int) $post->post_author ) {
// Latest content is in autosave.
$nonce = wp_create_nonce( 'post_preview_' . $post->ID );
$query_args['preview_id'] = $post->ID;
@@ -1902,11 +1980,12 @@
* Fires before an autosave is stored.
*
* @since 4.1.0
+ * @since 6.4.0 The `$is_update` parameter was added to indicate if the autosave is being updated or was newly created.
*
* @param array $new_autosave Post array - the autosave that is about to be saved.
+ * @param bool $is_update Whether this is an existing autosave.
*/
- do_action( 'wp_creating_autosave', $new_autosave );
-
+ do_action( 'wp_creating_autosave', $new_autosave, true );
return wp_update_post( $new_autosave );
}
@@ -1914,7 +1993,68 @@
$post_data = wp_unslash( $post_data );
// Otherwise create the new autosave as a special post revision.
- return _wp_put_post_revision( $post_data, true );
+ $revision = _wp_put_post_revision( $post_data, true );
+
+ if ( ! is_wp_error( $revision ) && 0 !== $revision ) {
+
+ /** This action is documented in wp-admin/includes/post.php */
+ do_action( 'wp_creating_autosave', get_post( $revision, ARRAY_A ), false );
+ }
+
+ return $revision;
+}
+
+/**
+ * Autosave the revisioned meta fields.
+ *
+ * Iterates through the revisioned meta fields and checks each to see if they are set,
+ * and have a changed value. If so, the meta value is saved and attached to the autosave.
+ *
+ * @since 6.4.0
+ *
+ * @param array $new_autosave The new post data being autosaved.
+ */
+function wp_autosave_post_revisioned_meta_fields( $new_autosave ) {
+ /*
+ * The post data arrives as either $_POST['data']['wp_autosave'] or the $_POST
+ * itself. This sets $posted_data to the correct variable.
+ *
+ * Ignoring sanitization to avoid altering meta. Ignoring the nonce check because
+ * this is hooked on inner core hooks where a valid nonce was already checked.
+ */
+ $posted_data = isset( $_POST['data']['wp_autosave'] ) ? $_POST['data']['wp_autosave'] : $_POST;
+
+ $post_type = get_post_type( $new_autosave['post_parent'] );
+
+ /*
+ * Go thru the revisioned meta keys and save them as part of the autosave, if
+ * the meta key is part of the posted data, the meta value is not blank and
+ * the the meta value has changes from the last autosaved value.
+ */
+ foreach ( wp_post_revision_meta_keys( $post_type ) as $meta_key ) {
+
+ if (
+ isset( $posted_data[ $meta_key ] ) &&
+ get_post_meta( $new_autosave['ID'], $meta_key, true ) !== wp_unslash( $posted_data[ $meta_key ] )
+ ) {
+ /*
+ * Use the underlying delete_metadata() and add_metadata() functions
+ * vs delete_post_meta() and add_post_meta() to make sure we're working
+ * with the actual revision meta.
+ */
+ delete_metadata( 'post', $new_autosave['ID'], $meta_key );
+
+ /*
+ * One last check to ensure meta value not empty().
+ */
+ if ( ! empty( $posted_data[ $meta_key ] ) ) {
+ /*
+ * Add the revisions meta data to the autosave.
+ */
+ add_metadata( 'post', $new_autosave['ID'], $meta_key, $posted_data[ $meta_key ] );
+ }
+ }
+ }
}
/**
@@ -1926,10 +2066,11 @@
*/
function post_preview() {
- $post_ID = (int) $_POST['post_ID'];
- $_POST['ID'] = $post_ID;
-
- $post = get_post( $post_ID );
+ $post_id = (int) $_POST['post_ID'];
+ $_POST['ID'] = $post_id;
+
+ $post = get_post( $post_id );
+
if ( ! $post ) {
wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
}
@@ -1940,7 +2081,7 @@
$is_autosave = false;
- if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() == $post->post_author
+ if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() === (int) $post->post_author
&& ( 'draft' === $post->post_status || 'auto-draft' === $post->post_status )
) {
$saved_post_id = edit_post();
@@ -2015,14 +2156,16 @@
$post_data['post_category'] = explode( ',', $post_data['catslist'] );
}
- if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() == $post->post_author
+ if ( ! wp_check_post_lock( $post->ID ) && get_current_user_id() === (int) $post->post_author
&& ( 'auto-draft' === $post->post_status || 'draft' === $post->post_status )
) {
// Drafts and auto-drafts are just overwritten by autosave for the same user if the post is not locked.
return edit_post( wp_slash( $post_data ) );
} else {
- // Non-drafts or other users' drafts are not overwritten.
- // The autosave is stored in a special post revision for each user.
+ /*
+ * Non-drafts or other users' drafts are not overwritten.
+ * The autosave is stored in a special post revision for each user.
+ */
return wp_create_post_autosave( wp_slash( $post_data ) );
}
}
@@ -2038,19 +2181,19 @@
if ( isset( $_POST['save'] ) || isset( $_POST['publish'] ) ) {
$status = get_post_status( $post_id );
- if ( isset( $_POST['publish'] ) ) {
- switch ( $status ) {
- case 'pending':
- $message = 8;
- break;
- case 'future':
- $message = 9;
- break;
- default:
- $message = 6;
- }
- } else {
- $message = 'draft' === $status ? 10 : 1;
+ switch ( $status ) {
+ case 'pending':
+ $message = 8;
+ break;
+ case 'future':
+ $message = 9;
+ break;
+ case 'draft':
+ $message = 10;
+ break;
+ default:
+ $message = isset( $_POST['publish'] ) ? 6 : 1;
+ break;
}
$location = add_query_arg( 'message', $message, get_edit_post_link( $post_id, 'url' ) );
@@ -2142,82 +2285,14 @@
}
/**
- * Returns whether the post can be edited in the block editor.
- *
- * @since 5.0.0
- *
- * @param int|WP_Post $post Post ID or WP_Post object.
- * @return bool Whether the post can be edited in the block editor.
- */
-function use_block_editor_for_post( $post ) {
- $post = get_post( $post );
-
- if ( ! $post ) {
- return false;
- }
-
- // We're in the meta box loader, so don't use the block editor.
- if ( isset( $_GET['meta-box-loader'] ) ) {
- check_admin_referer( 'meta-box-loader', 'meta-box-loader-nonce' );
- return false;
- }
-
- $use_block_editor = use_block_editor_for_post_type( $post->post_type );
-
- /**
- * Filters whether a post is able to be edited in the block editor.
- *
- * @since 5.0.0
- *
- * @param bool $use_block_editor Whether the post can be edited or not.
- * @param WP_Post $post The post being checked.
- */
- return apply_filters( 'use_block_editor_for_post', $use_block_editor, $post );
-}
-
-/**
- * Returns whether a post type is compatible with the block editor.
- *
- * The block editor depends on the REST API, and if the post type is not shown in the
- * REST API, then it won't work with the block editor.
- *
- * @since 5.0.0
- *
- * @param string $post_type The post type.
- * @return bool Whether the post type can be edited with the block editor.
- */
-function use_block_editor_for_post_type( $post_type ) {
- if ( ! post_type_exists( $post_type ) ) {
- return false;
- }
-
- if ( ! post_type_supports( $post_type, 'editor' ) ) {
- return false;
- }
-
- $post_type_object = get_post_type_object( $post_type );
- if ( $post_type_object && ! $post_type_object->show_in_rest ) {
- return false;
- }
-
- /**
- * Filters whether a post is able to be edited in the block editor.
- *
- * @since 5.0.0
- *
- * @param bool $use_block_editor Whether the post type can be edited or not. Default true.
- * @param string $post_type The post type being checked.
- */
- return apply_filters( 'use_block_editor_for_post_type', true, $post_type );
-}
-
-/**
* Prepares server-registered blocks for the block editor.
*
* Returns an associative array of registered block data keyed by block name. Data includes properties
* of a block relevant for client registration.
*
* @since 5.0.0
+ * @since 6.3.0 Added `selectors` field.
+ * @since 6.4.0 Added `block_hooks` field.
*
* @return array An associative array of registered block data.
*/
@@ -2232,6 +2307,8 @@
'attributes' => 'attributes',
'provides_context' => 'providesContext',
'uses_context' => 'usesContext',
+ 'block_hooks' => 'blockHooks',
+ 'selectors' => 'selectors',
'supports' => 'supports',
'category' => 'category',
'styles' => 'styles',
@@ -2241,6 +2318,7 @@
'keywords' => 'keywords',
'example' => 'example',
'variations' => 'variations',
+ 'allowed_blocks' => 'allowedBlocks',
);
foreach ( $block_registry->get_all_registered() as $block_name => $block_type ) {
@@ -2264,6 +2342,10 @@
* Renders the meta boxes forms.
*
* @since 5.0.0
+ *
+ * @global WP_Post $post Global post object.
+ * @global WP_Screen $current_screen WordPress current screen object.
+ * @global array $wp_meta_boxes Global meta box state.
*/
function the_block_editor_meta_boxes() {
global $post, $current_screen, $wp_meta_boxes;
@@ -2326,7 +2408,7 @@
$meta_boxes = (array) $wp_meta_boxes[ $current_screen->id ][ $location ][ $priority ];
foreach ( $meta_boxes as $meta_box ) {
- if ( false == $meta_box || ! $meta_box['title'] ) {
+ if ( false === $meta_box || ! $meta_box['title'] ) {
continue;
}
@@ -2389,6 +2471,50 @@
wp_add_inline_script( 'wp-lists', $script );
}
+ /*
+ * Refresh nonces used by the meta box loader.
+ *
+ * The logic is very similar to that provided by post.js for the classic editor.
+ */
+ $script = "( function( $ ) {
+ var check, timeout;
+
+ function schedule() {
+ check = false;
+ window.clearTimeout( timeout );
+ timeout = window.setTimeout( function() { check = true; }, 300000 );
+ }
+
+ $( document ).on( 'heartbeat-send.wp-refresh-nonces', function( e, data ) {
+ var post_id, \$authCheck = $( '#wp-auth-check-wrap' );
+
+ if ( check || ( \$authCheck.length && ! \$authCheck.hasClass( 'hidden' ) ) ) {
+ if ( ( post_id = $( '#post_ID' ).val() ) && $( '#_wpnonce' ).val() ) {
+ data['wp-refresh-metabox-loader-nonces'] = {
+ post_id: post_id
+ };
+ }
+ }
+ }).on( 'heartbeat-tick.wp-refresh-nonces', function( e, data ) {
+ var nonces = data['wp-refresh-metabox-loader-nonces'];
+
+ if ( nonces ) {
+ if ( nonces.replace ) {
+ if ( nonces.replace.metabox_loader_nonce && window._wpMetaBoxUrl && wp.url ) {
+ window._wpMetaBoxUrl= wp.url.addQueryArgs( window._wpMetaBoxUrl, { 'meta-box-loader-nonce': nonces.replace.metabox_loader_nonce } );
+ }
+
+ if ( nonces.replace._wpnonce ) {
+ $( '#_wpnonce' ).val( nonces.replace._wpnonce );
+ }
+ }
+ }
+ }).ready( function() {
+ schedule();
+ });
+ } )( jQuery );";
+ wp_add_inline_script( 'heartbeat', $script );
+
// Reset meta box data.
$wp_meta_boxes = $_original_meta_boxes;
}
@@ -2428,7 +2554,7 @@
$classic_elements = wp_html_split( $classic_output );
$hidden_inputs = '';
foreach ( $classic_elements as $element ) {
- if ( 0 !== strpos( $element, '