Skip to content

Commit

Permalink
Merge pull request #6773 from ampproject/add/wp-back-compat
Browse files Browse the repository at this point in the history
Add back-compat to old WP versions for new v2.2 features
  • Loading branch information
westonruter authored Dec 14, 2021
2 parents 3003385 + ff7e7b7 commit 27a2104
Show file tree
Hide file tree
Showing 40 changed files with 686 additions and 515 deletions.
1 change: 0 additions & 1 deletion .phpstorm.meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
'rest.scannable_urls_controller' => \AmpProject\AmpWP\Validation\ScannableURLsRestController::class,
'rest.validation_counts_controller' => \AmpProject\AmpWP\Validation\ValidationCountsRestController::class,
'sandboxing' => \AmpProject\AmpWP\Sandboxing::class,
'save_post_validation_event' => \AmpProject\AmpWP\Validation\SavePostValidationEvent::class,
'server_timing' => \AmpProject\AmpWP\Instrumentation\ServerTiming::class,
'site_health_integration' => \AmpProject\AmpWP\Admin\SiteHealth::class,
'support' => \AmpProject\AmpWP\Support\SupportCliCommand::class,
Expand Down
2 changes: 1 addition & 1 deletion assets/src/admin/site-scan-notice/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function Providers( { children } ) {
optionsRestPath={ OPTIONS_REST_PATH }
populateDefaultValues={ false }
>
<PluginsContextProvider hasErrorBoundary={ true }>
<PluginsContextProvider>
<SiteScanContextProvider
scannableUrlsRestPath={ SCANNABLE_URLS_REST_PATH }
validateNonce={ VALIDATE_NONCE }
Expand Down
42 changes: 10 additions & 32 deletions assets/src/components/plugins-context-provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,22 @@ import PropTypes from 'prop-types';
/**
* WordPress dependencies
*/
import {
createContext,
useContext,
useEffect,
useRef,
useState,
} from '@wordpress/element';
import { createContext, useEffect, useRef, useState } from '@wordpress/element';
import apiFetch from '@wordpress/api-fetch';

/**
* Internal dependencies
*/
import { ErrorContext } from '../error-context-provider';
import { useAsyncError } from '../../utils/use-async-error';
import { addQueryArgs } from '@wordpress/url';

export const Plugins = createContext();

/**
* Plugins context provider.
*
* @param {Object} props Component props.
* @param {any} props.children Component children.
* @param {boolean} props.hasErrorBoundary Whether the component is wrapped in an error boundary.
* @param {Object} props Component props.
* @param {any} props.children Component children.
*/
export function PluginsContextProvider( {
children,
hasErrorBoundary = false,
} ) {
export function PluginsContextProvider( { children } ) {
const [ plugins, setPlugins ] = useState( [] );
const [ fetchingPlugins, setFetchingPlugins ] = useState( null );

const { error, setError } = useContext( ErrorContext );
const { setAsyncError } = useAsyncError();
const [ error, setError ] = useState();

/**
* This component sets state inside async functions.
Expand All @@ -62,7 +45,9 @@ export function PluginsContextProvider( {

try {
const fetchedPlugins = await apiFetch( {
path: '/wp/v2/plugins',
path: addQueryArgs( '/wp/v2/plugins', {
_fields: [ 'author', 'name', 'plugin', 'status', 'version' ],
} ),
} );

if ( hasUnmounted.current === true ) {
Expand All @@ -76,17 +61,11 @@ export function PluginsContextProvider( {
}

setError( e );

if ( hasErrorBoundary ) {
setAsyncError( e );
}

return;
}

setFetchingPlugins( false );
} )();
}, [ error, fetchingPlugins, hasErrorBoundary, plugins, setAsyncError, setError ] );
}, [ error, fetchingPlugins, plugins ] );

return (
<Plugins.Provider
Expand All @@ -101,5 +80,4 @@ export function PluginsContextProvider( {
}
PluginsContextProvider.propTypes = {
children: PropTypes.any,
hasErrorBoundary: PropTypes.bool,
};
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function PluginsWithAmpIncompatibility( {
<SiteScanSourcesList
sources={ sources }
inactiveSourceNotice={ __( 'This plugin has been deactivated since last site scan.' ) }
uninstalledSourceNotice={ __( 'This plugin has been uninstalled since last site scan.' ) }
uninstalledSourceNotice={ __( 'This plugin has been uninstalled or its metadata is unavailable.' ) }
/>
</SiteScanResults>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function ThemesWithAmpIncompatibility( {
<SiteScanSourcesList
sources={ sources }
inactiveSourceNotice={ __( 'This theme has been deactivated since last site scan.' ) }
uninstalledSourceNotice={ __( 'This theme has been uninstalled since last site scan.' ) }
uninstalledSourceNotice={ __( 'This theme has been uninstalled or its metadata is unavailable.' ) }
/>
</SiteScanResults>
);
Expand Down
42 changes: 10 additions & 32 deletions assets/src/components/themes-context-provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,22 @@ import PropTypes from 'prop-types';
/**
* WordPress dependencies
*/
import {
createContext,
useContext,
useEffect,
useRef,
useState,
} from '@wordpress/element';
import { createContext, useEffect, useRef, useState } from '@wordpress/element';
import apiFetch from '@wordpress/api-fetch';

/**
* Internal dependencies
*/
import { ErrorContext } from '../error-context-provider';
import { useAsyncError } from '../../utils/use-async-error';
import { addQueryArgs } from '@wordpress/url';

export const Themes = createContext();

/**
* Themes context provider.
*
* @param {Object} props Component props.
* @param {any} props.children Component children.
* @param {boolean} props.hasErrorBoundary Whether the component is wrapped in an error boundary.
* @param {Object} props Component props.
* @param {any} props.children Component children.
*/
export function ThemesContextProvider( {
children,
hasErrorBoundary = false,
} ) {
export function ThemesContextProvider( { children } ) {
const [ themes, setThemes ] = useState( [] );
const [ fetchingThemes, setFetchingThemes ] = useState( null );

const { error, setError } = useContext( ErrorContext );
const { setAsyncError } = useAsyncError();
const [ error, setError ] = useState();

/**
* This component sets state inside async functions.
Expand All @@ -62,7 +45,9 @@ export function ThemesContextProvider( {

try {
const fetchedThemes = await apiFetch( {
path: '/wp/v2/themes',
path: addQueryArgs( '/wp/v2/themes', {
_fields: [ 'author', 'name', 'status', 'stylesheet', 'version' ],
} ),
} );

if ( hasUnmounted.current === true ) {
Expand All @@ -76,17 +61,11 @@ export function ThemesContextProvider( {
}

setError( e );

if ( hasErrorBoundary ) {
setAsyncError( e );
}

return;
}

setFetchingThemes( false );
} )();
}, [ error, fetchingThemes, hasErrorBoundary, themes, setAsyncError, setError ] );
}, [ error, fetchingThemes, themes ] );

return (
<Themes.Provider
Expand All @@ -101,5 +80,4 @@ export function ThemesContextProvider( {
}
ThemesContextProvider.propTypes = {
children: PropTypes.any,
hasErrorBoundary: PropTypes.bool,
};
4 changes: 2 additions & 2 deletions assets/src/onboarding-wizard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ export function Providers( { children } ) {
userOptionDeveloperTools={ USER_FIELD_DEVELOPER_TOOLS_ENABLED }
usersResourceRestPath={ USERS_RESOURCE_REST_PATH }
>
<PluginsContextProvider hasErrorBoundary={ true }>
<ThemesContextProvider hasErrorBoundary={ true }>
<PluginsContextProvider>
<ThemesContextProvider>
<SiteScanContextProvider
fetchCachedValidationErrors={ false }
resetOnOptionsChange={ false }
Expand Down
8 changes: 5 additions & 3 deletions assets/src/settings-page/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ function Providers( { children } ) {
updatesNonce={ UPDATES_NONCE }
wpAjaxUrl={ wpAjaxUrl }
>
<PluginsContextProvider hasErrorBoundary={ true }>
<ThemesContextProvider hasErrorBoundary={ true }>
<PluginsContextProvider>
<ThemesContextProvider>
<SiteScanContextProvider
fetchCachedValidationErrors={ true }
resetOnOptionsChange={ true }
Expand Down Expand Up @@ -277,7 +277,9 @@ function Root( { appRoot } ) {
initialOpen={ 'other-settings' === focusedSection }
>
<MobileRedirection />
<DeveloperTools />
{ HAS_DEPENDENCY_SUPPORT && (
<DeveloperTools />
) }
<DeleteDataAtUninstall />
</AMPDrawer>
<SettingsFooter />
Expand Down
35 changes: 35 additions & 0 deletions includes/admin/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
* @package AMP
*/

use AmpProject\AmpWP\DependencySupport;
use AmpProject\AmpWP\Option;
use AmpProject\AmpWP\QueryVar;
use AmpProject\AmpWP\Services;

/**
* Sets up the AMP template editor for the Customizer.
Expand All @@ -15,6 +17,39 @@
*/
function amp_init_customizer() {

if ( ! Services::get( 'dependency_support' )->has_support() ) {
// @codeCoverageIgnoreStart
add_action(
'customize_controls_init',
static function () {
global $wp_customize;
if (
Services::get( 'reader_theme_loader' )->is_theme_overridden()
||
array_intersect( $wp_customize->get_autofocus(), [ 'panel' => AMP_Template_Customizer::PANEL_ID ] )
||
isset( $_GET[ QueryVar::AMP_PREVIEW ] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
) {
wp_die(
esc_html(
sprintf(
/* translators: %s is minimum WordPress version */
__( 'Customizer for AMP is unavailable due to WordPress being out of date. Please upgrade to WordPress %s or greater.', 'amp' ),
DependencySupport::WP_MIN_VERSION
)
),
esc_html__( 'AMP Customizer Unavailable', 'amp' ),
[
'response' => 503,
'back_link' => true,
]
);
}
}
);
// @codeCoverageIgnoreEnd
}

// Fire up the AMP Customizer.
add_action( 'customize_register', [ AMP_Template_Customizer::class, 'init' ], 500 );

Expand Down
34 changes: 34 additions & 0 deletions includes/amp-helper-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ function amp_bootstrap_plugin() {
// Ensure async and custom-element/custom-template attributes are present on script tags.
add_filter( 'script_loader_tag', 'amp_filter_script_loader_tag', PHP_INT_MAX, 2 );

// Ensure ID attribute is present in WP<5.5.
if ( version_compare( get_bloginfo( 'version' ), '5.5', '<' ) ) {
add_filter( 'script_loader_tag', 'amp_ensure_id_attribute_on_script_loader_tag', ~PHP_INT_MAX, 2 );
}

// Ensure crossorigin=anonymous is added to font links.
add_filter( 'style_loader_tag', 'amp_filter_font_style_loader_tag_with_crossorigin_anonymous', 10, 4 );

Expand Down Expand Up @@ -1157,6 +1162,35 @@ function amp_filter_script_loader_tag( $tag, $handle ) {
return $tag;
}

/**
* Ensure ID attribute is added to printed scripts.
*
* Core started adding the ID attribute in WP 5.5. This attribute is used both by validation logic for sourcing
* attribution as well as in the script and comments sanitizers.
*
* @link https://core.trac.wordpress.org/changeset/48295
* @since 2.2
* @internal
*
* @param string $tag The script tag for the enqueued script.
* @param string $handle The script's registered handle.
* @return string Filtered script.
*/
function amp_ensure_id_attribute_on_script_loader_tag( $tag, $handle ) {
$tag = preg_replace_callback(
'/(<script[^>]*?\ssrc=(["\']).*?\2)([^>]*?>)/',
static function ( $matches ) use ( $handle ) {
if ( false === strpos( $matches[0], 'id=' ) ) {
return $matches[1] . sprintf( ' id="%s"', esc_attr( "$handle-js" ) ) . $matches[3];
}
return $matches[0];
},
$tag,
1
);
return $tag;
}

/**
* Explicitly opt-in to CORS mode by adding the crossorigin attribute to font stylesheet links.
*
Expand Down
4 changes: 4 additions & 0 deletions includes/settings/class-amp-customizer-design-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

use AmpProject\AmpWP\Option;
use AmpProject\AmpWP\Services;

/**
* Class AMP_Customizer_Design_Settings
Expand Down Expand Up @@ -72,6 +73,9 @@ public static function init() {
* Init customizer.
*/
public static function init_customizer() {
if ( ! Services::get( 'dependency_support' )->has_support() ) {
return;
}
add_action( 'amp_customizer_register_settings', [ __CLASS__, 'register_customizer_settings' ] );
add_action( 'amp_customizer_register_ui', [ __CLASS__, 'register_customizer_ui' ] );
add_action( 'amp_customizer_enqueue_preview_scripts', [ __CLASS__, 'enqueue_customizer_preview_scripts' ] );
Expand Down
Loading

0 comments on commit 27a2104

Please sign in to comment.