From bb506c39a57492f3bb6d02e236005af9c2c66841 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 8 Jun 2019 13:04:16 -0700 Subject: [PATCH 01/21] Always allow switching themes with built-in Transitional support to Native Fixes #2312 --- includes/class-amp-theme-support.php | 114 ++++++++++++++- includes/options/class-amp-options-menu.php | 145 ++++++++++---------- tests/test-class-amp-theme-support.php | 49 +++++-- 3 files changed, 220 insertions(+), 88 deletions(-) diff --git a/includes/class-amp-theme-support.php b/includes/class-amp-theme-support.php index 974efd31beb..5799213da40 100644 --- a/includes/class-amp-theme-support.php +++ b/includes/class-amp-theme-support.php @@ -54,6 +54,22 @@ class AMP_Theme_Support { */ const CACHE_MISS_URL_OPTION = 'amp_cache_miss_url'; + /** + * Slug identifying native mode. + * + * @since 1.2 + * @var string + */ + const NATIVE_MODE_SLUG = 'native'; + + /** + * Slug identifying transitional mode. + * + * @since 1.2 + * @var string + */ + const TRANSITIONAL_MODE_SLUG = 'paired'; + /** * Sanitizer classes. * @@ -110,12 +126,23 @@ class AMP_Theme_Support { protected static $is_output_buffering = false; /** - * Theme support options that were added via option. + * Theme support mode that was added via option. + * + * This should be either null (reader), 'native', or 'transitional'. * * @since 1.0 - * @var bool + * @var null|string */ - protected static $support_added_via_option = false; + protected static $support_added_via_option = null; + + /** + * Theme support mode which was added via the theme. + * + * This should be either null (reader), 'native', or 'transitional'. + * + * @var null|string + */ + protected static $support_added_via_theme = null; /** * Initialize. @@ -159,22 +186,78 @@ function () { * * @since 1.0 * @see AMP_Theme_Support::read_theme_support() + * @see AMP_Theme_Support::get_support_mode() + * @deprecated Use AMP_Theme_Support::get_support_mode_added_via_option(). * * @return bool Support added via option. */ public static function is_support_added_via_option() { + _deprecated_function( __METHOD__, '1.2', 'AMP_Theme_Support::get_support_mode_added_via_option' ); + return null !== self::$support_added_via_option; + } + + /** + * Get the theme support mode added via admin option. + * + * @since 1.2 + * @see AMP_Theme_Support::read_theme_support() + * @see AMP_Theme_Support::TRANSITIONAL_MODE_SLUG + * @see AMP_Theme_Support::NATIVE_MODE_SLUG + * + * @return null|string Support added via option, with null meaning Reader, and otherwise being 'native' or 'paired'. + */ + public static function get_support_mode_added_via_option() { return self::$support_added_via_option; } + /** + * Get the theme support mode added via admin option. + * + * @since 1.2 + * @see AMP_Theme_Support::read_theme_support() + * @see AMP_Theme_Support::TRANSITIONAL_MODE_SLUG + * @see AMP_Theme_Support::NATIVE_MODE_SLUG + * + * @return null|string Support added via option, with null meaning Reader, and otherwise being 'native' or 'paired'. + */ + public static function get_support_mode_added_via_theme() { + return self::$support_added_via_theme; + } + + /** + * Get theme support mode. + * + * @since 1.2 + * @see AMP_Theme_Support::read_theme_support() + * @see AMP_Theme_Support::TRANSITIONAL_MODE_SLUG + * @see AMP_Theme_Support::NATIVE_MODE_SLUG + * + * @return string Theme support mode. + */ + public static function get_support_mode() { + $theme_support = self::get_support_mode_added_via_option(); + if ( ! $theme_support ) { + $theme_support = self::get_support_mode_added_via_theme(); + } + if ( ! $theme_support ) { + $theme_support = 'disabled'; + } + return $theme_support; + } + /** * Check theme support args or add theme support if option is set in the admin. * * The DB option is only considered if the theme does not already explicitly support AMP. * - * @see AMP_Theme_Support::is_support_added_via_option() + * @see AMP_Theme_Support::get_support_mode_added_via_theme() + * @see AMP_Theme_Support::get_support_mode_added_via_option() * @see AMP_Post_Type_Support::add_post_type_support() For where post type support is added, since it is irrespective of theme support. */ public static function read_theme_support() { + self::$support_added_via_theme = null; + self::$support_added_via_option = null; + $theme_support_option = AMP_Options_Manager::get_option( 'theme_support' ); if ( current_theme_supports( self::SLUG ) ) { $args = self::get_theme_support_args(); @@ -209,16 +292,33 @@ public static function read_theme_support() { '1.0' ); } - self::$support_added_via_option = false; + + $is_paired = ! empty( $args['paired'] ); + + self::$support_added_via_theme = $is_paired ? self::TRANSITIONAL_MODE_SLUG : self::NATIVE_MODE_SLUG; + + /* + * If the theme has transitional support, allow the user to opt for native mode via an option, since a theme + * in transitional mode entails that it supports serving templates as both AMP and non-AMP, and this it is + * able to serve AMP-first pages just as well as paired pages. Otherwise, consider that the the mode was + * not set at all via option. + */ + self::$support_added_via_option = ( $is_paired && self::NATIVE_MODE_SLUG === $theme_support_option ) ? self::NATIVE_MODE_SLUG : null; + if ( self::NATIVE_MODE_SLUG === self::$support_added_via_option ) { + $args['paired'] = false; + add_theme_support( 'amp', $args ); + } } elseif ( 'disabled' !== $theme_support_option ) { + $is_paired = ( 'paired' === $theme_support_option ); add_theme_support( self::SLUG, array( - 'paired' => ( 'paired' === $theme_support_option ), + 'paired' => $is_paired, ) ); - self::$support_added_via_option = true; + self::$support_added_via_option = $is_paired ? self::TRANSITIONAL_MODE_SLUG : self::NATIVE_MODE_SLUG; } elseif ( AMP_Validation_Manager::is_theme_support_forced() ) { + self::$support_added_via_option = self::NATIVE_MODE_SLUG; add_theme_support( self::SLUG ); } } diff --git a/includes/options/class-amp-options-menu.php b/includes/options/class-amp-options-menu.php index 0fe5726f5d8..4e80ace656e 100644 --- a/includes/options/class-amp-options-menu.php +++ b/includes/options/class-amp-options-menu.php @@ -149,33 +149,27 @@ public function add_menu_items() { * @since 1.0 */ public function render_theme_support() { - $theme_support = AMP_Options_Manager::get_option( 'theme_support' ); + $theme_support = AMP_Theme_Support::get_support_mode(); /* translators: %s: URL to the documentation. */ - $native_description = sprintf( __( 'Integrates AMP as the framework for your site by using the active’s theme templates and styles to render AMP responses. This means your site is AMP-first and your canonical URLs are AMP! Depending on your theme/plugins, a varying level of development work may be required.', 'amp' ), esc_url( 'https://amp-wp.org/documentation/developing-wordpress-amp-sites/' ) ); + $native_description = sprintf( __( 'The active theme integrates AMP as the framework for your site by using its templates and styles to render webpages. This means your site is AMP-first and your canonical URLs are AMP! Depending on your theme/plugins, a varying level of development work may be required.', 'amp' ), esc_url( 'https://amp-wp.org/documentation/developing-wordpress-amp-sites/' ) ); /* translators: %s: URL to the documentation. */ - $transitional_description = sprintf( __( 'Uses the active theme’s templates to generate non-AMP and AMP versions of your content, allowing for each canonical URL to have a corresponding (paired) AMP URL. This mode is useful to progressively transition towards a fully AMP-first site. Depending on your theme/plugins, a varying level of development work may be required.', 'amp' ), esc_url( 'https://amp-wp.org/documentation/developing-wordpress-amp-sites/' ) ); + $transitional_description = sprintf( __( 'The active theme’s templates are used to generate non-AMP and AMP versions of your content, allowing for each canonical URL to have a corresponding (paired) AMP URL. This mode is useful to progressively transition towards a fully AMP-first site. Depending on your theme/plugins, a varying level of development work may be required.', 'amp' ), esc_url( 'https://amp-wp.org/documentation/developing-wordpress-amp-sites/' ) ); $reader_description = __( 'Formerly called the classic mode, this mode generates paired AMP content using simplified templates which may not match the look-and-feel of your site. Only posts/pages can be served as AMP in Reader mode. No redirection is performed for mobile visitors; AMP pages are served by AMP consumption platforms.', 'amp' ); /* translators: %s: URL to the ecosystem page. */ $ecosystem_description = sprintf( __( 'For a list of themes and plugins that are known to be AMP compatible, please see the ecosystem page.' ), esc_url( 'https://amp-wp.org/ecosystem/' ) ); $builtin_support = in_array( get_template(), AMP_Core_Theme_Sanitizer::get_supported_themes(), true ); ?> - +

