: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
do_action( 'wp_creating_autosave', get_post( $revision, ARRAY_A ), false );
* 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.
* @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 ) {
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 ] );
* Saves a draft or manually autosaves for the purpose of showing a post preview.
* @return string URL to redirect to show the preview.
function post_preview() {
$post_id = (int) $_POST['post_ID'];
$post = get_post( $post_id );
wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
if ( ! current_user_can( 'edit_post', $post->ID ) ) {
wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
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();
if ( isset( $_POST['post_status'] ) && 'auto-draft' === $_POST['post_status'] ) {
$_POST['post_status'] = 'draft';
$saved_post_id = wp_create_post_autosave( $post->ID );
if ( is_wp_error( $saved_post_id ) ) {
wp_die( $saved_post_id->get_error_message() );
if ( $is_autosave && $saved_post_id ) {
$query_args['preview_id'] = $post->ID;
$query_args['preview_nonce'] = wp_create_nonce( 'post_preview_' . $post->ID );
if ( isset( $_POST['post_format'] ) ) {
$query_args['post_format'] = empty( $_POST['post_format'] ) ? 'standard' : sanitize_key( $_POST['post_format'] );
if ( isset( $_POST['_thumbnail_id'] ) ) {
$query_args['_thumbnail_id'] = ( (int) $_POST['_thumbnail_id'] <= 0 ) ? '-1' : (int) $_POST['_thumbnail_id'];
return get_preview_post_link( $post, $query_args );
* Saves a post submitted with XHR.
* Intended for use with heartbeat and autosave.js
* @param array $post_data Associative array of the submitted post data.
* @return mixed The value 0 or WP_Error on failure. The saved post ID on success.
* The ID can be the draft post_id or the autosave revision post_id.
function wp_autosave( $post_data ) {
if ( ! defined( 'DOING_AUTOSAVE' ) ) {
define( 'DOING_AUTOSAVE', true );
$post_id = (int) $post_data['post_id'];
$post_data['ID'] = $post_id;
$post_data['post_ID'] = $post_id;
if ( false === wp_verify_nonce( $post_data['_wpnonce'], 'update-post_' . $post_id ) ) {
return new WP_Error( 'invalid_nonce', __( 'Error while saving.' ) );
$post = get_post( $post_id );
if ( ! current_user_can( 'edit_post', $post->ID ) ) {
return new WP_Error( 'edit_posts', __( 'Sorry, you are not allowed to edit this item.' ) );
if ( 'auto-draft' === $post->post_status ) {
$post_data['post_status'] = 'draft';
if ( 'page' !== $post_data['post_type'] && ! empty( $post_data['catslist'] ) ) {
$post_data['post_category'] = explode( ',', $post_data['catslist'] );
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 ) );
* 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 ) );
* Redirects to previous page.
* @param int $post_id Optional. Post ID.
function redirect_post( $post_id = '' ) {
if ( isset( $_POST['save'] ) || isset( $_POST['publish'] ) ) {
$status = get_post_status( $post_id );
$message = isset( $_POST['publish'] ) ? 6 : 1;
$location = add_query_arg( 'message', $message, get_edit_post_link( $post_id, 'url' ) );
} elseif ( isset( $_POST['addmeta'] ) && $_POST['addmeta'] ) {
$location = add_query_arg( 'message', 2, wp_get_referer() );
$location = explode( '#', $location );
$location = $location[0] . '#postcustom';
} elseif ( isset( $_POST['deletemeta'] ) && $_POST['deletemeta'] ) {
$location = add_query_arg( 'message', 3, wp_get_referer() );
$location = explode( '#', $location );
$location = $location[0] . '#postcustom';
$location = add_query_arg( 'message', 4, get_edit_post_link( $post_id, 'url' ) );
* Filters the post redirect destination URL.
* @param string $location The destination URL.
* @param int $post_id The post ID.
wp_redirect( apply_filters( 'redirect_post_location', $location, $post_id ) );
* Sanitizes POST values from a checkbox taxonomy metabox.
* @param string $taxonomy The taxonomy name.
* @param array $terms Raw term data from the 'tax_input' field.
* @return int[] Array of sanitized term IDs.
function taxonomy_meta_box_sanitize_cb_checkboxes( $taxonomy, $terms ) {
return array_map( 'intval', $terms );
* Sanitizes POST values from an input taxonomy metabox.
* @param string $taxonomy The taxonomy name.
* @param array|string $terms Raw term data from the 'tax_input' field.
function taxonomy_meta_box_sanitize_cb_input( $taxonomy, $terms ) {
* Assume that a 'tax_input' string is a comma-separated list of term names.
* Some languages may use a character other than a comma as a delimiter, so we standardize on
* commas before parsing the list.
if ( ! is_array( $terms ) ) {
$comma = _x( ',', 'tag delimiter' );
$terms = str_replace( $comma, ',', $terms );
$terms = explode( ',', trim( $terms, " \n\t\r\0\x0B," ) );
foreach ( $terms as $term ) {
// Empty terms are invalid input.
if ( ! empty( $_term ) ) {
$clean_terms[] = (int) $_term[0];
// No existing term was found, so pass the string. A new term will be created.
* 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 6.3.0 Added `selectors` field.
* @since 6.4.0 Added `block_hooks` field.
* @return array An associative array of registered block data.
function get_block_editor_server_block_settings() {
$block_registry = WP_Block_Type_Registry::get_instance();
'api_version' => 'apiVersion',
'description' => 'description',
'attributes' => 'attributes',
'provides_context' => 'providesContext',
'uses_context' => 'usesContext',
'block_hooks' => 'blockHooks',
'selectors' => 'selectors',
'supports' => 'supports',
'category' => 'category',
'textdomain' => 'textdomain',
'ancestor' => 'ancestor',
'keywords' => 'keywords',
'variations' => 'variations',
'allowed_blocks' => 'allowedBlocks',
foreach ( $block_registry->get_all_registered() as $block_name => $block_type ) {
foreach ( $fields_to_pick as $field => $key ) {
if ( ! isset( $block_type->{ $field } ) ) {
if ( ! isset( $blocks[ $block_name ] ) ) {
$blocks[ $block_name ] = array();
$blocks[ $block_name ][ $key ] = $block_type->{ $field };
* Renders the meta boxes forms.
* @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;
// Handle meta box state.
$_original_meta_boxes = $wp_meta_boxes;
* Fires right before the meta boxes are rendered.
* This allows for the filtering of meta box data, that should already be
* present by this point. Do not use as a means of adding meta box data.
* @param array $wp_meta_boxes Global meta box state.
$wp_meta_boxes = apply_filters( 'filter_block_editor_meta_boxes', $wp_meta_boxes );
$locations = array( 'side', 'normal', 'advanced' );
$priorities = array( 'high', 'sorted', 'core', 'default', 'low' );
<form class="metabox-base-form">
<?php the_block_editor_meta_box_post_form_hidden_fields( $post ); ?>
<form id="toggle-custom-fields-form" method="post" action="<?php echo esc_url( admin_url( 'post.php' ) ); ?>">
<?php wp_nonce_field( 'toggle-custom-fields', 'toggle-custom-fields-nonce' ); ?>
<input type="hidden" name="action" value="toggle-custom-fields" />
<?php foreach ( $locations as $location ) : ?>
<form class="metabox-location-<?php echo esc_attr( $location ); ?>" onsubmit="return false;">
<div id="poststuff" class="sidebar-open">
<div id="postbox-container-2" class="postbox-container">
$meta_boxes_per_location = array();
foreach ( $locations as $location ) {
$meta_boxes_per_location[ $location ] = array();
if ( ! isset( $wp_meta_boxes[ $current_screen->id ][ $location ] ) ) {
foreach ( $priorities as $priority ) {
if ( ! isset( $wp_meta_boxes[ $current_screen->id ][ $location ][ $priority ] ) ) {
$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 a meta box is just here for back compat, don't show it in the block editor.
if ( isset( $meta_box['args']['__back_compat_meta_box'] ) && $meta_box['args']['__back_compat_meta_box'] ) {
$meta_boxes_per_location[ $location ][] = array(
'title' => $meta_box['title'],
* Sadly we probably cannot add this data directly into editor settings.
* Some meta boxes need `admin_head` to fire for meta box registry.
* `admin_head` fires after `admin_enqueue_scripts`, which is where we create
$script = 'window._wpLoadBlockEditor.then( function() {
wp.data.dispatch( \'core/edit-post\' ).setAvailableMetaBoxesPerLocation( ' . wp_json_encode( $meta_boxes_per_location ) . ' );
wp_add_inline_script( 'wp-edit-post', $script );
* When `wp-edit-post` is output in the `<head>`, the inline script needs to be manually printed.
* Otherwise, meta boxes will not display because inline scripts for `wp-edit-post`
* will not be printed again after this point.
if ( wp_script_is( 'wp-edit-post', 'done' ) ) {
printf( "<script type='text/javascript'>\n%s\n</script>\n", trim( $script ) );
* If the 'postcustom' meta box is enabled, then we need to perform
* some extra initialization on it.
$enable_custom_fields = (bool) get_user_meta( get_current_user_id(), 'enable_custom_fields', true );
if ( $enable_custom_fields ) {
$script = "( function( $ ) {
if ( $('#postcustom').length ) {
$( '#the-list' ).wpList( {
addBefore: function( s ) {
s.data += '&post_id=$post->ID';
$('table#list-table').show();
wp_enqueue_script( 'wp-lists' );
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( $ ) {
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'] = {
}).on( 'heartbeat-tick.wp-refresh-nonces', function( e, data ) {
var nonces = data['wp-refresh-metabox-loader-nonces'];