Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revamp notice appearing in AMP Enabled toggle, revamp how plugin determines whether AMP can be disabled #5010

Merged
merged 27 commits into from
Jul 14, 2020
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5bcc30a
Default to paired when amp theme support added
westonruter Jul 9, 2020
f3ba560
Eliminate use of theme support flags and amp_supportable_templates fi…
westonruter Jul 9, 2020
6f037ab
Merge branch 'develop' of github.com:ampproject/amp-wp into update/th…
westonruter Jul 10, 2020
490fe5a
Eliminate use of post type support to control post type support
westonruter Jul 9, 2020
723a7bb
Remove test kept after merge conflict
westonruter Jul 10, 2020
a6596ba
Fix tests for changes to post type support
westonruter Jul 10, 2020
dc1d73a
Add tests for migrating supported_post_types
westonruter Jul 10, 2020
88d1c8b
Migrated supported_templates to be stored as associative array
westonruter Jul 10, 2020
14aeece
Remove redundant isset checks with alternative to appease PhpStan
westonruter Jul 10, 2020
1919ec1
Remove _doing_it_wrong() since templates_supported is supported only …
westonruter Jul 10, 2020
ab52015
Add missing semicolons from JS
westonruter Jul 10, 2020
d85ec63
Make sure toggling all themes supported does not destroy individual s…
westonruter Jul 11, 2020
668d0d9
Migrate theme support flags to options when upgrading
westonruter Jul 11, 2020
2a13776
Defer doing amp_plugin_update until end of after_setup_theme
westonruter Jul 11, 2020
75487f4
Remove obsolete checks for password-protected posts
westonruter Jul 11, 2020
270d604
Remove obsolete error codes for page-on-front and page-for-posts
westonruter Jul 11, 2020
e1f3871
Fix tests and finish changes for get_status_and_errors
westonruter Jul 11, 2020
7a0ab77
Revamp AMP Unavailable notice in post editor
westonruter Jul 11, 2020
3a326c3
Restore using non-associative arrays to store supported post types an…
westonruter Jul 11, 2020
8c51a9d
Remove obsolete assertion
westonruter Jul 11, 2020
3315937
Use static closures
westonruter Jul 11, 2020
a39c212
Remove duplicate test data
westonruter Jul 11, 2020
fefff34
Remove invalid todo
westonruter Jul 11, 2020
dac8963
Merge branch 'develop' of github.com:ampproject/amp-wp into update/th…
westonruter Jul 12, 2020
6e190c5
Merge branch 'develop' of github.com:ampproject/amp-wp into update/th…
westonruter Jul 13, 2020
7df6a05
Use end of init instead of end of after_setup_theme to do DB upgrade
westonruter Jul 13, 2020
e07656a
Improve styling of AMP Unavailable notice
westonruter Jul 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions assets/src/settings-page/supported-templates-visibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ export function SupportedTemplatesVisibility() {
const { all_templates_supported: allTemplatesSupported, reader_theme: readerTheme, theme_support: themeSupport } = editedOptions || {};

const supportedPostTypesTitle = useRef( document.querySelector( '#all_templates_supported_fieldset, #supported_post_types_fieldset > .title' ) );
const supportedPostTypesFieldset = useRef( document.getElementById( 'supported_post_types_fieldset' ) );
const supportedTemplatesFieldset = useRef( document.getElementById( 'supported_templates_fieldset' ) );
const supportedTemplateInputs = useRef( [ ...document.querySelectorAll( '#supported_templates_fieldset input[type=checkbox]' ) ] );
const supportedPostTypesFieldset = document.getElementById( 'supported_post_types_fieldset' );
const supportedTemplatesFieldset = document.getElementById( 'supported_templates_fieldset' );
const supportedPostTypesFieldsetRef = useRef( supportedPostTypesFieldset );
const supportedTemplatesFieldsetRef = useRef( supportedTemplatesFieldset );
const supportedTemplateInputs = useRef( [ ...supportedTemplatesFieldset.querySelectorAll( 'input[type=checkbox]' ) ] );
const supportedPostTypeInputs = useRef( [ ...supportedPostTypesFieldset.querySelectorAll( 'input[type=checkbox]' ) ] );

/**
* Show/hide settings features depending on options on the page.
Expand All @@ -36,30 +39,43 @@ export function SupportedTemplatesVisibility() {
if ( 'reader' === themeSupport && 'legacy' === readerTheme ) {
supportedPostTypesHidden = false;
}
supportedPostTypesFieldset.current.classList.toggle(
supportedPostTypesFieldsetRef.current.classList.toggle(
'hidden',
supportedPostTypesHidden,
);

supportedTemplatesFieldset.current.classList.toggle(
supportedTemplatesFieldsetRef.current.classList.toggle(
'hidden',
allTemplatesSupported || ( 'reader' === themeSupport && 'legacy' === readerTheme ),
);
}, [ allTemplatesSupported, readerTheme, themeSupport ] );

const handleChecked = ( checkboxInput ) => {
const hiddenInput = checkboxInput.nextElementSibling;
hiddenInput.value = JSON.stringify( checkboxInput.checked );
};

/**
* Check or uncheck all of a checkbox's child checkboxes when it is checked or unchecked.
*/
useEffect( () => {
const listenerCallback = ( event ) => {
if ( ! supportedTemplateInputs.current.includes( event.target ) ) {
const isSupportedTemplateCheckbox = supportedTemplateInputs.current.includes( event.target );
const isPostTypeSupportCheckbox = supportedPostTypeInputs.current.includes( event.target );

if ( ! isSupportedTemplateCheckbox && ! isPostTypeSupportCheckbox ) {
return;
}

const checked = event.target.checked;
[ ...event.target.parentElement.querySelectorAll( 'input[type=checkbox]' ) ].forEach( ( inputElement ) => {
inputElement.checked = checked;
} );
if ( isSupportedTemplateCheckbox ) {
const checked = event.target.checked;
[ ...event.target.parentElement.querySelectorAll( 'input[type=checkbox]' ) ].forEach( ( inputElement ) => {
inputElement.checked = checked;
handleChecked( inputElement );
} );
}

handleChecked( event.target );
};

global.addEventListener( 'click', listenerCallback );
Expand Down
12 changes: 1 addition & 11 deletions includes/admin/class-amp-post-meta-box.php
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,6 @@ public static function get_status_and_errors( $post ) {
$availability = AMP_Theme_Support::get_template_availability( $post );
$status = $availability['supported'] ? self::ENABLED_STATUS : self::DISABLED_STATUS;
$errors = array_diff( $availability['errors'], [ 'post-status-disabled' ] ); // Subtract the status which the metabox will allow to be toggled.
if ( true === $availability['immutable'] ) {
$errors[] = 'status_immutable';
}
} else {
$errors = AMP_Post_Type_Support::get_support_errors( $post );
$status = empty( $errors ) ? self::ENABLED_STATUS : self::DISABLED_STATUS;
Expand All @@ -344,13 +341,6 @@ public static function get_status_and_errors( $post ) {
*/
public function get_error_messages( $status, $errors ) {
$error_messages = [];
if ( in_array( 'status_immutable', $errors, true ) ) {
if ( self::ENABLED_STATUS === $status ) {
$error_messages[] = __( 'Your site does not allow AMP to be disabled.', 'amp' );
} else {
$error_messages[] = __( 'Your site does not allow AMP to be enabled.', 'amp' );
}
}
Comment on lines -347 to -353
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Byebye!

if ( in_array( 'template_unsupported', $errors, true ) || in_array( 'no_matching_template', $errors, true ) ) {
$error_messages[] = sprintf(
/* translators: %s is a link to the AMP settings screen */
Expand All @@ -371,7 +361,7 @@ public function get_error_messages( $status, $errors ) {
if ( in_array( 'skip-post', $errors, true ) ) {
$error_messages[] = __( 'A plugin or theme has disabled AMP support.', 'amp' );
}
if ( count( array_diff( $errors, [ 'status_immutable', 'page-on-front', 'page-for-posts', 'password-protected', 'post-type-support', 'skip-post', 'template_unsupported', 'no_matching_template' ] ) ) > 0 ) {
if ( count( array_diff( $errors, [ 'page-on-front', 'page-for-posts', 'password-protected', 'post-type-support', 'skip-post', 'template_unsupported', 'no_matching_template' ] ) ) > 0 ) {
$error_messages[] = __( 'Unavailable for an unknown reason.', 'amp' );
}

Expand Down
6 changes: 3 additions & 3 deletions includes/admin/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function amp_admin_get_preview_permalink() {
$post_type = (string) apply_filters( 'amp_customizer_post_type', 'post' );

// Make sure the desired post type is actually supported, and if so, prefer it.
$supported_post_types = get_post_types_by_support( AMP_Post_Type_Support::SLUG );
$supported_post_types = AMP_Post_Type_Support::get_supported_post_types();
if ( in_array( $post_type, $supported_post_types, true ) ) {
$supported_post_types = array_unique( array_merge( [ $post_type ], $supported_post_types ) );
}
Expand All @@ -63,8 +63,8 @@ function amp_admin_get_preview_permalink() {
'no_found_rows' => true,
'suppress_filters' => false,
'post_status' => 'publish',
'post_password' => '',
'post_type' => $supported_post_types,
'post_password' => '', // @todo Not needed anymore because password-protected posts are now supported.
'post_type' => $supported_post_types, // @todo This is not needed if ( ! amp_is_legacy() && AMP_Options_Manager::get_option( Option::ALL_TEMPLATES_SUPPORTED ) ).
'posts_per_page' => 1,
'fields' => 'ids',
// @todo This should eventually do a meta_query to make sure there are none that have AMP_Post_Meta_Box::STATUS_POST_META_KEY = DISABLED_STATUS.
Expand Down
24 changes: 15 additions & 9 deletions includes/amp-helper-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,6 @@ function amp_init() {
add_action( 'wp_loaded', 'amp_bootstrap_admin' );

add_rewrite_endpoint( amp_get_slug(), EP_PERMALINK );
AMP_Post_Type_Support::add_post_type_support();
add_action( 'init', [ '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 );

Expand Down Expand Up @@ -143,14 +141,22 @@ function () {
*/
$options = get_option( AMP_Options_Manager::OPTION_NAME, [] );
$old_version = isset( $options[ Option::VERSION ] ) ? $options[ Option::VERSION ] : '0.0';

if ( AMP__VERSION !== $old_version && is_admin() && current_user_can( 'manage_options' ) ) {
/**
* Triggers when after amp_init when the plugin version has updated.
*
* @param string $old_version Old version.
*/
do_action( 'amp_plugin_update', $old_version );
AMP_Options_Manager::update_option( Option::VERSION, AMP__VERSION );
// This waits to happen until after_setup_theme to ensure that amp theme support and amp post type support have all been added.
add_action(
'after_setup_theme',
pierlon marked this conversation as resolved.
Show resolved Hide resolved
function () use ( $old_version ) {
westonruter marked this conversation as resolved.
Show resolved Hide resolved
/**
* Triggers when after amp_init when the plugin version has updated.
*
* @param string $old_version Old version.
*/
do_action( 'amp_plugin_update', $old_version );
AMP_Options_Manager::update_option( Option::VERSION, AMP__VERSION );
},
PHP_INT_MAX
);
}

add_action(
Expand Down
26 changes: 18 additions & 8 deletions includes/class-amp-post-type-support.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static function get_eligible_post_types() {
*/
public static function get_post_types_for_rest_api() {
return array_intersect(
get_post_types_by_support( 'amp' ),
self::get_supported_post_types(),
get_post_types(
[
'show_in_rest' => true,
Expand All @@ -67,21 +67,31 @@ public static function get_post_types_for_rest_api() {
);
}

/**
* Get supported post types.
*
* @return string[] List of post types that support AMP.
*/
public static function get_supported_post_types() {
if ( ! amp_is_legacy() && AMP_Options_Manager::get_option( Option::ALL_TEMPLATES_SUPPORTED ) ) {
return self::get_eligible_post_types();
}
return array_keys( array_filter( AMP_Options_Manager::get_option( Option::SUPPORTED_POST_TYPES, [] ) ) );
}

/**
* Declare support for post types.
*
* This function should only be invoked through the 'after_setup_theme' action to
* allow plugins/theme to overwrite the post types support.
*
* @codeCoverageIgnore
* @since 0.6
* @deprecated The 'amp' post type support is no longer used at runtime to determine whether AMP is supported.
*/
public static function add_post_type_support() {
if ( ! amp_is_legacy() && AMP_Options_Manager::get_option( Option::ALL_TEMPLATES_SUPPORTED ) ) {
$post_types = self::get_eligible_post_types();
} else {
$post_types = AMP_Options_Manager::get_option( Option::SUPPORTED_POST_TYPES, [] );
}
foreach ( $post_types as $post_type ) {
_deprecated_function( __METHOD__, '1.6' );
foreach ( self::get_supported_post_types() as $post_type ) {
add_post_type_support( $post_type, self::SLUG );
}
}
Expand All @@ -100,7 +110,7 @@ public static function get_support_errors( $post ) {
}
$errors = [];

if ( ! post_type_supports( $post->post_type, self::SLUG ) ) {
if ( ! in_array( $post->post_type, self::get_supported_post_types(), true ) ) {
$errors[] = 'post-type-support';
}

Expand Down
100 changes: 44 additions & 56 deletions includes/class-amp-theme-support.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,6 @@ public static function get_support_mode() {
* In older versions of the plugin, the DB option was only considered if the theme does not already explicitly support AMP.
* This is no longer the case. The DB option is the only value that is considered.
*
* @todo Should we store the original theme support args so we can tell the user that the active theme says it can be used in Standard/Transitional modes?
* @todo What is even the purpose of doing any of this? Calling current_theme_supports('amp') is irrelevant if is_amp_endpoint().
* Maybe not because really we should be scanning the site to actually see if there are validation errors, and tha that this
*
* @see AMP_Post_Type_Support::add_post_type_support() For where post type support is added, since it is irrespective of theme support.
* @deprecated
* @codeCoverageIgnore
Expand All @@ -263,16 +259,18 @@ public static function get_theme_support_args() {
return false;
}
$support = get_theme_support( self::SLUG );
if ( true === $support ) {
return [
self::PAIRED_FLAG => false,
];
if ( isset( $support[0] ) && is_array( $support[0] ) ) {
$args = $support[0];
} else {
$args = [];
}
if ( ! isset( $support[0] ) || ! is_array( $support[0] ) ) {
return [ 'paired' => false ];
if ( ! isset( $args[ self::PAIRED_FLAG ] ) ) {
// Formerly when paired was not supplied it defaulted to be false. However, the reality is that
// the vast majority of themes should be built to work in AMP and non-AMP because AMP can be
// disabled for any URL just by disabling AMP for the post.
$args[ self::PAIRED_FLAG ] = true;
}

return wp_parse_args( $support[0], [ 'paired' => false ] );
return $args;
}

/**
Expand Down Expand Up @@ -512,7 +510,6 @@ public static function add_amp_template_filters() {
* Template availability.
*
* @type bool $supported Whether the template is supported in AMP.
* @type bool|null $immutable Whether the supported status is known to be unchangeable.
* @type string|null $template The ID of the matched template (conditional), such as 'is_singular', or null if nothing was matched.
* @type string[] $errors List of the errors or reasons for why the template is not available.
* }
Expand All @@ -537,7 +534,7 @@ public static function get_template_availability( $query = null ) {
$default_response = [
'errors' => [],
'supported' => false,
'immutable' => null,
'immutable' => false, // Obsolete.
'template' => null,
];

Expand All @@ -556,15 +553,7 @@ public static function get_template_availability( $query = null ) {
);
}

$theme_support_args = self::get_theme_support_args();

$all_templates_supported_by_theme_support = false;
if ( isset( $theme_support_args['templates_supported'] ) ) {
$all_templates_supported_by_theme_support = 'all' === $theme_support_args['templates_supported'];
}
$all_templates_supported = (
$all_templates_supported_by_theme_support || AMP_Options_Manager::get_option( Option::ALL_TEMPLATES_SUPPORTED )
);
$all_templates_supported = AMP_Options_Manager::get_option( Option::ALL_TEMPLATES_SUPPORTED );

// Make sure global $wp_query is set in case of conditionals that unfortunately look at global scope.
$prev_query = $wp_query;
Expand Down Expand Up @@ -594,7 +583,6 @@ public static function get_template_availability( $query = null ) {
$matching_templates[ $id ] = [
'template' => $id,
'supported' => ! empty( $supportable_template['supported'] ),
'immutable' => ! empty( $supportable_template['immutable'] ),
];
}
}
Expand Down Expand Up @@ -880,50 +868,50 @@ public static function get_supportable_templates() {
/**
* Filters list of supportable templates.
*
* A theme or plugin can force a given template to be supported or not by preemptively
* setting the 'supported' flag for a given template. Otherwise, if the flag is undefined
* then the user will be able to toggle it themselves in the admin. Each array item should
* have a key that corresponds to a template conditional function. If the key is such a
* function, then the key is used to evaluate whether the given template entry is a match.
* Otherwise, a supportable template item can include a callback value which is used instead.
* Each item needs a 'label' value. Additionally, if the supportable template is a subset of
* another condition (e.g. is_singular > is_single) then this relationship needs to be
* indicated via the 'parent' value.
* Each array item should have a key that corresponds to a template conditional function.
* If the key is such a function, then the key is used to evaluate whether the given template
* entry is a match. Otherwise, a supportable template item can include a callback value which
* is used instead. Each item needs a 'label' value. Additionally, if the supportable template
* is a subset of another condition (e.g. is_singular > is_single) then this relationship needs
* to be indicated via the 'parent' value.
*
* @since 1.0
*
* @param array $templates Supportable templates.
*/
$templates = apply_filters( 'amp_supportable_templates', $templates );

$theme_support_args = self::get_theme_support_args();
$theme_supported_templates = [];
if ( isset( $theme_support_args['templates_supported'] ) ) {
$theme_supported_templates = $theme_support_args['templates_supported'];
}

$supported_templates = AMP_Options_Manager::get_option( Option::SUPPORTED_TEMPLATES );
foreach ( $templates as $id => &$template ) {
$are_all_supported = AMP_Options_Manager::get_option( Option::ALL_TEMPLATES_SUPPORTED );

// Capture user-elected support from options. This allows us to preserve the original user selection through programmatic overrides.
$template['user_supported'] = in_array( $id, $supported_templates, true );

// Consider supported templates from theme support args.
if ( ! isset( $template['supported'] ) ) {
if ( 'all' === $theme_supported_templates ) {
$template['supported'] = true;
} elseif ( is_array( $theme_supported_templates ) && isset( $theme_supported_templates[ $id ] ) ) {
$template['supported'] = $theme_supported_templates[ $id ];
}
$did_filter_supply_supported = false;
$did_filter_supply_immutable = false;
foreach ( $templates as $id => &$template ) {
if ( isset( $template['supported'] ) ) {
$did_filter_supply_supported = true;
}
if ( isset( $template['immutable'] ) ) {
$did_filter_supply_immutable = true;
}

// Make supported state immutable if it was programmatically set.
$template['immutable'] = isset( $template['supported'] );
$template['supported'] = $are_all_supported || ! empty( $supported_templates[ $id ] );
$template['user_supported'] = $template['supported']; // Obsolete.
$template['immutable'] = false; // Obsolete.
}

// Set supported state from user preference.
if ( ! $template['immutable'] ) {
$template['supported'] = AMP_Options_Manager::get_option( Option::ALL_TEMPLATES_SUPPORTED ) || $template['user_supported'];
}
if ( $did_filter_supply_supported ) {
_doing_it_wrong(
'add_filter',
esc_html__( 'The AMP plugin no longer allows `amp_supportable_templates` filters to specify a template as being `supported`. This is now managed only in AMP Settings.', 'amp' ),
'1.6'
);
}
if ( $did_filter_supply_immutable ) {
_doing_it_wrong(
'add_filter',
esc_html__( 'The AMP plugin no longer allows `amp_supportable_templates` filters to specify a template\'s support as being `immutable`. This is now managed only in AMP Settings.', 'amp' ),
'1.6'
);
}

return $templates;
Expand Down
Loading