- +

- - - - - - - +

> @@ -184,12 +178,15 @@ public function render_theme_support() {

-

- -

+ + +

+ +

+
- > + > @@ -198,7 +195,7 @@ public function render_theme_support() {
- > + > @@ -206,49 +203,57 @@ public function render_theme_support() {
-
- > - -
-
- - - publish > 0 ) : ?> -
-

- +

+ > + +
+
+ + + publish > 0 ) : ?> +
+

+ %s', - esc_url( add_query_arg( 'post_type', AMP_Validated_URL_Post_Type::POST_TYPE_SLUG, admin_url( 'edit.php' ) ) ), - esc_html( get_post_type_object( AMP_Validated_URL_Post_Type::POST_TYPE_SLUG )->labels->name ) - ), - sprintf( - '%s', - esc_url( - add_query_arg( - array( - 'taxonomy' => AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG, - 'post_type' => AMP_Validated_URL_Post_Type::POST_TYPE_SLUG, - ), - admin_url( 'edit-tags.php' ) - ) + /* translators: %1: link to invalid URLs. 2: link to validation errors. */ + __( 'View current site compatibility results for native and transitional modes: %1$s and %2$s.', 'amp' ), + sprintf( + '%s', + esc_url( add_query_arg( 'post_type', AMP_Validated_URL_Post_Type::POST_TYPE_SLUG, admin_url( 'edit.php' ) ) ), + esc_html( get_post_type_object( AMP_Validated_URL_Post_Type::POST_TYPE_SLUG )->labels->name ) ), - esc_html( get_taxonomy( AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG )->labels->name ) + sprintf( + '%s', + esc_url( + add_query_arg( + array( + 'taxonomy' => AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG, + 'post_type' => AMP_Validated_URL_Post_Type::POST_TYPE_SLUG, + ), + admin_url( 'edit-tags.php' ) + ) + ), + esc_html( get_taxonomy( AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG )->labels->name ) + ) ) - ) - ); - ?> -

-
- -
+ ); + ?> +

+ + + +
+ + +

+ +

