diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php index a36fe791d4..9c53441bf6 100644 --- a/src/wp-includes/theme.php +++ b/src/wp-includes/theme.php @@ -2549,7 +2549,7 @@ function _wp_customize_include() { * @param WP_Post $changeset_post Changeset post object. */ function _wp_customize_publish_changeset( $new_status, $old_status, $changeset_post ) { - global $wp_customize; + global $wp_customize, $wpdb; $is_publishing_changeset = ( 'customize_changeset' === $changeset_post->post_type @@ -2600,7 +2600,47 @@ function _wp_customize_publish_changeset( $new_status, $old_status, $changeset_p * and thus garbage collected. */ if ( ! wp_revisions_enabled( $changeset_post ) ) { - wp_trash_post( $changeset_post->ID ); + $post = $changeset_post; + $post_id = $changeset_post->ID; + + /* + * The following re-formulates the logic from wp_trash_post() as done in + * wp_publish_post(). The reason for bypassing wp_trash_post() is that it + * will mutate the the post_content and the post_name when they should be + * untouched. + */ + if ( ! EMPTY_TRASH_DAYS ) { + wp_delete_post( $post_id, true ); + } else { + /** This action is documented in wp-includes/post.php */ + do_action( 'wp_trash_post', $post_id ); + + add_post_meta( $post_id, '_wp_trash_meta_status', $post->post_status ); + add_post_meta( $post_id, '_wp_trash_meta_time', time() ); + + $old_status = $post->post_status; + $new_status = 'trash'; + $wpdb->update( $wpdb->posts, array( 'post_status' => $new_status ), array( 'ID' => $post->ID ) ); + clean_post_cache( $post->ID ); + + $post->post_status = $new_status; + wp_transition_post_status( $new_status, $old_status, $post ); + + /** This action is documented in wp-includes/post.php */ + do_action( 'edit_post', $post->ID, $post ); + + /** This action is documented in wp-includes/post.php */ + do_action( "save_post_{$post->post_type}", $post->ID, $post, true ); + + /** This action is documented in wp-includes/post.php */ + do_action( 'save_post', $post->ID, $post, true ); + + /** This action is documented in wp-includes/post.php */ + do_action( 'wp_insert_post', $post->ID, $post, true ); + + /** This action is documented in wp-includes/post.php */ + do_action( 'trashed_post', $post_id ); + } } } diff --git a/tests/phpunit/tests/customize/manager.php b/tests/phpunit/tests/customize/manager.php index a28d83400b..3ace533ad6 100644 --- a/tests/phpunit/tests/customize/manager.php +++ b/tests/phpunit/tests/customize/manager.php @@ -416,6 +416,7 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase { * @covers WP_Customize_Manager::save_changeset_post() */ function test_save_changeset_post_without_theme_activation() { + global $wp_customize; wp_set_current_user( self::$admin_user_id ); $did_action = array( @@ -425,7 +426,7 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase { ); $uuid = wp_generate_uuid4(); - $manager = new WP_Customize_Manager( array( + $wp_customize = $manager = new WP_Customize_Manager( array( 'changeset_uuid' => $uuid, ) ); $manager->register_controls(); @@ -507,7 +508,7 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase { $this->assertEquals( $previous_saved_data, json_decode( get_post( $post_id )->post_content, true ) ); // Attempt a non-transactional/incremental update. - $manager = new WP_Customize_Manager( array( + $wp_customize = $manager = new WP_Customize_Manager( array( 'changeset_uuid' => $uuid, ) ); $manager->register_controls(); // That is, register settings. @@ -543,28 +544,61 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase { ) ); $this->assertEquals( $customize_changeset_save_data_call_count + 1, $this->customize_changeset_save_data_call_count ); - // Publish the changeset. - $manager = new WP_Customize_Manager( array( 'changeset_uuid' => $uuid ) ); + // Publish the changeset: actions will be doubled since also trashed. + $expected_actions = array( + 'wp_trash_post' => 1, + 'clean_post_cache' => 2, + 'transition_post_status' => 2, + 'publish_to_trash' => 1, + 'trash_customize_changeset' => 1, + 'edit_post' => 2, + 'save_post_customize_changeset' => 2, + 'save_post' => 2, + 'wp_insert_post' => 2, + 'trashed_post' => 1, + ); + $action_counts = array(); + foreach ( array_keys( $expected_actions ) as $action_name ) { + $action_counts[ $action_name ] = did_action( $action_name ); + } + + $wp_customize = $manager = new WP_Customize_Manager( array( 'changeset_uuid' => $uuid ) ); $manager->register_controls(); - $GLOBALS['wp_customize'] = $manager; + $manager->add_setting( 'scratchpad', array( + 'type' => 'option', + 'capability' => 'exist', + ) ); + $manager->get_setting( 'blogname' )->capability = 'exist'; + wp_set_current_user( self::$subscriber_user_id ); $r = $manager->save_changeset_post( array( 'status' => 'publish', 'data' => array( 'blogname' => array( 'value' => 'Do it live \o/', ), + 'scratchpad' => array( + 'value' => '', + ), ), ) ); $this->assertInternalType( 'array', $r ); $this->assertEquals( 'Do it live \o/', get_option( 'blogname' ) ); $this->assertEquals( 'trash', get_post_status( $post_id ) ); // Auto-trashed. + $this->assertContains( '