Make WordPress Core

Ticket #38865: 38865.1.diff

File 38865.1.diff, 11.3 KB (added by westonruter, 9 years ago)

https://github.com/xwp/wordpress-develop/pull/202

  • src/wp-includes/class-wp-customize-manager.php

    diff --git src/wp-includes/class-wp-customize-manager.php src/wp-includes/class-wp-customize-manager.php
    index d047620..ec7c251 100644
    final class WP_Customize_Manager { 
    17281728                                }
    17291729                                continue;
    17301730                        }
    1731                         if ( is_null( $unsanitized_value ) ) {
    1732                                 continue;
    1733                         }
    17341731                        if ( $options['validate_capability'] && ! current_user_can( $setting->capability ) ) {
    17351732                                $validity = new WP_Error( 'unauthorized', __( 'Unauthorized to modify setting due to capability.' ) );
    17361733                        } else {
     1734                                if ( is_null( $unsanitized_value ) ) {
     1735                                        continue;
     1736                                }
    17371737                                $validity = $setting->validate( $unsanitized_value );
    17381738                        }
    17391739                        if ( ! is_wp_error( $validity ) ) {
    final class WP_Customize_Manager { 
    20302030                                $changed_setting_ids[] = $setting_id;
    20312031                        }
    20322032                }
    2033                 $post_values = wp_array_slice_assoc( $post_values, $changed_setting_ids );
    20342033
    20352034                /**
    20362035                 * Fires before save validation happens.
    final class WP_Customize_Manager { 
    20462045                do_action( 'customize_save_validation_before', $this );
    20472046
    20482047                // Validate settings.
    2049                 $setting_validities = $this->validate_setting_values( $post_values, array(
     2048                $validated_values = array_merge(
     2049                        array_fill_keys( array_keys( $args['data'] ), null ), // Make sure existence/capability checks are done on value-less setting updates.
     2050                        $post_values
     2051                );
     2052                $setting_validities = $this->validate_setting_values( $validated_values, array(
    20502053                        'validate_capability' => true,
    20512054                        'validate_existence' => true,
    20522055                ) );
    final class WP_Customize_Manager { 
    20642067                        return new WP_Error( 'transaction_fail', '', $response );
    20652068                }
    20662069
    2067                 $response = array(
    2068                         'setting_validities' => $setting_validities,
    2069                 );
    2070 
    20712070                // Obtain/merge data for changeset.
    20722071                $original_changeset_data = $this->get_changeset_post_data( $changeset_post_id );
    20732072                $data = $original_changeset_data;
    final class WP_Customize_Manager { 
    21052104                                // Remove setting from changeset entirely.
    21062105                                unset( $data[ $changeset_setting_id ] );
    21072106                        } else {
    2108                                 // Merge any additional setting params that have been supplied with the existing params.
     2107
    21092108                                if ( ! isset( $data[ $changeset_setting_id ] ) ) {
    21102109                                        $data[ $changeset_setting_id ] = array();
    21112110                                }
    21122111
     2112                                // Merge any additional setting params that have been supplied with the existing params.
     2113                                $merged_setting_params = array_merge( $data[ $changeset_setting_id ], $setting_params );
     2114
     2115                                // Skip updating setting params if unchanged (ensuring the user_id is not overwritten).
     2116                                if ( $data[ $changeset_setting_id ] === $merged_setting_params ) {
     2117                                        continue;
     2118                                }
     2119
    21132120                                $data[ $changeset_setting_id ] = array_merge(
    2114                                         $data[ $changeset_setting_id ],
    2115                                         $setting_params,
     2121                                        $merged_setting_params,
    21162122                                        array(
    21172123                                                'type' => $setting->type,
    21182124                                                'user_id' => $args['user_id'],
    final class WP_Customize_Manager { 
    22202226
    22212227                remove_filter( 'wp_save_post_revision_post_has_changed', array( $this, '_filter_revision_post_has_changed' ) );
    22222228
     2229                $response = array(
     2230                        'setting_validities' => $setting_validities,
     2231                );
     2232
    22232233                if ( is_wp_error( $r ) ) {
    22242234                        $response['changeset_post_save_failure'] = $r->get_error_code();
    22252235                        return new WP_Error( 'changeset_post_save_failure', '', $response );
  • tests/phpunit/tests/customize/manager.php

    diff --git tests/phpunit/tests/customize/manager.php tests/phpunit/tests/customize/manager.php
    index 54128f8..30f66ff 100644
    class Tests_WP_Customize_Manager extends WP_UnitTestCase { 
    860860                $other_admin_user_id = self::factory()->user->create( array( 'role' => 'administrator' ) );
    861861
    862862                $uuid = wp_generate_uuid4();
    863                 $manager = new WP_Customize_Manager( array(
    864                         'changeset_uuid' => $uuid,
    865                 ) );
    866                 $wp_customize = $manager;
    867                 do_action( 'customize_register', $manager );
    868                 $manager->add_setting( 'scratchpad', array(
    869                         'type' => 'option',
    870                         'capability' => 'exist',
    871                 ) );
    872 
    873                 // Create initial set of
    874                 $r = $manager->save_changeset_post( array(
     863                $wp_customize = $this->create_test_manager( $uuid );
     864                $r = $wp_customize->save_changeset_post( array(
    875865                        'status' => 'auto-draft',
    876866                        'data' => array(
    877867                                'blogname' => array(
    class Tests_WP_Customize_Manager extends WP_UnitTestCase { 
    890880                        array_fill_keys( array( 'blogname', 'scratchpad', 'background_color' ), true ),
    891881                        $r['setting_validities']
    892882                );
    893                 $post_id = $manager->find_changeset_post_id( $uuid );
     883                $post_id = $wp_customize->find_changeset_post_id( $uuid );
    894884                $data = json_decode( get_post( $post_id )->post_content, true );
    895885                $this->assertEquals( self::$admin_user_id, $data['blogname']['user_id'] );
    896886                $this->assertEquals( self::$admin_user_id, $data['scratchpad']['user_id'] );
    class Tests_WP_Customize_Manager extends WP_UnitTestCase { 
    898888
    899889                // Attempt to save just one setting under a different user.
    900890                wp_set_current_user( $other_admin_user_id );
    901                 $r = $manager->save_changeset_post( array(
     891                $wp_customize = $this->create_test_manager( $uuid );
     892                $r = $wp_customize->save_changeset_post( array(
    902893                        'status' => 'auto-draft',
    903894                        'data' => array(
    904895                                'blogname' => array(
    class Tests_WP_Customize_Manager extends WP_UnitTestCase { 
    923914                $this->assertEquals( $other_admin_user_id, $data[ $this->manager->get_stylesheet() . '::background_color' ]['user_id'] );
    924915
    925916                // Attempt to save now as under-privileged user.
    926                 $r = $manager->save_changeset_post( array(
     917                $wp_customize = $this->create_test_manager( $uuid );
     918                $r = $wp_customize->save_changeset_post( array(
    927919                        'status' => 'auto-draft',
    928920                        'data' => array(
     921                                'blogname' => array(
     922                                        'value' => 'Admin 2 Title', // Identical to what is already in the changeset so will be skipped.
     923                                ),
    929924                                'scratchpad' => array(
    930925                                        'value' => 'Subscriber Scratch',
    931926                                ),
    class Tests_WP_Customize_Manager extends WP_UnitTestCase { 
    934929                ) );
    935930                $this->assertInternalType( 'array', $r );
    936931                $this->assertEquals(
    937                         array_fill_keys( array( 'scratchpad' ), true ),
     932                        array_fill_keys( array( 'scratchpad', 'blogname' ), true ),
    938933                        $r['setting_validities']
    939934                );
    940935                $data = json_decode( get_post( $post_id )->post_content, true );
    941                 $this->assertEquals( $other_admin_user_id, $data['blogname']['user_id'] );
     936                $this->assertEquals( $other_admin_user_id, $data['blogname']['user_id'], 'Expected setting to be untouched.' );
    942937                $this->assertEquals( self::$subscriber_user_id, $data['scratchpad']['user_id'] );
    943938                $this->assertEquals( $other_admin_user_id, $data[ $this->manager->get_stylesheet() . '::background_color' ]['user_id'] );
    944939
    class Tests_WP_Customize_Manager extends WP_UnitTestCase { 
    955950                        $save_counts[ $setting_id ] = did_action( sprintf( 'customize_save_%s', $setting_id ) );
    956951                }
    957952                $this->filtered_setting_current_user_ids = array();
    958                 foreach ( $manager->settings() as $setting ) {
     953                foreach ( $wp_customize->settings() as $setting ) {
    959954                        add_filter( sprintf( 'customize_sanitize_%s', $setting->id ), array( $this, 'filter_customize_setting_to_log_current_user' ), 10, 2 );
    960955                }
    961956                wp_update_post( array( 'ID' => $post_id, 'post_status' => 'publish' ) );
    class Tests_WP_Customize_Manager extends WP_UnitTestCase { 
    972967        }
    973968
    974969        /**
     970         * Create test manager.
     971         *
     972         * @param string $uuid Changeset UUID.
     973         * @return WP_Customize_Manager Manager.
     974         */
     975        protected function create_test_manager( $uuid ) {
     976                $manager = new WP_Customize_Manager( array(
     977                        'changeset_uuid' => $uuid,
     978                ) );
     979                do_action( 'customize_register', $manager );
     980                $manager->add_setting( 'blogfounded', array(
     981                        'type' => 'option',
     982                ) );
     983                $manager->add_setting( 'blogterminated', array(
     984                        'type' => 'option',
     985                        'capability' => 'do_not_allow',
     986                ) );
     987                $manager->add_setting( 'scratchpad', array(
     988                        'type' => 'option',
     989                        'capability' => 'exist',
     990                ) );
     991                return $manager;
     992        }
     993
     994        /**
     995         * Test writing changesets when user supplies unchanged values.
     996         *
     997         * @ticket 38865
     998         * @covers WP_Customize_Manager::save_changeset_post()
     999         */
     1000        function test_save_changeset_post_with_unchanged_values() {
     1001                global $wp_customize;
     1002
     1003                add_theme_support( 'custom-background' );
     1004                wp_set_current_user( self::$admin_user_id );
     1005                $other_admin_user_id = self::factory()->user->create( array( 'role' => 'administrator' ) );
     1006
     1007                $uuid = wp_generate_uuid4();
     1008                $wp_customize = $this->create_test_manager( $uuid );
     1009                $wp_customize->save_changeset_post( array(
     1010                        'status' => 'auto-draft',
     1011                        'data' => array(
     1012                                'blogname' => array(
     1013                                        'value' => 'Admin 1 Title',
     1014                                ),
     1015                                'blogdescription' => array(
     1016                                        'value' => 'Admin 1 Tagline',
     1017                                ),
     1018                                'blogfounded' => array(
     1019                                        'value' => '2016',
     1020                                ),
     1021                                'scratchpad' => array(
     1022                                        'value' => 'Admin 1 Scratch',
     1023                                ),
     1024                        ),
     1025                ) );
     1026
     1027                // Make sure that setting properties of unknown and unauthorized settings are rejected.
     1028                $data = get_post( $wp_customize->changeset_post_id() )->post_content;
     1029                $r = $wp_customize->save_changeset_post( array(
     1030                        'data' => array(
     1031                                'unknownsetting' => array(
     1032                                        'custom' => 'prop',
     1033                                ),
     1034                                'blogterminated' => array(
     1035                                        'custom' => 'prop',
     1036                                ),
     1037                        ),
     1038                ) );
     1039                $this->assertInstanceOf( 'WP_Error', $r['setting_validities']['unknownsetting'] );
     1040                $this->assertEquals( 'unrecognized', $r['setting_validities']['unknownsetting']->get_error_code() );
     1041                $this->assertInstanceOf( 'WP_Error', $r['setting_validities']['blogterminated'] );
     1042                $this->assertEquals( 'unauthorized', $r['setting_validities']['blogterminated']->get_error_code() );
     1043                $this->assertEquals( $data, get_post( $wp_customize->changeset_post_id() )->post_content );
     1044
     1045                // Test submitting data with changed and unchanged settings, creating a new instance so that the post_values are cleared.
     1046                wp_set_current_user( $other_admin_user_id );
     1047                $wp_customize = $this->create_test_manager( $uuid );
     1048                $r = $wp_customize->save_changeset_post( array(
     1049                        'status' => 'auto-draft',
     1050                        'data' => array(
     1051                                'blogname' => array(
     1052                                        'value' => 'Admin 1 Title', // Unchanged value.
     1053                                ),
     1054                                'blogdescription' => array(
     1055                                        'value' => 'Admin 1 Tagline Changed', // Changed value.
     1056                                ),
     1057                                'blogfounded' => array(
     1058                                        'extra' => 'blogfounded_param', // New param.
     1059                                ),
     1060                                'scratchpad' => array(
     1061                                        'value' => 'Admin 1 Scratch', // Unchanged value.
     1062                                        'extra' => 'background_scratchpad2', // New param.
     1063                                ),
     1064                        ),
     1065                ) );
     1066
     1067                // Note that blogfounded is not included among setting_validities because no value was supplied and it is not unrecognized/unauthorized.
     1068                $this->assertEquals( array_fill_keys( array( 'blogname', 'blogdescription', 'scratchpad' ), true ), $r['setting_validities'], 'Expected blogname even though unchanged.' );
     1069
     1070                $data = json_decode( get_post( $wp_customize->changeset_post_id() )->post_content, true );
     1071
     1072                $this->assertEquals( self::$admin_user_id, $data['blogname']['user_id'], 'Expected unchanged user_id since value was unchanged.' );
     1073                $this->assertEquals( $other_admin_user_id, $data['blogdescription']['user_id'] );
     1074                $this->assertEquals( $other_admin_user_id, $data['blogfounded']['user_id'] );
     1075                $this->assertEquals( $other_admin_user_id, $data['scratchpad']['user_id'] );
     1076        }
     1077
     1078        /**
    9751079         * Test writing changesets and publishing with users who can unfiltered_html and those who cannot.
    9761080         *
    9771081         * @ticket 38705