+
// Update the visibility of the fieldsets based on the selected template mode and then whether all templates are indicated to be supported. (function ( $ ) { - var templateModeInputs, themeSupportDisabledInput, allTemplatesSupportedInput, supportForced; - templateModeInputs = $( 'input[type=radio][name="amp-options[theme_support]"]' ); - themeSupportDisabledInput = $( '#theme_support_disabled' ); - allTemplatesSupportedInput = $( '#all_templates_supported' ); - supportForced = ; + const templateModeInputs = $( 'input[type=radio][name="amp-options[theme_support]"]' ); + const themeSupportDisabledInput = $( '#theme_support_disabled' ); + const allTemplatesSupportedInput = $( '#all_templates_supported' ); function isThemeSupportDisabled() { - return ! supportForced && themeSupportDisabledInput.prop( 'checked' ); + return Boolean( themeSupportDisabledInput.length && themeSupportDisabledInput.prop( 'checked' ) ); } function updateFieldsetVisibility() { - var allTemplatesSupported = 0 === allTemplatesSupportedInput.length || allTemplatesSupportedInput.prop( 'checked' ); + const allTemplatesSupported = 0 === allTemplatesSupportedInput.length || allTemplatesSupportedInput.prop( 'checked' ); $( '#all_templates_supported_fieldset, #supported_post_types_fieldset > .title' ).toggleClass( 'hidden', isThemeSupportDisabled() diff --git a/tests/test-class-amp-theme-support.php b/tests/test-class-amp-theme-support.php index 03f0011f595..b0bd58916f7 100644 --- a/tests/test-class-amp-theme-support.php +++ b/tests/test-class-amp-theme-support.php @@ -120,40 +120,69 @@ public function test_read_theme_support_bad_available_callback() { * Test read_theme_support, get_theme_support_args, and is_support_added_via_option. * * @covers \AMP_Theme_Support::read_theme_support() - * @covers \AMP_Theme_Support::is_support_added_via_option() + * @covers \AMP_Theme_Support::get_support_mode_added_via_option() + * @covers \AMP_Theme_Support::get_support_mode_added_via_theme() + * @covers \AMP_Theme_Support::get_support_mode() * @covers \AMP_Theme_Support::get_theme_support_args() */ public function test_read_theme_support_and_support_args() { - // Test with option set, but some configs supplied via theme support. - AMP_Options_Manager::update_option( 'theme_support', 'native' ); // Will be ignored since theme support flag set. + // Test that native via option trumps transitional in theme. $args = array( 'templates_supported' => 'all', 'paired' => true, 'comments_live_list' => true, ); add_theme_support( AMP_Theme_Support::SLUG, $args ); + AMP_Options_Manager::update_option( 'theme_support', AMP_Theme_Support::NATIVE_MODE_SLUG ); // Will override the theme support flag. AMP_Theme_Support::read_theme_support(); - $this->assertEquals( $args, AMP_Theme_Support::get_theme_support_args() ); - $this->assertFalse( AMP_Theme_Support::is_support_added_via_option() ); + $this->assertEquals( + array_merge( + $args, + array( + 'paired' => false, // The 'native' user option overrides the theme flag. + ) + ), + AMP_Theme_Support::get_theme_support_args() + ); + $this->assertSame( AMP_Theme_Support::NATIVE_MODE_SLUG, AMP_Theme_Support::get_support_mode_added_via_option() ); + $this->assertSame( AMP_Theme_Support::TRANSITIONAL_MODE_SLUG, AMP_Theme_Support::get_support_mode_added_via_theme() ); + $this->assertSame( AMP_Theme_Support::NATIVE_MODE_SLUG, AMP_Theme_Support::get_support_mode() ); $this->assertTrue( current_theme_supports( AMP_Theme_Support::SLUG ) ); + // Test that native via theme always trumps transitional via option. add_theme_support( AMP_Theme_Support::SLUG ); + AMP_Options_Manager::update_option( 'theme_support', AMP_Theme_Support::TRANSITIONAL_MODE_SLUG ); // Will be ignored since native in theme overrides transitional option. + AMP_Theme_Support::read_theme_support(); $this->assertTrue( current_theme_supports( AMP_Theme_Support::SLUG ) ); - $this->assertFalse( AMP_Theme_Support::is_support_added_via_option() ); + $this->assertNull( AMP_Theme_Support::get_support_mode_added_via_option() ); + $this->assertSame( AMP_Theme_Support::NATIVE_MODE_SLUG, AMP_Theme_Support::get_support_mode_added_via_theme() ); + $this->assertSame( AMP_Theme_Support::NATIVE_MODE_SLUG, AMP_Theme_Support::get_support_mode() ); $this->assertEquals( array( 'paired' => false ), AMP_Theme_Support::get_theme_support_args() ); + // Test that no support via theme can be overridden with option. + remove_theme_support( AMP_Theme_Support::SLUG ); + AMP_Options_Manager::update_option( 'theme_support', AMP_Theme_Support::NATIVE_MODE_SLUG ); + AMP_Theme_Support::read_theme_support(); + $this->assertNull( AMP_Theme_Support::get_support_mode_added_via_theme() ); + $this->assertSame( AMP_Theme_Support::NATIVE_MODE_SLUG, AMP_Theme_Support::get_support_mode_added_via_option() ); + $this->assertTrue( current_theme_supports( AMP_Theme_Support::SLUG ) ); + + // Test that no support via theme can be overridden with option. remove_theme_support( AMP_Theme_Support::SLUG ); - AMP_Options_Manager::update_option( 'theme_support', 'native' ); // Will be ignored since theme support flag set. + AMP_Options_Manager::update_option( 'theme_support', AMP_Theme_Support::TRANSITIONAL_MODE_SLUG ); AMP_Theme_Support::read_theme_support(); - $this->assertTrue( AMP_Theme_Support::is_support_added_via_option() ); + $this->assertNull( AMP_Theme_Support::get_support_mode_added_via_theme() ); + $this->assertSame( AMP_Theme_Support::TRANSITIONAL_MODE_SLUG, AMP_Theme_Support::get_support_mode_added_via_option() ); $this->assertTrue( current_theme_supports( AMP_Theme_Support::SLUG ) ); + // Test that forced validation works. remove_theme_support( AMP_Theme_Support::SLUG ); - AMP_Options_Manager::update_option( 'theme_support', 'disabled' ); + delete_option( AMP_Options_Manager::OPTION_NAME ); $_GET[ AMP_Validation_Manager::VALIDATE_QUERY_VAR ] = AMP_Validation_Manager::get_amp_validate_nonce(); AMP_Theme_Support::read_theme_support(); - $this->assertTrue( AMP_Theme_Support::is_support_added_via_option() ); + $this->assertSame( AMP_Theme_Support::NATIVE_MODE_SLUG, AMP_Theme_Support::get_support_mode_added_via_option() ); + $this->assertNull( AMP_Theme_Support::get_support_mode_added_via_theme() ); $this->assertTrue( get_theme_support( AMP_Theme_Support::SLUG ) ); } From 7952fce3787f77651d8146c32e49468acf54953d Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 8 Jun 2019 16:51:25 -0700 Subject: [PATCH 02/21] Prevent AMP validation from appearing in Reader mode on non-Story posts Fixes #2311 --- .../class-amp-validation-manager.php | 129 +++++++++++++----- tests/test-class-amp-theme-support.php | 1 + ...st-class-amp-validation-error-taxonomy.php | 1 + .../test-class-amp-validation-manager.php | 100 +++++++++++++- 4 files changed, 193 insertions(+), 38 deletions(-) diff --git a/includes/validation/class-amp-validation-manager.php b/includes/validation/class-amp-validation-manager.php index d81c347264b..583e9821d61 100644 --- a/includes/validation/class-amp-validation-manager.php +++ b/includes/validation/class-amp-validation-manager.php @@ -179,32 +179,34 @@ public static function init( $args = array() ) { add_action( 'save_post', array( __CLASS__, 'handle_save_post_prompting_validation' ) ); add_action( 'enqueue_block_editor_assets', array( __CLASS__, 'enqueue_block_validation' ) ); - add_action( 'edit_form_top', array( __CLASS__, 'print_edit_form_validation_status' ), 10, 2 ); - add_action( 'all_admin_notices', array( __CLASS__, 'print_plugin_notice' ) ); - add_action( 'rest_api_init', array( __CLASS__, 'add_rest_api_fields' ) ); - // Actions and filters involved in validation. - add_action( - 'activate_plugin', - function() { - if ( ! has_action( 'shutdown', array( __CLASS__, 'validate_after_plugin_activation' ) ) ) { - add_action( 'shutdown', array( __CLASS__, 'validate_after_plugin_activation' ) ); // Shutdown so all plugins will have been activated. + // Add actions for checking theme support is present to determine plugin compatibility and show validation links in the admin bar. + if ( current_theme_supports( AMP_Theme_Support::SLUG ) ) { + // Actions and filters involved in validation. + add_action( + 'activate_plugin', + function() { + if ( ! has_action( 'shutdown', array( __CLASS__, 'validate_after_plugin_activation' ) ) ) { + add_action( 'shutdown', array( __CLASS__, 'validate_after_plugin_activation' ) ); // Shutdown so all plugins will have been activated. + } } - } - ); + ); - // Prevent query vars from persisting after redirect. - add_filter( - 'removable_query_args', - function( $query_vars ) { - $query_vars[] = AMP_Validation_Manager::VALIDATION_ERRORS_QUERY_VAR; - return $query_vars; - } - ); + // Prevent query vars from persisting after redirect. + add_filter( + 'removable_query_args', + function( $query_vars ) { + $query_vars[] = AMP_Validation_Manager::VALIDATION_ERRORS_QUERY_VAR; + return $query_vars; + } + ); - add_action( 'admin_bar_menu', array( __CLASS__, 'add_admin_bar_menu_items' ), 101 ); + add_action( 'all_admin_notices', array( __CLASS__, 'print_plugin_notice' ) ); + + add_action( 'admin_bar_menu', array( __CLASS__, 'add_admin_bar_menu_items' ), 101 ); + } if ( self::$should_locate_sources ) { /* @@ -220,6 +222,49 @@ function( $query_vars ) { } } + /** + * Determine if a post supports AMP validation. + * + * @since 1.2 + * + * @param WP_Post|int $post Post. + * @return bool Whether post supports AMP validation. + */ + public static function post_supports_validation( $post ) { + $post = get_post( $post ); + if ( ! $post ) { + return false; + } + + $supports_validation = ( + // Skip if the post type is not viewable on the frontend, since we need a permalink to validate. + is_post_type_viewable( $post->post_type ) + && + ! wp_is_post_autosave( $post ) + && + ! wp_is_post_revision( $post ) + && + 'auto-draft' !== $post->post_status + && + 'trash' !== $post->post_status + ); + if ( ! $supports_validation ) { + return false; + } + + // Story post type always supports validation. + if ( AMP_Story_Post_Type::POST_TYPE_SLUG === $post->post_type ) { + return true; + } + + // Prevent doing post validation in Reader mode. + if ( ! current_theme_supports( AMP_Theme_Support::SLUG ) ) { + return false; + } + + return post_supports_amp( $post ); + } + /** * Determine whether AMP theme support is forced via the amp_validate query param. * @@ -515,13 +560,7 @@ public static function handle_save_post_prompting_validation( $post_id ) { $should_validate_post = ( $is_classic_editor_post_save && - is_post_type_viewable( $post->post_type ) - && - ! wp_is_post_autosave( $post ) - && - ! wp_is_post_revision( $post ) - && - 'auto-draft' !== $post->post_status + self::post_supports_validation( $post ) && ! isset( self::$posts_pending_frontend_validation[ $post_id ] ) ); @@ -546,7 +585,7 @@ public static function validate_queued_posts_on_frontend() { $posts = array_filter( array_map( 'get_post', array_keys( array_filter( self::$posts_pending_frontend_validation ) ) ), function( $post ) { - return $post && post_supports_amp( $post ) && 'trash' !== $post->post_status; + return self::post_supports_validation( $post ); } ); @@ -599,8 +638,10 @@ function( $post ) { * @return void */ public static function add_rest_api_fields() { - if ( amp_is_canonical() ) { - $object_types = get_post_types_by_support( 'editor' ); + if ( ! current_theme_supports( AMP_Theme_Support::SLUG ) ) { + $object_types = array( AMP_Story_Post_Type::POST_TYPE_SLUG ); // Eventually validation should be done in Reader mode as well, but for now, limit to stories. + } elseif ( amp_is_canonical() ) { + $object_types = get_post_types_by_support( 'editor' ); // @todo Shouldn't this actually only be those with 'amp' support, or if if all_templates_supported? } else { $object_types = array_intersect( get_post_types_by_support( 'amp' ), @@ -638,7 +679,7 @@ public static function add_rest_api_fields() { */ public static function get_amp_validity_rest_field( $post_data, $field_name, $request ) { unset( $field_name ); - if ( ! current_user_can( 'edit_post', $post_data['id'] ) ) { + if ( ! current_user_can( 'edit_post', $post_data['id'] ) || ! self::has_cap() || ! self::post_supports_validation( $post_data['id'] ) ) { return null; } $post = get_post( $post_data['id'] ); @@ -794,12 +835,7 @@ public static function reset_validation_results() { * @return void */ public static function print_edit_form_validation_status( $post ) { - if ( ! post_supports_amp( $post ) || ! self::has_cap() ) { - return; - } - - // Skip if the post type is not viewable on the frontend, since we need a permalink to validate. - if ( ! is_post_type_viewable( $post->post_type ) ) { + if ( ! self::post_supports_validation( $post ) || ! self::has_cap() ) { return; } @@ -1955,6 +1991,25 @@ public static function print_plugin_notice() { * @return void */ public static function enqueue_block_validation() { + /* + * The AMP_Validation_Manager::post_supports_validation() method is not being used here because + * a post's status for validation checking can change during the life of the editor, such as when + * the user to toggle AMP back on after having turned it off, and then get the validation + * warnings appearing due to the amp-block-validation having been enqueued already. + */ + $should_enqueue_block_validation = ( + self::has_cap() + && + ( + current_theme_supports( AMP_Theme_Support::SLUG ) + || + AMP_Story_Post_Type::POST_TYPE_SLUG === get_post_type() + ) + ); + if ( ! $should_enqueue_block_validation ) { + return; + } + $slug = 'amp-block-validation'; $script_deps_path = AMP__DIR__ . '/assets/js/' . $slug . '.deps.json'; diff --git a/tests/test-class-amp-theme-support.php b/tests/test-class-amp-theme-support.php index b0bd58916f7..29144920eff 100644 --- a/tests/test-class-amp-theme-support.php +++ b/tests/test-class-amp-theme-support.php @@ -36,6 +36,7 @@ public function setUp() { AMP_Validation_Manager::reset_validation_results(); unset( $GLOBALS['current_screen'] ); remove_theme_support( AMP_Theme_Support::SLUG ); + AMP_Theme_Support::read_theme_support(); } /** diff --git a/tests/validation/test-class-amp-validation-error-taxonomy.php b/tests/validation/test-class-amp-validation-error-taxonomy.php index 71b60881818..806461ff18b 100644 --- a/tests/validation/test-class-amp-validation-error-taxonomy.php +++ b/tests/validation/test-class-amp-validation-error-taxonomy.php @@ -32,6 +32,7 @@ class Test_AMP_Validation_Error_Taxonomy extends \WP_UnitTestCase { public function tearDown() { $_REQUEST = array(); remove_theme_support( AMP_Theme_Support::SLUG ); + AMP_Theme_Support::read_theme_support(); remove_filter( 'amp_validation_error_sanitized', '__return_true' ); remove_all_filters( 'amp_validation_error_sanitized' ); remove_all_filters( 'terms_clauses' ); diff --git a/tests/validation/test-class-amp-validation-manager.php b/tests/validation/test-class-amp-validation-manager.php index eff3f863dab..278b8dd31a9 100644 --- a/tests/validation/test-class-amp-validation-manager.php +++ b/tests/validation/test-class-amp-validation-manager.php @@ -98,6 +98,7 @@ public function setUp() { public function tearDown() { $GLOBALS['wp_registered_widgets'] = $this->original_wp_registered_widgets; remove_theme_support( AMP_Theme_Support::SLUG ); + AMP_Theme_Support::read_theme_support(); $_REQUEST = array(); unset( $GLOBALS['current_screen'] ); AMP_Validation_Manager::$should_locate_sources = false; @@ -143,6 +144,69 @@ public function test_init() { $this->assertEquals( 10, has_action( 'wp', array( self::TESTED_CLASS, 'wrap_widget_callbacks' ) ) ); } + /** + * Test init when theme support and stories support are not present. + * + * @covers AMP_Validation_Manager::init() + */ + public function test_init_without_theme_or_stories_support() { + AMP_Options_Manager::update_option( 'enable_amp_stories', false ); + remove_theme_support( AMP_Theme_Support::SLUG ); + AMP_Validation_Manager::init(); + + $this->assertFalse( has_action( 'save_post', array( 'AMP_Validation_Manager', 'handle_save_post_prompting_validation' ) ) ); + } + + /** + * Test init when theme support is absent but stories support is. + * + * @covers AMP_Validation_Manager::init() + */ + public function test_init_with_stories_and_without_theme_support() { + AMP_Options_Manager::update_option( 'enable_amp_stories', true ); + remove_theme_support( AMP_Theme_Support::SLUG ); + AMP_Validation_Manager::init(); + + $this->assertSame( 10, has_action( 'save_post', array( 'AMP_Validation_Manager', 'handle_save_post_prompting_validation' ) ) ); + $this->assertFalse( has_action( 'admin_bar_menu', array( self::TESTED_CLASS, 'add_admin_bar_menu_items' ) ) ); + } + + /** + * Test \AMP_Validation_Manager::post_supports_validation. + * + * @covers \AMP_Validation_Manager::post_supports_validation() + */ + public function test_post_supports_validation() { + + // Ensure that story posts can be validated even when theme support is absent. + remove_theme_support( AMP_Theme_Support::SLUG ); + AMP_Options_Manager::update_option( 'enable_amp_stories', true ); + AMP_Story_Post_Type::register(); + if ( post_type_exists( AMP_Story_Post_Type::POST_TYPE_SLUG ) ) { + $post = $this->factory()->post->create( array( 'post_type' => AMP_Story_Post_Type::POST_TYPE_SLUG ) ); + $this->assertTrue( AMP_Validation_Manager::post_supports_validation( $post ) ); + } + + // Support absent if theme support is absent for regular posts. + remove_theme_support( AMP_Theme_Support::SLUG ); + $this->assertFalse( AMP_Validation_Manager::post_supports_validation( $this->factory()->post->create() ) ); + + // Ensure normal case of validating published post when theme support present. + add_theme_support( AMP_Theme_Support::SLUG ); + $this->assertTrue( AMP_Validation_Manager::post_supports_validation( $this->factory()->post->create() ) ); + + // Trashed posts are not validatable. + $this->assertFalse( AMP_Validation_Manager::post_supports_validation( $this->factory()->post->create( array( 'post_status' => 'trash' ) ) ) ); + + // An invalid post is not previewable. + $this->assertFalse( AMP_Validation_Manager::post_supports_validation( 0 ) ); + + // Ensure non-viewable posts do not support validation. + register_post_type( 'not_viewable', array( 'publicly_queryable' => false ) ); + $post = $this->factory()->post->create( array( 'post_type' => 'not_viewable' ) ); + $this->assertFalse( AMP_Validation_Manager::post_supports_validation( $post ) ); + } + /** * Test add_validation_hooks. * @@ -282,6 +346,7 @@ public function test_add_validation_error_sourcing_gutenberg() { * @covers AMP_Validation_Manager::validate_queued_posts_on_frontend() */ public function test_handle_save_post_prompting_validation_and_validate_queued_posts_on_frontend() { + add_theme_support( AMP_Theme_Support::SLUG ); $_SERVER['REQUEST_METHOD'] = 'POST'; $GLOBALS['pagenow'] = 'post.php'; @@ -328,7 +393,10 @@ function() { * @covers AMP_Validation_Manager::add_rest_api_fields() */ public function test_add_rest_api_fields() { - // Test in a non Native-AMP (canonical) context. + + // Test in a transitional context. + add_theme_support( AMP_Theme_Support::SLUG, array( 'paired' => true ) ); + AMP_Theme_Support::read_theme_support(); AMP_Validation_Manager::add_rest_api_fields(); $post_types_non_canonical = array_intersect( get_post_types_by_support( 'amp' ), @@ -342,6 +410,7 @@ public function test_add_rest_api_fields() { // Test in a Native AMP (canonical) context. add_theme_support( AMP_Theme_Support::SLUG ); + AMP_Theme_Support::read_theme_support(); AMP_Validation_Manager::add_rest_api_fields(); $post_types_canonical = get_post_types_by_support( 'editor' ); $this->assert_rest_api_field_present( $post_types_canonical ); @@ -373,6 +442,7 @@ protected function assert_rest_api_field_present( $post_types ) { * @covers AMP_Validation_Manager::validate_url() */ public function test_get_amp_validity_rest_field() { + add_theme_support( AMP_Theme_Support::SLUG, array( 'paired' => true ) ); AMP_Options_Manager::update_option( 'auto_accept_sanitization', false ); AMP_Validated_URL_Post_Type::register(); AMP_Validation_Error_Taxonomy::register(); @@ -1386,6 +1456,7 @@ public function test_enqueue_block_validation() { $this->markTestSkipped( 'The block editor is not available.' ); } + add_theme_support( AMP_Theme_Support::SLUG ); global $post; $post = $this->factory()->post->create_and_get(); $slug = 'amp-block-validation'; @@ -1411,6 +1482,33 @@ public function test_enqueue_block_validation() { $this->assertContains( $slug, wp_scripts()->queue ); } + /** + * Test enqueue_block_validation. + * + * @covers AMP_Validation_Manager::enqueue_block_validation() + */ + public function test_enqueue_block_validation_without_amp_support() { + if ( ! function_exists( 'register_block_type' ) ) { + $this->markTestSkipped( 'The block editor is not available.' ); + } + + remove_theme_support( AMP_Theme_Support::SLUG ); + global $post; + $post = $this->factory()->post->create_and_get(); + $slug = 'amp-block-validation'; + $this->set_capability(); + AMP_Validation_Manager::enqueue_block_validation(); + $this->assertNotContains( $slug, wp_scripts()->queue ); + + AMP_Options_Manager::update_option( 'enable_amp_stories', true ); + AMP_Story_Post_Type::register(); + if ( post_type_exists( AMP_Story_Post_Type::POST_TYPE_SLUG ) ) { + $post = $this->factory()->post->create_and_get( array( 'post_type' => AMP_Story_Post_Type::POST_TYPE_SLUG ) ); + AMP_Validation_Manager::enqueue_block_validation(); + $this->assertContains( $slug, wp_scripts()->queue ); + } + } + /** * Processes markup, to determine AMP validity. * From a24e71556c100574e01d290bed78466f4c3de734 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 8 Jun 2019 16:55:19 -0700 Subject: [PATCH 03/21] Remove dead options from validated environment Amends ba158001e8fbb6a8d243f0eef729e0dc9c4715bf in #2508 --- .../validation/class-amp-validated-url-post-type.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/includes/validation/class-amp-validated-url-post-type.php b/includes/validation/class-amp-validated-url-post-type.php index e1383065443..ddcf3a3aa28 100644 --- a/includes/validation/class-amp-validated-url-post-type.php +++ b/includes/validation/class-amp-validated-url-post-type.php @@ -837,13 +837,6 @@ public static function get_post_staleness( $post ) { } } - if ( isset( $old_validated_environment['options'] ) ) { - $differing_options = array_diff_assoc( $new_validated_environment['options'], $old_validated_environment['options'] ); - if ( $differing_options ) { - $staleness['options'] = $differing_options; - } - } - return $staleness; } @@ -1751,10 +1744,6 @@ public static function print_status_meta_box( $post ) { esc_html_e( 'Different plugins were active when these results were obtained.', 'amp' ); echo ' '; } - if ( ! empty( $staleness['options'] ) ) { - esc_html_e( 'Options have changed.', 'amp' ); - echo ' '; - } esc_html_e( 'Please recheck.', 'amp' ); echo '

