Make WordPress Core


Ignore:
Timestamp:
09/27/2017 10:24:37 PM (7 years ago)
Author:
westonruter
Message:

Customize: Introduce drafting and scheduling for Customizer changesets.

  • Incorporates code from the Customize Snapshots and Customize Posts feature plugins.
  • Adds a new Publish Settings section for managing the changeset status, scheduled date, and frontend preview link.
  • Updates Publish button to reflect the status selected in the Publish Settings (including Save Draft and Schedule).
  • Deactivates the Themes section when a non-publish status selected, and deactivates the Publish Settings section when previewing a theme switch.
  • Introduces an outer section type (wp.customize.OuterSection in JS) for the Publish Settings section to use and for available widgets and available nav menu panels to use in the future. These sections can be expanded while other sections are expanded.
  • Introduces WP_Customize_Date_Time_Control in PHP and wp.customize.DateTimeControl in JS for managing a date/time value.
  • Keeps track of scheduled time and proactively publish from the client when the time arrives, as opposed to waiting for WP Cron.
  • Auto-publishes a scheduled changeset when attempting to access one that missed its schedule.
  • Starts a new changeset if attempting to save a changeset that was previously publish.
  • Adds force arg to requestChangesetUpdate() to force an update request even when there are no pending changes.
  • Adds utils methods for getCurrentTimestamp and getRemainingTime.
  • Adds new state values for selectedChangesetStatus, changesetDate, selectedChangesetDate.
  • Fixes logic for when to short-circuit check to close Customizer when there are unsaved changes.
  • Adds getter methods for autosaved and branching parameters, with the latter applying the customize_changeset_branching filter.
  • Call to establish_loaded_changeset on the fly when changeset_uuid() is called if no changeset UUID was specififed.
  • De-duplicates logic for dismissing auto-draft changesets.
  • Includes unit tests.

