WordPress.org

Make WordPress Core

Ticket #39487: 39487.2.diff

File 39487.2.diff, 6.9 KB (added by dlh, 6 months ago)
  • src/wp-includes/customize/class-wp-customize-selective-refresh.php

    diff --git src/wp-includes/customize/class-wp-customize-selective-refresh.php src/wp-includes/customize/class-wp-customize-selective-refresh.php
    index 0b5c446131..2f49608963 100644
    final class WP_Customize_Selective_Refresh { 
    6565                require_once( ABSPATH . WPINC . '/customize/class-wp-customize-partial.php' );
    6666
    6767                add_action( 'customize_preview_init', array( $this, 'init_preview' ) );
     68                add_action( 'customize_preview_init', [ $this, 'check_transport_of_settings_with_partials' ] );
     69                add_action( 'customize_controls_init', [ $this, 'check_transport_of_settings_with_partials' ] );
    6870        }
    6971
    7072        /**
    final class WP_Customize_Selective_Refresh { 
    7274         *
    7375         * @since 4.5.0
    7476         *
    75          * @return array Partials.
     77         * @return WP_Customize_Partial[] Partials.
    7678         */
    7779        public function partials() {
    7880                return $this->partials;
    final class WP_Customize_Selective_Refresh { 
    163165                add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_preview_scripts' ) );
    164166        }
    165167
     168        /**
     169         * Ensure that settings associated with partials use the 'postMessage' transport.
     170         */
     171        public function check_transport_of_settings_with_partials() {
     172                foreach ( $this->partials() as $partial ) {
     173                        /*
     174                         * It's possible to register a partial for a setting while intending
     175                         * to use the partial in only certain circumstances. Before
     176                         * enforcing the 'postMessage' transport for such settings, check
     177                         * that the partial is configured to request a full refresh of the
     178                         * preview if the selective refresh fails because the partial isn't
     179                         * actually used in the preview.
     180                         */
     181                        if ( ! $partial->fallback_refresh ) {
     182                                continue;
     183                        }
     184
     185                        foreach ( $partial->settings as $setting_id ) {
     186                                $setting = $this->manager->get_setting( $setting_id );
     187
     188                                if ( $setting instanceof WP_Customize_Setting ) {
     189                                        // Change only the 'refresh' transport, not custom transports.
     190                                        if ( 'refresh' !== $setting->transport ) {
     191                                                continue;
     192                                        }
     193
     194                                        /*
     195                                         * If the partial is unsupported, don't change any settings.
     196                                         *
     197                                         * Save this check until the end to avoid unnecessarily
     198                                         * re-checking the capabilities for partials and all their
     199                                         * settings when the settings already use 'postMessage'.
     200                                         */
     201                                        if ( ! $partial->check_capabilities() ) {
     202                                                continue 2;
     203                                        }
     204
     205                                        $setting->transport = 'postMessage';
     206                                }
     207                        }
     208                }
     209        }
     210
    166211        /**
    167212         * Enqueues preview scripts.
    168213         *
  • tests/phpunit/tests/customize/selective-refresh.php

    diff --git tests/phpunit/tests/customize/selective-refresh.php tests/phpunit/tests/customize/selective-refresh.php
    index 3edeee4170..e1f2a6759f 100644
    class Test_WP_Customize_Selective_Refresh extends WP_UnitTestCase { 
    116116                $this->assertEquals( 10, has_action( 'wp_enqueue_scripts', array( $this->selective_refresh, 'enqueue_preview_scripts' ) ) );
    117117        }
    118118
     119        /**
     120         * Test \WP_Customize_Selective_Refresh::check_transport_of_settings_with_partials().
     121         *
     122         * @see \WP_Customize_Selective_Refresh::check_transport_of_settings_with_partials()
     123         */
     124        public function test_check_transport_of_settings_with_partials() {
     125                wp_set_current_user( self::factory()->user->create( array( 'role' => 'administrator' ) ) );
     126
     127                // Test case with ineligible partial.
     128                $this->wp_customize->add_setting(
     129                        'cat',
     130                        array(
     131                                'transport' => 'refresh',
     132                        )
     133                );
     134                $this->wp_customize->selective_refresh->add_partial(
     135                        'cat',
     136                        array(
     137                                'fallback_refresh' => false,
     138                        )
     139                );
     140
     141                // Test case with ineligible setting transport.
     142                $this->wp_customize->add_setting(
     143                        'elephant',
     144                        array(
     145                                'transport' => 'bicycle',
     146                        )
     147                );
     148                $this->wp_customize->selective_refresh->add_partial( 'elephant' );
     149
     150                // Test case with ineligible partial capability.
     151                $this->wp_customize->add_setting(
     152                        'horse',
     153                        array(
     154                                'transport' => 'refresh',
     155                        )
     156                );
     157                $this->wp_customize->selective_refresh->add_partial(
     158                        'horse',
     159                        array(
     160                                'capability' => 'do_not_allow',
     161                        )
     162                );
     163
     164                // Test case with ineligible setting capability.
     165                $this->wp_customize->add_setting(
     166                        'mouse',
     167                        array(
     168                                'capability' => 'do_not_allow',
     169                        )
     170                );
     171                $this->wp_customize->selective_refresh->add_partial( 'mouse' );
     172
     173                // Test case with one ineligible setting.
     174                $this->wp_customize->add_setting(
     175                        'bat',
     176                        array(
     177                                'transport' => 'refresh',
     178                        )
     179                );
     180                $this->wp_customize->add_setting(
     181                        'tiger',
     182                        array(
     183                                'transport'  => 'refresh',
     184                                'capability' => 'do_not_allow',
     185                        )
     186                );
     187                $this->wp_customize->selective_refresh->add_partial(
     188                        'circus',
     189                        array(
     190                                'settings' => array( 'bat', 'tiger' ),
     191                        )
     192                );
     193
     194                // Test case with one eligible setting.
     195                $this->wp_customize->add_setting(
     196                        'dog',
     197                        array(
     198                                'transport' => 'refresh',
     199                        )
     200                );
     201                $this->wp_customize->selective_refresh->add_partial( 'dog' );
     202
     203                // Test case with many eligible settings.
     204                $this->wp_customize->add_setting(
     205                        'spider',
     206                        array(
     207                                'transport' => 'refresh',
     208                        )
     209                );
     210                $this->wp_customize->add_setting(
     211                        'hawk',
     212                        array(
     213                                'transport' => 'refresh',
     214                        )
     215                );
     216                $this->wp_customize->selective_refresh->add_partial(
     217                        'zoo',
     218                        array(
     219                                'settings' => array( 'spider', 'hawk' ),
     220                        )
     221                );
     222
     223                $this->wp_customize->selective_refresh->check_transport_of_settings_with_partials();
     224
     225                // This setting should not have been changed because it doesn't support 'fallback_refresh'.
     226                $this->assertSame( 'refresh', $this->wp_customize->get_setting( 'cat' )->transport );
     227
     228                // This setting should not have been changed because it uses a custom transport.
     229                $this->assertSame( 'bicycle', $this->wp_customize->get_setting( 'elephant' )->transport );
     230
     231                // This setting should not have been changed because of the partial's capability.
     232                $this->assertSame( 'refresh', $this->wp_customize->get_setting( 'horse' )->transport );
     233
     234                // This setting should not have been changed because of the setting's capability.
     235                $this->assertSame( 'refresh', $this->wp_customize->get_setting( 'mouse' )->transport );
     236
     237                // Neither of these settings from the same partial should have been changed because of one of the settings' capability.
     238                $this->assertSame( 'refresh', $this->wp_customize->get_setting( 'bat' )->transport );
     239                $this->assertSame( 'refresh', $this->wp_customize->get_setting( 'tiger' )->transport );
     240
     241                // These settings should have been updated to use 'postMessage'.
     242                $this->assertSame( 'postMessage', $this->wp_customize->get_setting( 'dog' )->transport );
     243                $this->assertSame( 'postMessage', $this->wp_customize->get_setting( 'spider' )->transport );
     244                $this->assertSame( 'postMessage', $this->wp_customize->get_setting( 'hawk' )->transport );
     245        }
     246
    119247        /**
    120248         * Test WP_Customize_Selective_Refresh::enqueue_preview_scripts().
    121249         *