'; } From 0ba049577a8be47d93499b50d534b6d5d59b9c8b Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 8 Jun 2019 20:03:48 -0700 Subject: [PATCH 04/21] Move AMP Stories section setting right after template mode --- includes/options/class-amp-options-menu.php | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/includes/options/class-amp-options-menu.php b/includes/options/class-amp-options-menu.php index 4e80ace656e..3a2b7a2ff22 100644 --- a/includes/options/class-amp-options-menu.php +++ b/includes/options/class-amp-options-menu.php @@ -87,6 +87,17 @@ public function add_menu_items() { ) ); + add_settings_field( + 'amp_stories', + __( 'Stories', 'amp' ), + array( $this, 'render_amp_stories' ), + AMP_Options_Manager::OPTION_NAME, + 'general', + array( + 'class' => 'amp-stories-field', + ) + ); + add_settings_field( 'validation', __( 'Validation Handling', 'amp' ), @@ -109,17 +120,6 @@ public function add_menu_items() { ) ); - add_settings_field( - 'amp_stories', - __( 'Stories', 'amp' ), - array( $this, 'render_amp_stories' ), - AMP_Options_Manager::OPTION_NAME, - 'general', - array( - 'class' => 'amp-stories-field', - ) - ); - if ( wp_using_ext_object_cache() ) { add_settings_field( 'caching', From d7680cb9ac1449a1b9848ae294b2e5b7e1aeeecb Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Mon, 10 Jun 2019 07:16:11 -0700 Subject: [PATCH 05/21] Add AMP experiences checkboxes --- .../options/class-amp-options-manager.php | 46 ++++- includes/options/class-amp-options-menu.php | 180 ++++++++++++------ 2 files changed, 166 insertions(+), 60 deletions(-) diff --git a/includes/options/class-amp-options-manager.php b/includes/options/class-amp-options-manager.php index ab2bc8792a0..95d68941c11 100644 --- a/includes/options/class-amp-options-manager.php +++ b/includes/options/class-amp-options-manager.php @@ -17,12 +17,25 @@ class AMP_Options_Manager { */ const OPTION_NAME = 'amp-options'; + /** + * Slug for website experience. + */ + const WEBSITE_EXPERIENCE = 'website'; + + /** + * Slug for stories experience. + * + * @var + */ + const STORIES_EXPERIENCE = 'stories'; + /** * Default option values. * * @var array */ protected static $defaults = array( + 'experiences' => array( self::WEBSITE_EXPERIENCE ), 'theme_support' => 'disabled', 'supported_post_types' => array( 'post' ), 'analytics' => array(), @@ -30,7 +43,6 @@ class AMP_Options_Manager { 'all_templates_supported' => true, 'supported_templates' => array( 'is_singular' ), 'enable_response_caching' => true, - 'enable_amp_stories' => false, 'version' => AMP__VERSION, 'story_templates_version' => false, ); @@ -81,10 +93,19 @@ public static function maybe_flush_rewrite_rules( $old_options, $new_options ) { public static function get_options() { $options = get_option( self::OPTION_NAME, array() ); if ( empty( $options ) ) { - $options = array(); + $options = array(); // Ensure empty string becomes array. } self::$defaults['enable_response_caching'] = wp_using_ext_object_cache(); - return array_merge( self::$defaults, $options ); + + $options = array_merge( self::$defaults, $options ); + + // Migrate stories option from 1.2-beta. + if ( ! empty( $options['enable_amp_stories'] ) ) { + $options['experiences'][] = self::STORIES_EXPERIENCE; + unset( $options['enable_amp_stories'] ); + } + + return $options; } /** @@ -118,6 +139,24 @@ public static function validate_options( $new_options ) { return $options; } + // Experiences. + if ( isset( $new_options['experiences'] ) && is_array( $new_options['experiences'] ) ) { + + // Validate the selected experiences. + $options['experiences'] = array_intersect( + $new_options['experiences'], + array( + self::WEBSITE_EXPERIENCE, + self::STORIES_EXPERIENCE, + ) + ); + + // At least one experience must be selected. + if ( empty( $options['experiences'] ) ) { + $options['experiences'] = array( self::WEBSITE_EXPERIENCE ); + } + } + // Theme support. $recognized_theme_supports = array( 'disabled', @@ -134,7 +173,6 @@ public static function validate_options( $new_options ) { } $options['auto_accept_sanitization'] = ! empty( $new_options['auto_accept_sanitization'] ); - $options['enable_amp_stories'] = ! empty( $new_options['enable_amp_stories'] ); // Validate post type support. $options['supported_post_types'] = array(); diff --git a/includes/options/class-amp-options-menu.php b/includes/options/class-amp-options-menu.php index 3a2b7a2ff22..2067dfc9308 100644 --- a/includes/options/class-amp-options-menu.php +++ b/includes/options/class-amp-options-menu.php @@ -77,24 +77,24 @@ public function add_menu_items() { ); add_settings_field( - 'theme_support', - __( 'Template Mode', 'amp' ), - array( $this, 'render_theme_support' ), + 'experiences', + __( 'Experiences', 'amp' ), + array( $this, 'render_experiences' ), AMP_Options_Manager::OPTION_NAME, 'general', array( - 'class' => 'theme_support', + 'class' => 'experiences', ) ); add_settings_field( - 'amp_stories', - __( 'Stories', 'amp' ), - array( $this, 'render_amp_stories' ), + 'theme_support', + __( 'Website Mode', 'amp' ), + array( $this, 'render_theme_support' ), AMP_Options_Manager::OPTION_NAME, 'general', array( - 'class' => 'amp-stories-field', + 'class' => 'amp-website-mode', ) ); @@ -120,6 +120,21 @@ public function add_menu_items() { ) ); + add_action( + 'admin_print_styles', + function() { + ?> + + +
+
+
+ > + +
+
+ AMP Websites.', 'amp' ), + esc_url( 'https://amp.dev/about/websites' ) + ) + ); + ?> +
+
+ > + +
+
+ +
+

