WordPress.org

Make WordPress Core

Changeset 40676


Ignore:
Timestamp:
05/16/17 05:36:25 (5 months ago)
Author:
westonruter
Message:

Customize: Keep alive auto-drafts created for page/post stubs when parent changeset is updated, and delete when changeset is garbage-collected.

Props utkarshpatel, westonruter.
See #31089.
Fixes #39715.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/default-filters.php

    r40631 r40676  
    326326add_action( 'delete_term',                '_wp_delete_tax_menu_item',   10, 3 ); 
    327327add_action( 'transition_post_status',     '_wp_auto_add_pages_to_menu', 10, 3 ); 
     328add_action( 'delete_post',                '_wp_delete_customize_changeset_dependent_auto_drafts' ); 
    328329 
    329330// Post Thumbnail CSS class filtering 
     
    401402add_action( 'admin_enqueue_scripts', '_wp_customize_loader_settings' ); 
    402403add_action( 'delete_attachment', '_delete_attachment_theme_mod' ); 
     404add_action( 'transition_post_status', '_wp_keep_alive_customize_changeset_dependent_auto_drafts', 20, 3 ); 
    403405 
    404406// Calendar widget cache 
  • trunk/src/wp-includes/nav-menu.php

    r39638 r40676  
    979979    } 
    980980} 
     981 
     982/** 
     983 * Delete auto-draft posts associated with the supplied changeset. 
     984 * 
     985 * @since 4.8.0 
     986 * @access private 
     987 * 
     988 * @param int $post_id Post ID for the customize_changeset. 
     989 */ 
     990function _wp_delete_customize_changeset_dependent_auto_drafts( $post_id ) { 
     991    $post = get_post( $post_id ); 
     992 
     993    if ( ! $post || 'customize_changeset' !== $post->post_type ) { 
     994        return; 
     995    } 
     996 
     997    $data = json_decode( $post->post_content, true ); 
     998    if ( empty( $data['nav_menus_created_posts']['value'] ) ) { 
     999        return; 
     1000    } 
     1001    remove_action( 'delete_post', '_wp_delete_customize_changeset_dependent_auto_drafts' ); 
     1002    foreach ( $data['nav_menus_created_posts']['value'] as $post_id ) { 
     1003        if ( ! empty( $post_id ) && 'auto-draft' === get_post_status( $post_id ) ) { 
     1004            wp_delete_post( $post_id, true ); 
     1005        } 
     1006    } 
     1007    add_action( 'delete_post', '_wp_delete_customize_changeset_dependent_auto_drafts' ); 
     1008} 
  • trunk/src/wp-includes/theme.php

    r40300 r40676  
    30603060    return ( $wp_customize instanceof WP_Customize_Manager ) && $wp_customize->is_preview(); 
    30613061} 
     3062 
     3063/** 
     3064 * Make sure that auto-draft posts get their post_date bumped to prevent premature garbage-collection. 
     3065 * 
     3066 * When a changeset is updated but remains an auto-draft, ensure the post_date 
     3067 * for the auto-draft posts remains the same so that it will be 
     3068 * garbage-collected at the same time by `wp_delete_auto_drafts()`. Otherwise, 
     3069 * if the changeset is updated to be a draft then update the posts 
     3070 * to have a far-future post_date so that they will never be garbage collected 
     3071 * unless the changeset post itself is deleted. 
     3072 * 
     3073 * @since 4.8.0 
     3074 * @access private 
     3075 * @see wp_delete_auto_drafts() 
     3076 * 
     3077 * @param string   $new_status Transition to this post status. 
     3078 * @param string   $old_status Previous post status. 
     3079 * @param \WP_Post $post       Post data. 
     3080 * @global wpdb $wpdb 
     3081 */ 
     3082function _wp_keep_alive_customize_changeset_dependent_auto_drafts( $new_status, $old_status, $post ) { 
     3083    global $wpdb; 
     3084    unset( $old_status ); 
     3085 
     3086    // Short-circuit if not a changeset or if the changeset was published. 
     3087    if ( 'customize_changeset' !== $post->post_type || 'publish' === $new_status ) { 
     3088        return; 
     3089    } 
     3090 
     3091    if ( 'auto-draft' === $new_status ) { 
     3092        /* 
     3093         * Keep the post date for the post matching the changeset 
     3094         * so that it will not be garbage-collected before the changeset. 
     3095         */ 
     3096        $new_post_date = $post->post_date; 
     3097    } else { 
     3098        /* 
     3099         * Since the changeset no longer has an auto-draft (and it is not published) 
     3100         * it is now a persistent changeset, a long-lived draft, and so any 
     3101         * associated auto-draft posts should have their dates 
     3102         * pushed out very far into the future to prevent them from ever 
     3103         * being garbage-collected. 
     3104         */ 
     3105        $new_post_date = gmdate( 'Y-m-d H:i:d', strtotime( '+100 years' ) ); 
     3106    } 
     3107 
     3108    $data = json_decode( $post->post_content, true ); 
     3109    if ( empty( $data['nav_menus_created_posts']['value'] ) ) { 
     3110        return; 
     3111    } 
     3112    foreach ( $data['nav_menus_created_posts']['value'] as $post_id ) { 
     3113        if ( empty( $post_id ) || 'auto-draft' !== get_post_status( $post_id ) ) { 
     3114            continue; 
     3115        } 
     3116        $wpdb->update( 
     3117            $wpdb->posts, 
     3118            array( 'post_date' => $new_post_date ), // Note wp_delete_auto_drafts() only looks at this this date. 
     3119            array( 'ID' => $post_id ) 
     3120        ); 
     3121        clean_post_cache( $post_id ); 
     3122    } 
     3123} 
  • trunk/tests/phpunit/tests/post/nav-menu.php

    r38945 r40676  
    524524        $this->assertNotContains( 'menu-item-home', $classes ); 
    525525    } 
     526 
     527    /** 
     528     * Test _wp_delete_customize_changeset_dependent_auto_drafts. 
     529     * 
     530     * @covers _wp_delete_customize_changeset_dependent_auto_drafts() 
     531     */ 
     532    function test_wp_delete_customize_changeset_dependent_auto_drafts() { 
     533        $nav_created_post_ids = $this->factory()->post->create_many(2, array( 
     534            'post_status' => 'auto-draft', 
     535        ) ); 
     536        $data = array( 
     537            'nav_menus_created_posts' => array( 
     538                'value' => $nav_created_post_ids, 
     539            ), 
     540        ); 
     541        wp_set_current_user( self::factory()->user->create( array( 
     542            'role' => 'administrator', 
     543        ) ) ); 
     544        require_once ABSPATH . WPINC . '/class-wp-customize-manager.php'; 
     545        $wp_customize = new WP_Customize_Manager(); 
     546        do_action( 'customize_register', $wp_customize ); 
     547        $wp_customize->save_changeset_post( array( 
     548            'data' => $data, 
     549        ) ); 
     550        $this->assertInstanceOf( 'WP_Post', get_post( $nav_created_post_ids[0] ) ); 
     551        $this->assertInstanceOf( 'WP_Post', get_post( $nav_created_post_ids[1] ) ); 
     552        wp_delete_post( $wp_customize->changeset_post_id(), true ); 
     553        $this->assertNotInstanceOf( 'WP_Post', get_post( $nav_created_post_ids[0] ) ); 
     554        $this->assertNotInstanceOf( 'WP_Post', get_post( $nav_created_post_ids[1] ) ); 
     555    } 
    526556} 
  • trunk/tests/phpunit/tests/theme.php

    r40524 r40676  
    310310        $this->assertEquals($style, get_stylesheet()); 
    311311    } 
     312 
     313    /** 
     314     * Test _wp_keep_alive_customize_changeset_dependent_auto_drafts. 
     315     * 
     316     * @covers _wp_keep_alive_customize_changeset_dependent_auto_drafts() 
     317     */ 
     318    function test_wp_keep_alive_customize_changeset_dependent_auto_drafts() { 
     319        $nav_created_post_ids = $this->factory()->post->create_many(2, array( 
     320            'post_status' => 'auto-draft', 
     321        ) ); 
     322        $data = array( 
     323            'nav_menus_created_posts' => array( 
     324                'value' => $nav_created_post_ids, 
     325            ), 
     326        ); 
     327        wp_set_current_user( self::factory()->user->create( array( 'role' => 'administrator' ) ) ); 
     328        require_once ABSPATH . WPINC . '/class-wp-customize-manager.php'; 
     329        $wp_customize = new WP_Customize_Manager(); 
     330        do_action( 'customize_register', $wp_customize ); 
     331        $wp_customize->save_changeset_post( array( 
     332            'data' => $data, 
     333        ) ); 
     334        $this->assertEquals( get_post( $nav_created_post_ids[0] )->post_date, get_post( $wp_customize->changeset_post_id() )->post_date ); 
     335        $this->assertEquals( get_post( $nav_created_post_ids[1] )->post_date, get_post( $wp_customize->changeset_post_id() )->post_date ); 
     336        $wp_customize->save_changeset_post( array( 
     337            'status' => 'draft', 
     338            'data' => $data, 
     339        ) ); 
     340        $expected_year = date( 'Y' ) + 100; 
     341        $this->assertEquals( $expected_year, date( 'Y', strtotime( get_post( $nav_created_post_ids[0] )->post_date ) ) ); 
     342        $this->assertEquals( $expected_year, date( 'Y', strtotime( get_post( $nav_created_post_ids[1] )->post_date ) ) ); 
     343    } 
    312344} 
Note: See TracChangeset for help on using the changeset viewer.