Make WordPress Core

Changeset 49716


Ignore:
Timestamp:
12/01/2020 03:42:31 AM (4 years ago)
Author:
TimothyBlynJacobs
Message:

Site Health, App Passwords: Ensure REST API responses are properly translated.

The REST API requests in Site Health and App Passwords now include _locale=user in the request URL to ensure the user's locale is used instead of the site locale. Additionally, the apiRequest library now sends a JSON Accept header which is required by determine_locale() to respect the _locale query parameter.

The Site Health REST API controllers now manually load the default admin textdomain if not is_admin(). This allows for the Site Health tests to be translated even though the translations are part of the administration project and the REST API is not.

Props oglekler, kebbet, Clorith, TimothyBlynJacobs, ocean90, SergeyBiryukov, adamsilverstein.
Fixes #51871.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/js/_enqueues/admin/application-passwords.js

    r49549 r49716  
    4848
    4949        wp.apiRequest( {
    50             path: '/wp/v2/users/' + userId + '/application-passwords',
     50            path: '/wp/v2/users/' + userId + '/application-passwords?_locale=user',
    5151            method: 'POST',
    5252            data: request
     
    9595
    9696        wp.apiRequest( {
    97             path: '/wp/v2/users/' + userId + '/application-passwords/' + uuid,
     97            path: '/wp/v2/users/' + userId + '/application-passwords/' + uuid + '?_locale=user',
    9898            method: 'DELETE'
    9999        } ).always( function() {
     
    124124
    125125        wp.apiRequest( {
    126             path: '/wp/v2/users/' + userId + '/application-passwords',
     126            path: '/wp/v2/users/' + userId + '/application-passwords?_locale=user',
    127127            method: 'DELETE'
    128128        } ).always( function() {
  • trunk/src/js/_enqueues/admin/auth-app.js

    r49562 r49716  
    5555
    5656        wp.apiRequest( {
    57             path: '/wp/v2/users/me/application-passwords',
     57            path: '/wp/v2/users/me/application-passwords?_locale=user',
    5858            method: 'POST',
    5959            data: request
  • trunk/src/js/_enqueues/admin/site-health.js

    r49537 r49716  
    272272                if ( 'undefined' !== typeof( this.has_rest ) && this.has_rest ) {
    273273                    wp.apiRequest( {
    274                         url: this.test,
     274                        url: wp.url.addQueryArgs( this.test, { _locale: 'user' } ),
    275275                        headers: this.headers
    276276                    } )
  • trunk/src/js/_enqueues/wp/api-request.js

    r49133 r49716  
    1111 * @since 4.9.0
    1212 * @since 5.6.0 Added overriding of the "PUT" and "DELETE" methods with "POST".
     13 *              Added an "application/json" Accept header to all requests.
    1314 * @output wp-includes/js/api-request.js
    1415 */
     
    2728        var method = options.method;
    2829        var namespaceTrimmed, endpointTrimmed, apiRoot;
    29         var headers, addNonceHeader, headerName;
     30        var headers, addNonceHeader, addAcceptHeader, headerName;
    3031
    3132        if (
     
    5657        // If ?_wpnonce=... is present, no need to add a nonce header.
    5758        addNonceHeader = ! ( options.data && options.data._wpnonce );
     59        addAcceptHeader = true;
    5860
    5961        headers = options.headers || {};
    6062
    61         // If an 'X-WP-Nonce' header (or any case-insensitive variation
    62         // thereof) was specified, no need to add a nonce header.
    63         if ( addNonceHeader ) {
    64             for ( headerName in headers ) {
    65                 if ( headers.hasOwnProperty( headerName ) ) {
    66                     if ( headerName.toLowerCase() === 'x-wp-nonce' ) {
    67                         addNonceHeader = false;
    68                         break;
    69                     }
    70                 }
     63        for ( headerName in headers ) {
     64            if ( ! headers.hasOwnProperty( headerName ) ) {
     65                continue;
     66            }
     67
     68            // If an 'X-WP-Nonce' or 'Accept' header (or any case-insensitive variation
     69            // thereof) was specified, no need to add the header again.
     70            switch ( headerName.toLowerCase() ) {
     71                case 'x-wp-nonce':
     72                    addNonceHeader = false;
     73                    break;
     74                case 'accept':
     75                    addAcceptHeader = false;
     76                    break;
    7177            }
    7278        }
     
    7682            headers = $.extend( {
    7783                'X-WP-Nonce': wpApiSettings.nonce
     84            }, headers );
     85        }
     86
     87        if ( addAcceptHeader ) {
     88            headers = $.extend( {
     89                'Accept': 'application/json, */*;q=0.1'
    7890            }, headers );
    7991        }
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-site-health-controller.php

    r49334 r49716  
    172172     */
    173173    public function test_background_updates() {
     174        $this->load_admin_textdomain();
    174175        return $this->site_health->get_test_background_updates();
    175176    }
     
    183184     */
    184185    public function test_dotorg_communication() {
     186        $this->load_admin_textdomain();
    185187        return $this->site_health->get_test_dotorg_communication();
    186188    }
     
    194196     */
    195197    public function test_loopback_requests() {
     198        $this->load_admin_textdomain();
    196199        return $this->site_health->get_test_loopback_requests();
    197200    }
     
    205208     */
    206209    public function test_authorization_header() {
     210        $this->load_admin_textdomain();
    207211        return $this->site_health->get_test_authorization_header();
    208212    }
     
    219223            require_once ABSPATH . 'wp-admin/includes/class-wp-debug-data.php';
    220224        }
     225
     226        $this->load_admin_textdomain();
    221227
    222228        $sizes_data = WP_Debug_Data::get_sizes();
     
    255261
    256262        return $all_sizes;
     263    }
     264
     265    /**
     266     * Loads the admin textdomain for Site Health tests.
     267     *
     268     * The {@see WP_Site_Health} class is defined in WP-Admin, while the REST API operates in a front-end context.
     269     * This means that the translations for Site Health won't be loaded by default in {@see load_default_textdomain()}.
     270     *
     271     * @since 5.6.0
     272     */
     273    protected function load_admin_textdomain() {
     274        // Accounts for inner REST API requests in the admin.
     275        if ( ! is_admin() ) {
     276            $locale = determine_locale();
     277            load_textdomain( 'default', WP_LANG_DIR . "/admin-$locale.mo" );
     278        }
    257279    }
    258280
  • trunk/src/wp-includes/script-loader.php

    r49649 r49716  
    12871287        $scripts->set_translations( 'plugin-install' );
    12881288
    1289         $scripts->add( 'site-health', "/wp-admin/js/site-health$suffix.js", array( 'clipboard', 'jquery', 'wp-util', 'wp-a11y', 'wp-api-request' ), false, 1 );
     1289        $scripts->add( 'site-health', "/wp-admin/js/site-health$suffix.js", array( 'clipboard', 'jquery', 'wp-util', 'wp-a11y', 'wp-api-request', 'wp-url' ), false, 1 );
    12901290        $scripts->set_translations( 'site-health' );
    12911291
  • trunk/tests/qunit/wp-includes/js/api-request.js

    r46586 r49716  
    33    var originalRootUrl = window.wpApiSettings.root;
    44
    5     var nonceHeader = { 'X-WP-Nonce': 'not_a_real_nonce' };
     5    var expectedHeaders = {
     6        'X-WP-Nonce': 'not_a_real_nonce',
     7        'Accept': 'application/json, */*;q=0.1'
     8    };
    69
    710    QUnit.module( 'wp-api-request', {
     
    3336            headers: {
    3437                'X-WP-Nonce': 'not_a_real_nonce',
     38                'Accept': 'application/json, */*;q=0.1',
    3539                'Header-Name': 'value'
    3640            },
     
    6569
    6670            assert.notStrictEqual( settings, settingsOriginal );
    67             assert.strictEqual( settings.headers, settingsOriginal.headers );
     71
     72            var expected = {
     73                Accept: 'application/json, */*;q=0.1'
     74            };
     75            expected[ headerName ] = nonceHeader[ headerName ];
    6876
    6977            assert.deepEqual( settings, {
    7078                url: 'aaaa',
    71                 headers: nonceHeader
     79                headers: expected
    7280            } );
    7381        } );
     
    8896        assert.deepEqual( settings, {
    8997            url: 'aaaa',
    90             headers: {},
     98            headers: {
     99                'Accept': 'application/json, */*;q=0.1'
     100            },
    91101            data: {
    92102                _wpnonce: 'definitely_not_a_real_nonce'
    93103            }
    94104        } );
     105    } );
     106
     107    QUnit.test( 'does not add accept header if already present', function( assert ) {
     108        var settingsOriginal = {
     109            url: 'aaaa',
     110            headers: {
     111                'Accept': 'text/xml'
     112            }
     113        };
     114
     115        var settings = wp.apiRequest.buildAjaxOptions( settingsOriginal );
     116
     117        assert.strictEqual( settingsOriginal.headers.Accept, settings.headers.Accept );
    95118    } );
    96119
     
    101124        } ), {
    102125            url: 'http://localhost/wp-json/wp/v2/posts',
    103             headers: nonceHeader
     126            headers: expectedHeaders
    104127        } );
    105128    } );
     
    111134        } ), {
    112135            url: 'http://localhost/wp-json/wp/v2/posts',
    113             headers: nonceHeader
     136            headers: expectedHeaders
    114137        } );
    115138    } );
     
    121144        } ), {
    122145            url: 'http://localhost/wp-json/wp/v2',
    123             headers: nonceHeader
     146            headers: expectedHeaders
    124147        } );
    125148    } );
     
    131154        } ), {
    132155            url: 'http://localhost/wp-json/',
    133             headers: nonceHeader
     156            headers: expectedHeaders
    134157        } );
    135158    } );
     
    144167            } ), {
    145168                url: 'http://localhost/index.php?rest_route=/wp/v2/posts&orderby=title',
    146                 headers: nonceHeader
     169                headers: expectedHeaders
    147170            } );
    148171        }
     
    158181            } ), {
    159182                url: 'http://localhost/index.php?rest_route=/',
    160                 headers: nonceHeader
     183                headers: expectedHeaders
    161184            } );
    162185        }
Note: See TracChangeset for help on using the changeset viewer.