+ ' . $gutenberg . ''; + } + printf( + /* translators: %s: Gutenberg plugin name */ + esc_html__( 'To use stories, you currently must have the latest version of the %s plugin installed and activated.', 'amp' ), + $gutenberg // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ); + ?> +

+
+ + AMP Stories.', 'amp' ), + esc_url( 'https://amp.dev/about/stories' ) + ) + ); + ?> +
+
+ +
+ >
-

+

@@ -188,7 +302,7 @@ public function render_theme_support() {
>
@@ -469,52 +583,6 @@ function updateFieldsetVisibility() { - -
-

- ' . $gutenberg . ''; - } - printf( - /* translators: %s: Gutenberg plugin name */ - esc_html__( 'To use stories, you currently must have the latest version of the %s plugin installed and activated.', 'amp' ), - $gutenberg // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - ); - ?> -

-
- -

- -

-

- Stories.', 'amp' ), - esc_url( 'https://amp.dev/about/stories' ) - ) - ); - ?> -

- Date: Mon, 10 Jun 2019 12:36:03 -0700 Subject: [PATCH 06/21] Conditionally do functionality for website and stories of experienced enabled --- amp.php | 44 +++++++++--------- includes/admin/class-amp-admin-pointers.php | 4 +- includes/admin/functions.php | 2 +- includes/class-amp-story-post-type.php | 2 +- includes/class-amp-theme-support.php | 4 +- .../options/class-amp-options-manager.php | 45 ++++++++++++++++--- includes/options/class-amp-options-menu.php | 14 +++++- .../class-amp-validation-manager.php | 14 +++--- tests/test-class-amp-options-manager.php | 14 +++++- tests/test-class-amp-story-post-type.php | 16 ++++--- .../test-class-amp-validation-manager.php | 15 ++++++- 11 files changed, 125 insertions(+), 49 deletions(-) diff --git a/amp.php b/amp.php index 92c27a5a061..e0e1e3b10bc 100644 --- a/amp.php +++ b/amp.php @@ -333,38 +333,42 @@ function amp_init() { */ do_action( 'amp_init' ); - add_rewrite_endpoint( amp_get_slug(), EP_PERMALINK ); - add_filter( 'allowed_redirect_hosts', array( 'AMP_HTTP', 'filter_allowed_redirect_hosts' ) ); AMP_HTTP::purge_amp_query_vars(); AMP_HTTP::send_cors_headers(); AMP_HTTP::handle_xhr_request(); AMP_Theme_Support::init(); AMP_Validation_Manager::init(); - AMP_Post_Type_Support::add_post_type_support(); - AMP_Story_Post_Type::register(); AMP_Service_Worker::init(); - add_action( 'init', array( 'AMP_Post_Type_Support', 'add_post_type_support' ), 1000 ); // After post types have been defined. - - if ( defined( 'WP_CLI' ) && WP_CLI ) { - WP_CLI::add_command( 'amp', new AMP_CLI() ); - } - - add_filter( 'request', 'amp_force_query_var_value' ); add_action( 'admin_init', 'AMP_Options_Manager::register_settings' ); - add_action( 'wp_loaded', 'amp_editor_core_blocks' ); - add_action( 'wp_loaded', 'amp_post_meta_box' ); - add_action( 'wp_loaded', 'amp_story_templates' ); add_action( 'wp_loaded', 'amp_add_options_menu' ); add_action( 'wp_loaded', 'amp_admin_pointer' ); - add_action( 'parse_query', 'amp_correct_query_when_is_front_page' ); - add_action( 'admin_bar_menu', 'amp_add_admin_bar_view_link', 100 ); - // Redirect the old url of amp page to the updated url. - add_filter( 'old_slug_redirect_url', 'amp_redirect_old_slug_to_new_url' ); + if ( AMP_Options_Manager::is_website_experience_enabled() ) { + add_rewrite_endpoint( amp_get_slug(), EP_PERMALINK ); + AMP_Post_Type_Support::add_post_type_support(); + add_action( 'init', array( 'AMP_Post_Type_Support', 'add_post_type_support' ), 1000 ); // After post types have been defined. + add_action( 'parse_query', 'amp_correct_query_when_is_front_page' ); + add_action( 'admin_bar_menu', 'amp_add_admin_bar_view_link', 100 ); + add_action( 'wp_loaded', 'amp_editor_core_blocks' ); + add_action( 'wp_loaded', 'amp_post_meta_box' ); + add_filter( 'request', 'amp_force_query_var_value' ); + + // Add actions for reader mode templates. + add_action( 'wp', 'amp_maybe_add_actions' ); + + // Redirect the old url of amp page to the updated url. + add_filter( 'old_slug_redirect_url', 'amp_redirect_old_slug_to_new_url' ); + } + + if ( AMP_Options_Manager::is_stories_experience_enabled() ) { + AMP_Story_Post_Type::register(); + add_action( 'wp_loaded', 'amp_story_templates' ); + } - // Add actions for legacy post templates. - add_action( 'wp', 'amp_maybe_add_actions' ); + if ( defined( 'WP_CLI' ) && WP_CLI ) { + WP_CLI::add_command( 'amp', new AMP_CLI() ); + } /* * Broadcast plugin updates. diff --git a/includes/admin/class-amp-admin-pointers.php b/includes/admin/class-amp-admin-pointers.php index fb843352724..d86d85cb79f 100644 --- a/includes/admin/class-amp-admin-pointers.php +++ b/includes/admin/class-amp-admin-pointers.php @@ -87,7 +87,7 @@ private function get_pointers() { if ( 'toplevel_page_amp-options' === $hook_suffix ) { return false; } - return ! AMP_Options_Manager::get_option( 'enable_amp_stories' ); + return ! AMP_Options_Manager::is_stories_experience_enabled(); }, ) ), @@ -104,7 +104,7 @@ private function get_pointers() { if ( 'edit.php' === $hook_suffix && AMP_Story_Post_Type::POST_TYPE_SLUG === filter_input( INPUT_GET, 'post_type' ) ) { return false; } - return AMP_Story_Post_Type::has_required_block_capabilities() && AMP_Options_Manager::get_option( 'enable_amp_stories' ); + return AMP_Options_Manager::is_stories_experience_enabled(); }, ) ), diff --git a/includes/admin/functions.php b/includes/admin/functions.php index 5c46ae7dd81..beaa1e24bc8 100644 --- a/includes/admin/functions.php +++ b/includes/admin/functions.php @@ -21,7 +21,7 @@ * And this does not need to toggle between the AMP and normal display. */ function amp_init_customizer() { - if ( amp_is_canonical() ) { + if ( amp_is_canonical() || ! AMP_Options_Manager::is_website_experience_enabled() ) { return; } diff --git a/includes/class-amp-story-post-type.php b/includes/class-amp-story-post-type.php index 8e83da82525..6dc03227b28 100644 --- a/includes/class-amp-story-post-type.php +++ b/includes/class-amp-story-post-type.php @@ -120,7 +120,7 @@ public static function has_required_block_capabilities() { * @return void */ public static function register() { - if ( ! AMP_Options_Manager::get_option( 'enable_amp_stories' ) || ! self::has_required_block_capabilities() ) { + if ( ! AMP_Options_Manager::is_stories_experience_enabled() || ! self::has_required_block_capabilities() ) { return; } diff --git a/includes/class-amp-theme-support.php b/includes/class-amp-theme-support.php index 5799213da40..294b465ac74 100644 --- a/includes/class-amp-theme-support.php +++ b/includes/class-amp-theme-support.php @@ -154,7 +154,7 @@ public static function init() { self::$init_start_time = microtime( true ); - if ( current_theme_supports( self::SLUG ) ) { + if ( AMP_Options_Manager::is_website_experience_enabled() && current_theme_supports( self::SLUG ) ) { // Ensure extra theme support for core themes is in place. AMP_Core_Theme_Sanitizer::extend_theme_support(); @@ -168,7 +168,7 @@ public static function init() { * action to template_redirect--the wp action--is used instead. */ add_action( 'wp', array( __CLASS__, 'finish_init' ), PHP_INT_MAX ); - } elseif ( AMP_Options_Manager::get_option( 'enable_amp_stories' ) ) { + } elseif ( AMP_Options_Manager::is_stories_experience_enabled() ) { add_action( 'wp', function () { diff --git a/includes/options/class-amp-options-manager.php b/includes/options/class-amp-options-manager.php index 95d68941c11..72a9c65fda7 100644 --- a/includes/options/class-amp-options-manager.php +++ b/includes/options/class-amp-options-manager.php @@ -126,6 +126,32 @@ public static function get_option( $option, $default = false ) { return $amp_options[ $option ]; } + /** + * Determine whether website experience is enabled. + * + * @since 1.2 + * + * @return bool Enabled. + */ + public static function is_website_experience_enabled() { + return in_array( self::WEBSITE_EXPERIENCE, self::get_option( 'experiences' ), true ); + } + + /** + * Determine whether stories experience is enabled. + * + * @since 1.2 + * + * @return bool Enabled. + */ + public static function is_stories_experience_enabled() { + return ( + AMP_Story_Post_Type::has_required_block_capabilities() + && + in_array( self::STORIES_EXPERIENCE, self::get_option( 'experiences' ), true ) + ); + } + /** * Validate options. * @@ -175,13 +201,15 @@ public static function validate_options( $new_options ) { $options['auto_accept_sanitization'] = ! empty( $new_options['auto_accept_sanitization'] ); // Validate post type support. - $options['supported_post_types'] = array(); - if ( isset( $new_options['supported_post_types'] ) ) { - foreach ( $new_options['supported_post_types'] as $post_type ) { - if ( ! post_type_exists( $post_type ) ) { - add_settings_error( self::OPTION_NAME, 'unknown_post_type', __( 'Unrecognized post type.', 'amp' ) ); - } else { - $options['supported_post_types'][] = $post_type; + if ( in_array( self::WEBSITE_EXPERIENCE, $options['experiences'], true ) || isset( $new_options['supported_post_types'] ) ) { + $options['supported_post_types'] = array(); + if ( isset( $new_options['supported_post_types'] ) ) { + foreach ( $new_options['supported_post_types'] as $post_type ) { + if ( ! post_type_exists( $post_type ) ) { + add_settings_error( self::OPTION_NAME, 'unknown_post_type', __( 'Unrecognized post type.', 'amp' ) ); + } else { + $options['supported_post_types'][] = $post_type; + } } } } @@ -270,6 +298,9 @@ public static function validate_options( $new_options ) { * @see add_settings_error() */ public static function check_supported_post_type_update_errors() { + if ( ! self::is_website_experience_enabled() ) { + return; + } // If all templates are supported then skip check since all post types are also supported. This option only applies with native/transitional theme support. if ( self::get_option( 'all_templates_supported', false ) && 'disabled' !== self::get_option( 'theme_support' ) ) { diff --git a/includes/options/class-amp-options-menu.php b/includes/options/class-amp-options-menu.php index 2067dfc9308..1bed68c491a 100644 --- a/includes/options/class-amp-options-menu.php +++ b/includes/options/class-amp-options-menu.php @@ -502,13 +502,23 @@ public function render_supported_templates() {
> - +

    + name, AMP_Post_Type_Support::SLUG ) + || + ( ! AMP_Options_Manager::is_website_experience_enabled() && in_array( $post_type->name, $supported_post_types, true ) ) + ); + ?>
  • name}"; ?> name, AMP_Post_Type_Support::SLUG ) ); ?> + >