Builds on [41597].
Props sayedwp, westonruter, melchoyce, JoshuaWold, folletto, stubgo, karmatosed, dlh, paaljoachim, afercia, johnregan3, utkarshpatel, valendesigns.
See #30937.
Fixes #39896, #28721, #39275.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/ajax/CustomizeManager.php

    r39409 r41626  
    166166        $this->assertFalse( $this->_last_response_parsed['success'] );
    167167        $this->assertEquals( 'changeset_already_published', $this->_last_response_parsed['data']['code'] );
    168         wp_update_post( array( 'ID' => $wp_customize->changeset_post_id(), 'post_status' => 'auto-draft' ) );
     168        wp_update_post( array(
     169            'ID' => $wp_customize->changeset_post_id(),
     170            'post_status' => 'auto-draft',
     171        ) );
    169172
    170173        // User cannot edit.
     
    223226        $this->assertTrue( $this->_last_response_parsed['success'] );
    224227        $this->assertEquals( 'future', get_post_status( $wp_customize->changeset_post_id() ) );
    225         wp_update_post( array( 'ID' => $wp_customize->changeset_post_id(), 'post_status' => 'auto-draft' ) );
    226 
     228        wp_update_post( array(
     229            'ID' => $wp_customize->changeset_post_id(),
     230            'post_status' => 'auto-draft',
     231        ) );
    227232    }
    228233
     
    255260        $wp_customize = $this->set_up_valid_state();
    256261
    257         // Successful future.
    258262        $_POST['customize_changeset_status'] = 'publish';
    259263        $_POST['customize_changeset_title'] = 'Success Changeset';
     
    269273        $this->assertEquals( 'publish', $this->_last_response_parsed['data']['changeset_status'] );
    270274        $this->assertArrayHasKey( 'next_changeset_uuid', $this->_last_response_parsed['data'] );
     275        $this->assertTrue( wp_is_uuid( $this->_last_response_parsed['data']['next_changeset_uuid'], 4 ) );
    271276        $this->assertEquals( 'Success Changeset', get_post( $wp_customize->changeset_post_id() )->post_title );
    272277        $this->assertEquals( 'Successful Site Title', get_option( 'blogname' ) );
    273 
    274278    }
    275279
     
    296300        $wp_customize = $this->set_up_valid_state( $uuid );
    297301
    298         // Successful future.
    299302        $_POST['customize_changeset_status'] = 'publish';
    300303        $_POST['customize_changeset_title'] = 'Published';
     
    305308        $this->assertEquals( 'publish', $this->_last_response_parsed['data']['changeset_status'] );
    306309        $this->assertArrayHasKey( 'next_changeset_uuid', $this->_last_response_parsed['data'] );
     310        $this->assertTrue( wp_is_uuid( $this->_last_response_parsed['data']['next_changeset_uuid'], 4 ) );
    307311        $this->assertEquals( 'New Site Title', get_option( 'blogname' ) );
    308312        $this->assertEquals( 'Published', get_post( $post_id )->post_title );
     
    337341        $this->make_ajax_call( 'customize_save' );
    338342        $this->assertTrue( $this->_last_response_parsed['success'] );
     343        $this->assertArrayHasKey( 'changeset_date', $this->_last_response_parsed['data'] );
    339344        $changeset_post_schedule = get_post( $post_id );
    340345        $this->assertEquals( $future_date, $changeset_post_schedule->post_date );
     
    345350        $this->make_ajax_call( 'customize_save' );
    346351        $this->assertTrue( $this->_last_response_parsed['success'] );
     352        $this->assertArrayNotHasKey( 'changeset_date', $this->_last_response_parsed['data'] );
    347353        $changeset_post_draft = get_post( $post_id );
    348354        $this->assertEquals( $future_date, $changeset_post_draft->post_date );
     
    352358        $this->make_ajax_call( 'customize_save' );
    353359        $this->assertTrue( $this->_last_response_parsed['success'] );
     360        $this->assertArrayHasKey( 'changeset_date', $this->_last_response_parsed['data'] );
    354361        $changeset_post_schedule = get_post( $post_id );
    355362        $this->assertEquals( $future_date, $changeset_post_schedule->post_date );
     
    381388        $this->make_ajax_call( 'customize_save' );
    382389        $this->assertTrue( $this->_last_response_parsed['success'] );
     390        $this->assertArrayHasKey( 'next_changeset_uuid', $this->_last_response_parsed['data'] );
     391        $this->assertTrue( wp_is_uuid( $this->_last_response_parsed['data']['next_changeset_uuid'], 4 ) );
    383392        $changeset_post_publish = get_post( $post_id );
    384393        $this->assertNotEquals( $future_date, $changeset_post_publish->post_date );
     394
     395        // Check response when trying to update an already-published post.
     396        $this->assertEquals( 'trash', get_post_status( $post_id ) );
     397        $_POST['customize_changeset_status'] = 'publish';
     398        $this->make_ajax_call( 'customize_save' );
     399        $this->assertFalse( $this->_last_response_parsed['success'] );
     400        $this->assertEquals( 'changeset_already_published', $this->_last_response_parsed['data']['code'] );
     401        $this->assertArrayHasKey( 'next_changeset_uuid', $this->_last_response_parsed['data'] );
     402        $this->assertTrue( wp_is_uuid( $this->_last_response_parsed['data']['next_changeset_uuid'], 4 ) );
     403    }
     404
     405    /**
     406     * Test WP_Customize_Manager::save().
     407     *
     408     * @ticket 39896
     409     * @covers WP_Customize_Manager::save()
     410     */
     411    public function test_save_autosave() {
     412        $uuid = wp_generate_uuid4();
     413
     414        $post_id = $this->factory()->post->create( array(
     415            'post_name' => $uuid,
     416            'post_type' => 'customize_changeset',
     417            'post_status' => 'draft',
     418            'post_content' => wp_json_encode( array(
     419                'blogname' => array(
     420                    'value' => 'New Site Title',
     421                ),
     422            ) ),
     423        ) );
     424        $this->set_up_valid_state( $uuid );
     425
     426        $this->assertFalse( wp_get_post_autosave( $post_id ) );
     427
     428        $_POST['customize_changeset_data'] = wp_json_encode( array(
     429            'blogname' => array(
     430                'value' => 'Autosaved Site Title',
     431            ),
     432        ) );
     433
     434        $_POST['customize_changeset_autosave'] = 'on';
     435        $this->make_ajax_call( 'customize_save' );
     436        $this->assertTrue( $this->_last_response_parsed['success'] );
     437        $this->assertEquals( 'draft', $this->_last_response_parsed['data']['changeset_status'] );
     438        $autosave_revision = wp_get_post_autosave( $post_id );
     439        $this->assertInstanceOf( 'WP_Post', $autosave_revision );
     440
     441        $this->assertContains( 'New Site Title', get_post( $post_id )->post_content );
     442        $this->assertContains( 'Autosaved Site Title', $autosave_revision->post_content );
     443    }
     444
     445    /**
     446     * Test request for dismissing autosave changesets.
     447     *
     448     * @ticket 39896
     449     * @covers WP_Customize_Manager::handle_dismiss_changeset_autosave_request()
     450     * @covers WP_Customize_Manager::dismiss_user_auto_draft_changesets()
     451     */
     452    public function test_handle_dismiss_changeset_autosave_request() {
     453        $uuid = wp_generate_uuid4();
     454        $wp_customize = $this->set_up_valid_state( $uuid );
     455
     456        $this->make_ajax_call( 'dismiss_customize_changeset_autosave' );
     457        $this->assertFalse( $this->_last_response_parsed['success'] );
     458        $this->assertEquals( 'invalid_nonce', $this->_last_response_parsed['data'] );
     459
     460        $nonce = wp_create_nonce( 'dismiss_customize_changeset_autosave' );
     461        $_POST['nonce'] = $_GET['nonce'] = $_REQUEST['nonce'] = $nonce;
     462        $this->make_ajax_call( 'dismiss_customize_changeset_autosave' );
     463        $this->assertFalse( $this->_last_response_parsed['success'] );
     464        $this->assertEquals( 'no_auto_draft_to_delete', $this->_last_response_parsed['data'] );
     465
     466        $other_user_id = $this->factory()->user->create();
     467
     468        // Create auto-drafts.
     469        $user_auto_draft_ids = array();
     470        for ( $i = 0; $i < 3; $i++ ) {
     471            $user_auto_draft_ids[] = $this->factory()->post->create( array(
     472                'post_name' => wp_generate_uuid4(),
     473                'post_type' => 'customize_changeset',
     474                'post_status' => 'auto-draft',
     475                'post_author' => self::$admin_user_id,
     476                'post_content' => wp_json_encode( array() ),
     477            ) );
     478        }
     479        $other_user_auto_draft_ids = array();
     480        for ( $i = 0; $i < 3; $i++ ) {
     481            $other_user_auto_draft_ids[] = $this->factory()->post->create( array(
     482                'post_name' => wp_generate_uuid4(),
     483                'post_type' => 'customize_changeset',
     484                'post_status' => 'auto-draft',
     485                'post_author' => $other_user_id,
     486                'post_content' => wp_json_encode( array() ),
     487            ) );
     488        }
     489        foreach ( array_merge( $user_auto_draft_ids, $other_user_auto_draft_ids ) as $post_id ) {
     490            $this->assertFalse( (bool) get_post_meta( $post_id, '_customize_restore_dismissed', true ) );
     491        }
     492        $this->make_ajax_call( 'dismiss_customize_changeset_autosave' );
     493        $this->assertTrue( $this->_last_response_parsed['success'] );
     494        $this->assertEquals( 'auto_draft_dismissed', $this->_last_response_parsed['data'] );
     495        foreach ( $user_auto_draft_ids as $post_id ) {
     496            $this->assertEquals( 'auto-draft', get_post_status( $post_id ) );
     497            $this->assertTrue( (bool) get_post_meta( $post_id, '_customize_restore_dismissed', true ) );
     498        }
     499        foreach ( $other_user_auto_draft_ids as $post_id ) {
     500            $this->assertEquals( 'auto-draft', get_post_status( $post_id ) );
     501            $this->assertFalse( (bool) get_post_meta( $post_id, '_customize_restore_dismissed', true ) );
     502        }
     503
     504        // Subsequent test results in none dismissed.
     505        $this->make_ajax_call( 'dismiss_customize_changeset_autosave' );
     506        $this->assertFalse( $this->_last_response_parsed['success'] );
     507        $this->assertEquals( 'no_auto_draft_to_delete', $this->_last_response_parsed['data'] );
     508
     509        // Save a changeset as a draft.
     510        $r = $wp_customize->save_changeset_post( array(
     511            'data' => array(
     512                'blogname' => array(
     513                    'value' => 'Foo',
     514                ),
     515            ),
     516            'status' => 'draft',
     517        ) );
     518        $this->assertNotInstanceOf( 'WP_Error', $r );
     519        $this->assertFalse( wp_get_post_autosave( $wp_customize->changeset_post_id() ) );
     520        $this->assertContains( 'Foo', get_post( $wp_customize->changeset_post_id() )->post_content );
     521
     522        // Since no autosave yet, confirm no action.
     523        $this->make_ajax_call( 'dismiss_customize_changeset_autosave' );
     524        $this->assertFalse( $this->_last_response_parsed['success'] );
     525        $this->assertEquals( 'no_autosave_revision_to_delete', $this->_last_response_parsed['data'] );
     526
     527        // Add the autosave revision.
     528        $r = $wp_customize->save_changeset_post( array(
     529            'data' => array(
     530                'blogname' => array(
     531                    'value' => 'Bar',
     532                ),
     533            ),
     534            'autosave' => true,
     535        ) );
     536        $this->assertNotInstanceOf( 'WP_Error', $r );
     537        $autosave_revision = wp_get_post_autosave( $wp_customize->changeset_post_id() );
     538        $this->assertInstanceOf( 'WP_Post', $autosave_revision );
     539        $this->assertContains( 'Foo', get_post( $wp_customize->changeset_post_id() )->post_content );
     540        $this->assertContains( 'Bar', $autosave_revision->post_content );
     541
     542        // Confirm autosave gets deleted.
     543        $this->make_ajax_call( 'dismiss_customize_changeset_autosave' );
     544        $this->assertTrue( $this->_last_response_parsed['success'] );
     545        $this->assertEquals( 'autosave_revision_deleted', $this->_last_response_parsed['data'] );
     546        $this->assertFalse( wp_get_post_autosave( $wp_customize->changeset_post_id() ) );
     547
     548        // Since no autosave yet, confirm no action.
     549        $this->make_ajax_call( 'dismiss_customize_changeset_autosave' );
     550        $this->assertFalse( $this->_last_response_parsed['success'] );
     551        $this->assertEquals( 'no_autosave_revision_to_delete', $this->_last_response_parsed['data'] );
    385552    }
    386553}
Note: See TracChangeset for help on using the changeset viewer.