: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Adds a suffix if any trashed posts have a given slug.
* Store its desired (i.e. current) slug so it can try to reclaim it
* if the post is untrashed.
* @param string $post_name Post slug.
* @param int $post_id Optional. Post ID that should be ignored. Default 0.
function wp_add_trashed_suffix_to_post_name_for_trashed_posts( $post_name, $post_id = 0 ) {
$trashed_posts_with_desired_slug = get_posts(
'post_status' => 'trash',
'post__not_in' => array( $post_id ),
if ( ! empty( $trashed_posts_with_desired_slug ) ) {
foreach ( $trashed_posts_with_desired_slug as $_post ) {
wp_add_trashed_suffix_to_post_name_for_post( $_post );
* Adds a trashed suffix for a given post.
* Store its desired (i.e. current) slug so it can try to reclaim it
* if the post is untrashed.
* @global wpdb $wpdb WordPress database abstraction object.
* @param WP_Post $post The post.
* @return string New slug for the post.
function wp_add_trashed_suffix_to_post_name_for_post( $post ) {
$post = get_post( $post );
if ( str_ends_with( $post->post_name, '__trashed' ) ) {
add_post_meta( $post->ID, '_wp_desired_post_slug', $post->post_name );
$post_name = _truncate_post_slug( $post->post_name, 191 ) . '__trashed';
$wpdb->update( $wpdb->posts, array( 'post_name' => $post_name ), array( 'ID' => $post->ID ) );
clean_post_cache( $post->ID );
* Sets the last changed time for the 'posts' cache group.
function wp_cache_set_posts_last_changed() {
wp_cache_set_last_changed( 'posts' );
* Gets all available post MIME types for a given post type.
* @global wpdb $wpdb WordPress database abstraction object.
* @return string[] An array of MIME types.
function get_available_post_mime_types( $type = 'attachment' ) {
* Filters the list of available post MIME types for the given post type.
* @param string[]|null $mime_types An array of MIME types. Default null.
* @param string $type The post type name. Usually 'attachment' but can be any post type.
$mime_types = apply_filters( 'pre_get_available_post_mime_types', null, $type );
if ( ! is_array( $mime_types ) ) {
$mime_types = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT post_mime_type FROM $wpdb->posts WHERE post_type = %s AND post_mime_type != ''", $type ) );
// Remove nulls from returned $mime_types.
return array_values( array_filter( $mime_types ) );
* Retrieves the path to an uploaded image file.
* Similar to `get_attached_file()` however some images may have been processed after uploading
* to make them suitable for web use. In this case the attached "full" size file is usually replaced
* with a scaled down version of the original image. This function always returns the path
* to the originally uploaded image file.
* @since 5.4.0 Added the `$unfiltered` parameter.
* @param int $attachment_id Attachment ID.
* @param bool $unfiltered Optional. Passed through to `get_attached_file()`. Default false.
* @return string|false Path to the original image file or false if the attachment is not an image.
function wp_get_original_image_path( $attachment_id, $unfiltered = false ) {
if ( ! wp_attachment_is_image( $attachment_id ) ) {
$image_meta = wp_get_attachment_metadata( $attachment_id );
$image_file = get_attached_file( $attachment_id, $unfiltered );
if ( empty( $image_meta['original_image'] ) ) {
$original_image = $image_file;
$original_image = path_join( dirname( $image_file ), $image_meta['original_image'] );
* Filters the path to the original image.
* @param string $original_image Path to original image file.
* @param int $attachment_id Attachment ID.
return apply_filters( 'wp_get_original_image_path', $original_image, $attachment_id );
* Retrieves the URL to an original attachment image.
* Similar to `wp_get_attachment_url()` however some images may have been
* processed after uploading. In this case this function returns the URL
* to the originally uploaded image file.
* @param int $attachment_id Attachment post ID.
* @return string|false Attachment image URL, false on error or if the attachment is not an image.
function wp_get_original_image_url( $attachment_id ) {
if ( ! wp_attachment_is_image( $attachment_id ) ) {
$image_url = wp_get_attachment_url( $attachment_id );
$image_meta = wp_get_attachment_metadata( $attachment_id );
if ( empty( $image_meta['original_image'] ) ) {
$original_image_url = $image_url;
$original_image_url = path_join( dirname( $image_url ), $image_meta['original_image'] );
* Filters the URL to the original attachment image.
* @param string $original_image_url URL to original image.
* @param int $attachment_id Attachment ID.
return apply_filters( 'wp_get_original_image_url', $original_image_url, $attachment_id );
* Filters callback which sets the status of an untrashed post to its previous status.
* This can be used as a callback on the `wp_untrash_post_status` filter.
* @param string $new_status The new status of the post being restored.
* @param int $post_id The ID of the post being restored.
* @param string $previous_status The status of the post at the point where it was trashed.
* @return string The new status of the post.
function wp_untrash_post_set_previous_status( $new_status, $post_id, $previous_status ) {
* Returns whether the post can be edited in the block editor.
* @since 6.1.0 Moved to wp-includes from wp-admin.
* @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 );
// We're in the meta box loader, so don't use the block editor.
if ( is_admin() && isset( $_GET['meta-box-loader'] ) ) {
check_admin_referer( 'meta-box-loader', 'meta-box-loader-nonce' );
$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.
* @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 6.1.0 Moved to wp-includes from wp-admin.
* @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 ) ) {
if ( ! post_type_supports( $post_type, 'editor' ) ) {
$post_type_object = get_post_type_object( $post_type );
if ( $post_type_object && ! $post_type_object->show_in_rest ) {
* Filters whether a post is able to be edited in the block editor.
* @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 );
* Registers any additional post meta fields.
* @since 6.3.0 Adds `wp_pattern_sync_status` meta field to the wp_block post type so an unsynced option can be added.
* @link https://github.com/WordPress/gutenberg/pull/51144
function wp_create_initial_post_meta() {
'wp_pattern_sync_status',
'sanitize_callback' => 'sanitize_text_field',
'enum' => array( 'partial', 'unsynced' ),