--- a/wp/wp-includes/post.php Fri Sep 05 18:40:08 2025 +0200
+++ b/wp/wp-includes/post.php Fri Sep 05 18:52:52 2025 +0200
@@ -75,7 +75,7 @@
'labels' => array(
'name' => _x( 'Media', 'post type general name' ),
'name_admin_bar' => _x( 'Media', 'add new from admin bar' ),
- 'add_new' => __( 'Add New Media File' ),
+ 'add_new' => __( 'Add Media File' ),
'edit_item' => __( 'Edit Media' ),
'view_item' => ( '1' === get_option( 'wp_attachment_pages_enabled' ) ) ? __( 'View Attachment Page' ) : __( 'View Media File' ),
'attributes' => __( 'Attachment Attributes' ),
@@ -202,8 +202,8 @@
'labels' => array(
'name' => _x( 'Changesets', 'post type general name' ),
'singular_name' => _x( 'Changeset', 'post type singular name' ),
- 'add_new' => __( 'Add New Changeset' ),
- 'add_new_item' => __( 'Add New Changeset' ),
+ 'add_new' => __( 'Add Changeset' ),
+ 'add_new_item' => __( 'Add Changeset' ),
'new_item' => __( 'New Changeset' ),
'edit_item' => __( 'Edit Changeset' ),
'view_item' => __( 'View Changeset' ),
@@ -284,8 +284,8 @@
'labels' => array(
'name' => _x( 'Patterns', 'post type general name' ),
'singular_name' => _x( 'Pattern', 'post type singular name' ),
- 'add_new' => __( 'Add New Pattern' ),
- 'add_new_item' => __( 'Add New Pattern' ),
+ 'add_new' => __( 'Add Pattern' ),
+ 'add_new_item' => __( 'Add Pattern' ),
'new_item' => __( 'New Pattern' ),
'edit_item' => __( 'Edit Block Pattern' ),
'view_item' => __( 'View Pattern' ),
@@ -350,8 +350,8 @@
'labels' => array(
'name' => _x( 'Templates', 'post type general name' ),
'singular_name' => _x( 'Template', 'post type singular name' ),
- 'add_new' => __( 'Add New Template' ),
- 'add_new_item' => __( 'Add New Template' ),
+ 'add_new' => __( 'Add Template' ),
+ 'add_new_item' => __( 'Add Template' ),
'new_item' => __( 'New Template' ),
'edit_item' => __( 'Edit Template' ),
'view_item' => __( 'View Template' ),
@@ -415,8 +415,8 @@
'labels' => array(
'name' => _x( 'Template Parts', 'post type general name' ),
'singular_name' => _x( 'Template Part', 'post type singular name' ),
- 'add_new' => __( 'Add New Template Part' ),
- 'add_new_item' => __( 'Add New Template Part' ),
+ 'add_new' => __( 'Add Template Part' ),
+ 'add_new_item' => __( 'Add Template Part' ),
'new_item' => __( 'New Template Part' ),
'edit_item' => __( 'Edit Template Part' ),
'view_item' => __( 'View Template Part' ),
@@ -489,7 +489,7 @@
'revisions_rest_controller_class' => 'WP_REST_Global_Styles_Revisions_Controller',
'late_route_registration' => true,
'capabilities' => array(
- 'read' => 'edit_theme_options',
+ 'read' => 'edit_posts',
'create_posts' => 'edit_theme_options',
'edit_posts' => 'edit_theme_options',
'edit_published_posts' => 'edit_theme_options',
@@ -522,8 +522,8 @@
'labels' => array(
'name' => _x( 'Navigation Menus', 'post type general name' ),
'singular_name' => _x( 'Navigation Menu', 'post type singular name' ),
- 'add_new' => __( 'Add New Navigation Menu' ),
- 'add_new_item' => __( 'Add New Navigation Menu' ),
+ 'add_new' => __( 'Add Navigation Menu' ),
+ 'add_new_item' => __( 'Add Navigation Menu' ),
'new_item' => __( 'New Navigation Menu' ),
'edit_item' => __( 'Edit Navigation Menu' ),
'view_item' => __( 'View Navigation Menu' ),
@@ -852,13 +852,15 @@
* Updates attachment file path based on attachment ID.
*
* Used to update the file path of the attachment, which uses post meta name
- * '_wp_attached_file' to store the path of the attachment.
+ * `_wp_attached_file` to store the path of the attachment.
*
* @since 2.1.0
*
* @param int $attachment_id Attachment ID.
* @param string $file File path for the attachment.
- * @return bool True on success, false on failure.
+ * @return int|bool Meta ID if the `_wp_attached_file` key didn't exist for the attachment.
+ * True on successful update, false on failure or if the `$file` value passed
+ * to the function is the same as the one that is already in the database.
*/
function update_attached_file( $attachment_id, $file ) {
if ( ! get_post( $attachment_id ) ) {
@@ -1135,7 +1137,7 @@
function get_post_ancestors( $post ) {
$post = get_post( $post );
- if ( ! $post || empty( $post->post_parent ) || $post->post_parent == $post->ID ) {
+ if ( ! $post || empty( $post->post_parent ) || $post->post_parent === $post->ID ) {
return array();
}
@@ -1146,7 +1148,9 @@
while ( $ancestor = get_post( $id ) ) {
// Loop detection: If the ancestor has been seen before, break.
- if ( empty( $ancestor->post_parent ) || ( $ancestor->post_parent == $post->ID ) || in_array( $ancestor->post_parent, $ancestors, true ) ) {
+ if ( empty( $ancestor->post_parent ) || $ancestor->post_parent === $post->ID
+ || in_array( $ancestor->post_parent, $ancestors, true )
+ ) {
break;
}
@@ -2022,8 +2026,8 @@
* - `name` - General name for the post type, usually plural. The same and overridden
* by `$post_type_object->label`. Default is 'Posts' / 'Pages'.
* - `singular_name` - Name for one object of this post type. Default is 'Post' / 'Page'.
- * - `add_new` - Label for adding a new item. Default is 'Add New Post' / 'Add New Page'.
- * - `add_new_item` - Label for adding a new singular item. Default is 'Add New Post' / 'Add New Page'.
+ * - `add_new` - Label for adding a new item. Default is 'Add Post' / 'Add Page'.
+ * - `add_new_item` - Label for adding a new singular item. Default is 'Add Post' / 'Add Page'.
* - `edit_item` - Label for editing a singular item. Default is 'Edit Post' / 'Edit Page'.
* - `new_item` - Label for the new item page title. Default is 'New Post' / 'New Page'.
* - `view_item` - Label for viewing a singular item. Default is 'View Post' / 'View Page'.
@@ -2084,6 +2088,8 @@
* @since 6.4.0 Changed default values for the `add_new` label to include the type of content.
* This matches `add_new_item` and provides more context for better accessibility.
* @since 6.6.0 Added the `template_name` label.
+ * @since 6.7.0 Restored pre-6.4.0 defaults for the `add_new` label and updated documentation.
+ * Updated core usage to reference `add_new_item`.
*
* @access private
*
@@ -2470,6 +2476,40 @@
}
/**
+ * Determines whether a post is embeddable.
+ *
+ * @since 6.8.0
+ *
+ * @param int|WP_Post|null $post Optional. Post ID or `WP_Post` object. Defaults to global $post.
+ * @return bool Whether the post should be considered embeddable.
+ */
+function is_post_embeddable( $post = null ) {
+ $post = get_post( $post );
+
+ if ( ! $post ) {
+ return false;
+ }
+
+ $post_type = get_post_type_object( $post->post_type );
+
+ if ( ! $post_type ) {
+ return false;
+ }
+
+ $is_embeddable = $post_type->embeddable;
+
+ /**
+ * Filter whether a post is embeddable.
+ *
+ * @since 6.8.0
+ *
+ * @param bool $is_embeddable Whether the post is embeddable.
+ * @param WP_Post $post Post object.
+ */
+ return apply_filters( 'is_post_embeddable', $is_embeddable, $post );
+}
+
+/**
* Retrieves an array of the latest posts, or posts matching the given criteria.
*
* For more information on the accepted arguments, see the
@@ -2552,7 +2592,13 @@
*
* @param int $post_id Post ID.
* @param string $meta_key Metadata name.
- * @param mixed $meta_value Metadata value. Must be serializable if non-scalar.
+ * @param mixed $meta_value Metadata value. Arrays and objects are stored as serialized data and
+ * will be returned as the same type when retrieved. Other data types will
+ * be stored as strings in the database:
+ * - false is stored and retrieved as an empty string ('')
+ * - true is stored and retrieved as '1'
+ * - numbers (both integer and float) are stored and retrieved as strings
+ * Must be serializable if non-scalar.
* @param bool $unique Optional. Whether the same key should not be added.
* Default false.
* @return int|false Meta ID on success, false on failure.
@@ -2607,7 +2653,13 @@
* @return mixed An array of values if `$single` is false.
* The value of the meta field if `$single` is true.
* False for an invalid `$post_id` (non-numeric, zero, or negative value).
- * An empty string if a valid but non-existing post ID is passed.
+ * An empty array if a valid but non-existing post ID is passed and `$single` is false.
+ * An empty string if a valid but non-existing post ID is passed and `$single` is true.
+ * Note: Non-serialized values are returned as strings:
+ * - false values are returned as empty strings ('')
+ * - true values are returned as '1'
+ * - numbers (both integer and float) are returned as strings
+ * Arrays and objects retain their original type.
*/
function get_post_meta( $post_id, $key = '', $single = false ) {
return get_metadata( 'post', $post_id, $key, $single );
@@ -2820,7 +2872,7 @@
function sanitize_post( $post, $context = 'display' ) {
if ( is_object( $post ) ) {
// Check if post already filtered for this context.
- if ( isset( $post->filter ) && $context == $post->filter ) {
+ if ( isset( $post->filter ) && $context === $post->filter ) {
return $post;
}
if ( ! isset( $post->ID ) ) {
@@ -2832,7 +2884,7 @@
$post->filter = $context;
} elseif ( is_array( $post ) ) {
// Check if post already filtered for this context.
- if ( isset( $post['filter'] ) && $context == $post['filter'] ) {
+ if ( isset( $post['filter'] ) && $context === $post['filter'] ) {
return $post;
}
if ( ! isset( $post['ID'] ) ) {
@@ -2895,7 +2947,23 @@
* Filters the value of a specific post field to edit.
*
* The dynamic portion of the hook name, `$field`, refers to the post
- * field name.
+ * field name. Possible filter names include:
+ *
+ * - `edit_post_author`
+ * - `edit_post_date`
+ * - `edit_post_date_gmt`
+ * - `edit_post_content`
+ * - `edit_post_title`
+ * - `edit_post_excerpt`
+ * - `edit_post_status`
+ * - `edit_post_password`
+ * - `edit_post_name`
+ * - `edit_post_modified`
+ * - `edit_post_modified_gmt`
+ * - `edit_post_content_filtered`
+ * - `edit_post_parent`
+ * - `edit_post_type`
+ * - `edit_post_mime_type`
*
* @since 2.3.0
*
@@ -2907,8 +2975,26 @@
/**
* Filters the value of a specific post field to edit.
*
- * The dynamic portion of the hook name, `$field_no_prefix`, refers to
- * the post field name.
+ * Only applied to post fields with a name which is prefixed with `post_`.
+ *
+ * The dynamic portion of the hook name, `$field_no_prefix`, refers to the
+ * post field name minus the `post_` prefix. Possible filter names include:
+ *
+ * - `author_edit_pre`
+ * - `date_edit_pre`
+ * - `date_gmt_edit_pre`
+ * - `content_edit_pre`
+ * - `title_edit_pre`
+ * - `excerpt_edit_pre`
+ * - `status_edit_pre`
+ * - `password_edit_pre`
+ * - `name_edit_pre`
+ * - `modified_edit_pre`
+ * - `modified_gmt_edit_pre`
+ * - `content_filtered_edit_pre`
+ * - `parent_edit_pre`
+ * - `type_edit_pre`
+ * - `mime_type_edit_pre`
*
* @since 2.3.0
*
@@ -2917,6 +3003,28 @@
*/
$value = apply_filters( "{$field_no_prefix}_edit_pre", $value, $post_id );
} else {
+ /**
+ * Filters the value of a specific post field to edit.
+ *
+ * Only applied to post fields not prefixed with `post_`.
+ *
+ * The dynamic portion of the hook name, `$field`, refers to the
+ * post field name. Possible filter names include:
+ *
+ * - `edit_post_ID`
+ * - `edit_post_ping_status`
+ * - `edit_post_pinged`
+ * - `edit_post_to_ping`
+ * - `edit_post_comment_count`
+ * - `edit_post_comment_status`
+ * - `edit_post_guid`
+ * - `edit_post_menu_order`
+ *
+ * @since 2.3.0
+ *
+ * @param mixed $value Value of the post field.
+ * @param int $post_id Post ID.
+ */
$value = apply_filters( "edit_post_{$field}", $value, $post_id );
}
@@ -2935,8 +3043,26 @@
/**
* Filters the value of a specific post field before saving.
*
+ * Only applied to post fields with a name which is prefixed with `post_`.
+ *
* The dynamic portion of the hook name, `$field`, refers to the post
- * field name.
+ * field name. Possible filter names include:
+ *
+ * - `pre_post_author`
+ * - `pre_post_date`
+ * - `pre_post_date_gmt`
+ * - `pre_post_content`
+ * - `pre_post_title`
+ * - `pre_post_excerpt`
+ * - `pre_post_status`
+ * - `pre_post_password`
+ * - `pre_post_name`
+ * - `pre_post_modified`
+ * - `pre_post_modified_gmt`
+ * - `pre_post_content_filtered`
+ * - `pre_post_parent`
+ * - `pre_post_type`
+ * - `pre_post_mime_type`
*
* @since 2.3.0
*
@@ -2947,8 +3073,26 @@
/**
* Filters the value of a specific field before saving.
*
- * The dynamic portion of the hook name, `$field_no_prefix`, refers
- * to the post field name.
+ * Only applied to post fields with a name which is prefixed with `post_`.
+ *
+ * The dynamic portion of the hook name, `$field_no_prefix`, refers to the
+ * post field name minus the `post_` prefix. Possible filter names include:
+ *
+ * - `author_save_pre`
+ * - `date_save_pre`
+ * - `date_gmt_save_pre`
+ * - `content_save_pre`
+ * - `title_save_pre`
+ * - `excerpt_save_pre`
+ * - `status_save_pre`
+ * - `password_save_pre`
+ * - `name_save_pre`
+ * - `modified_save_pre`
+ * - `modified_gmt_save_pre`
+ * - `content_filtered_save_pre`
+ * - `parent_save_pre`
+ * - `type_save_pre`
+ * - `mime_type_save_pre`
*
* @since 2.3.0
*
@@ -2956,13 +3100,45 @@
*/
$value = apply_filters( "{$field_no_prefix}_save_pre", $value );
} else {
+ /**
+ * Filters the value of a specific field before saving.
+ *
+ * Only applied to post fields with a name which is prefixed with `post_`.
+ *
+ * The dynamic portion of the hook name, `$field_no_prefix`, refers to the
+ * post field name minus the `post_` prefix. Possible filter names include:
+ *
+ * - `pre_post_ID`
+ * - `pre_post_comment_status`
+ * - `pre_post_ping_status`
+ * - `pre_post_to_ping`
+ * - `pre_post_pinged`
+ * - `pre_post_guid`
+ * - `pre_post_menu_order`
+ * - `pre_post_comment_count`
+ *
+ * @since 2.3.0
+ *
+ * @param mixed $value Value of the post field.
+ */
$value = apply_filters( "pre_post_{$field}", $value );
/**
* Filters the value of a specific post field before saving.
*
+ * Only applied to post fields with a name which is *not* prefixed with `post_`.
+ *
* The dynamic portion of the hook name, `$field`, refers to the post
- * field name.
+ * field name. Possible filter names include:
+ *
+ * - `ID_pre`
+ * - `comment_status_pre`
+ * - `ping_status_pre`
+ * - `to_ping_pre`
+ * - `pinged_pre`
+ * - `guid_pre`
+ * - `menu_order_pre`
+ * - `comment_count_pre`
*
* @since 2.3.0
*
@@ -2978,8 +3154,26 @@
/**
* Filters the value of a specific post field for display.
*
+ * Only applied to post fields with a name which is prefixed with `post_`.
+ *
* The dynamic portion of the hook name, `$field`, refers to the post
- * field name.
+ * field name. Possible filter names include:
+ *
+ * - `post_author`
+ * - `post_date`
+ * - `post_date_gmt`
+ * - `post_content`
+ * - `post_title`
+ * - `post_excerpt`
+ * - `post_status`
+ * - `post_password`
+ * - `post_name`
+ * - `post_modified`
+ * - `post_modified_gmt`
+ * - `post_content_filtered`
+ * - `post_parent`
+ * - `post_type`
+ * - `post_mime_type`
*
* @since 2.3.0
*
@@ -2991,6 +3185,31 @@
*/
$value = apply_filters( "{$field}", $value, $post_id, $context );
} else {
+ /**
+ * Filters the value of a specific post field for display.
+ *
+ * Only applied to post fields name which is *not* prefixed with `post_`.
+ *
+ * The dynamic portion of the hook name, `$field`, refers to the post
+ * field name. Possible filter names include:
+ *
+ * - `post_ID`
+ * - `post_comment_status`
+ * - `post_ping_status`
+ * - `post_to_ping`
+ * - `post_pinged`
+ * - `post_guid`
+ * - `post_menu_order`
+ * - `post_comment_count`
+ *
+ * @since 2.3.0
+ *
+ * @param mixed $value Value of the unprefixed post field.
+ * @param int $post_id Post ID
+ * @param string $context Context for how to sanitize the field.
+ * Accepts 'raw', 'edit', 'db', 'display',
+ * 'attribute', or 'js'. Default 'display'.
+ */
$value = apply_filters( "post_{$field}", $value, $post_id, $context );
}
@@ -3005,7 +3224,6 @@
if ( in_array( $field, $int_fields, true ) ) {
$value = (int) $value;
}
-
return $value;
}
@@ -3219,7 +3437,8 @@
);
$counts = wp_cache_get( $cache_key, 'counts' );
- if ( false == $counts ) {
+
+ if ( false === $counts ) {
$and = wp_post_mime_type_where( $mime_type );
$count = $wpdb->get_results( "SELECT post_mime_type, COUNT( * ) AS num_posts FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' $and GROUP BY post_mime_type", ARRAY_A );
@@ -3687,11 +3906,11 @@
* If the page is defined in option page_on_front or post_for_posts,
* adjust the corresponding options.
*/
- if ( get_option( 'page_on_front' ) == $post->ID ) {
+ if ( (int) get_option( 'page_on_front' ) === $post->ID ) {
update_option( 'show_on_front', 'posts' );
update_option( 'page_on_front', 0 );
}
- if ( get_option( 'page_for_posts' ) == $post->ID ) {
+ if ( (int) get_option( 'page_for_posts' ) === $post->ID ) {
update_option( 'page_for_posts', 0 );
}
}
@@ -5889,9 +6108,9 @@
$revparts = array_reverse( $parts );
- $foundid = 0;
+ $found_id = 0;
foreach ( (array) $pages as $page ) {
- if ( $page->post_name == $revparts[0] ) {
+ if ( $page->post_name === $revparts[0] ) {
$count = 0;
$p = $page;
@@ -5899,18 +6118,21 @@
* Loop through the given path parts from right to left,
* ensuring each matches the post ancestry.
*/
- while ( 0 != $p->post_parent && isset( $pages[ $p->post_parent ] ) ) {
+ while ( 0 !== (int) $p->post_parent && isset( $pages[ $p->post_parent ] ) ) {
++$count;
$parent = $pages[ $p->post_parent ];
- if ( ! isset( $revparts[ $count ] ) || $parent->post_name != $revparts[ $count ] ) {
+ if ( ! isset( $revparts[ $count ] ) || $parent->post_name !== $revparts[ $count ] ) {
break;
}
$p = $parent;
}
- if ( 0 == $p->post_parent && count( $revparts ) === $count + 1 && $p->post_name == $revparts[ $count ] ) {
- $foundid = $page->ID;
- if ( $page->post_type == $post_type ) {
+ if ( 0 === (int) $p->post_parent
+ && count( $revparts ) === $count + 1
+ && $p->post_name === $revparts[ $count ]
+ ) {
+ $found_id = $page->ID;
+ if ( $page->post_type === $post_type ) {
break;
}
}
@@ -5918,10 +6140,10 @@
}
// We cache misses as well as hits.
- wp_cache_set( $cache_key, $foundid, 'post-queries' );
-
- if ( $foundid ) {
- return get_post( $foundid, $output );
+ wp_cache_set( $cache_key, $found_id, 'post-queries' );
+
+ if ( $found_id ) {
+ return get_post( $found_id, $output );
}
return null;
@@ -6182,7 +6404,7 @@
$query_args['author__in'] = array();
foreach ( $post_authors as $post_author ) {
// Do we have an author id or an author login?
- if ( 0 == (int) $post_author ) {
+ if ( 0 === (int) $post_author ) {
$post_author = get_user_by( 'login', $post_author );
if ( empty( $post_author ) ) {
continue;
@@ -6829,7 +7051,7 @@
switch ( $type ) {
case 'image':
- $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp', 'avif' );
+ $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp', 'avif', 'heic' );
return in_array( $ext, $image_exts, true );
case 'audio':
@@ -7035,12 +7257,14 @@
*/
function wp_check_for_changed_slugs( $post_id, $post, $post_before ) {
// Don't bother if it hasn't changed.
- if ( $post->post_name == $post_before->post_name ) {
+ if ( $post->post_name === $post_before->post_name ) {
return;
}
// We're only concerned with published, non-hierarchical objects.
- if ( ! ( 'publish' === $post->post_status || ( 'attachment' === get_post_type( $post ) && 'inherit' === $post->post_status ) ) || is_post_type_hierarchical( $post->post_type ) ) {
+ if ( ! ( 'publish' === $post->post_status || ( 'attachment' === $post->post_type && 'inherit' === $post->post_status ) )
+ || is_post_type_hierarchical( $post->post_type )
+ ) {
return;
}
@@ -7081,12 +7305,14 @@
$new_date = gmdate( 'Y-m-d', strtotime( $post->post_date ) );
// Don't bother if it hasn't changed.
- if ( $new_date == $previous_date ) {
+ if ( $new_date === $previous_date ) {
return;
}
// We're only concerned with published, non-hierarchical objects.
- if ( ! ( 'publish' === $post->post_status || ( 'attachment' === get_post_type( $post ) && 'inherit' === $post->post_status ) ) || is_post_type_hierarchical( $post->post_type ) ) {
+ if ( ! ( 'publish' === $post->post_status || ( 'attachment' === $post->post_type && 'inherit' === $post->post_status ) )
+ || is_post_type_hierarchical( $post->post_type )
+ ) {
return;
}
@@ -7182,7 +7408,7 @@
$id = get_current_user_id();
if ( null === $post_author || ! $full ) {
$post_status_sql .= " OR post_status = 'private' AND post_author = $id";
- } elseif ( $id == (int) $post_author ) {
+ } elseif ( $id === (int) $post_author ) {
$post_status_sql .= " OR post_status = 'private'";
} // Else none.
} // Else none.
@@ -7758,7 +7984,7 @@
}
// Can't be its own parent.
- if ( $post_parent == $post_id ) {
+ if ( $post_parent === $post_id ) {
return 0;
}
@@ -7793,7 +8019,10 @@
*
* @param int|WP_Post $post Post ID or post object where thumbnail should be attached.
* @param int $thumbnail_id Thumbnail to attach.
- * @return int|bool True on success, false on failure.
+ * @return int|bool Post meta ID if the key didn't exist (ie. this is the first time that
+ * a thumbnail has been saved for the post), true on successful update,
+ * false on failure or if the value passed is the same as the one that
+ * is already in the database.
*/
function set_post_thumbnail( $post, $thumbnail_id ) {
$post = get_post( $post );