Skip to content

Commit

Permalink
Merge pull request #4312 from ampproject/enhancement/2204-default-amp…
Browse files Browse the repository at this point in the history
…-endpoint

Default to ?amp=1 query parameter
  • Loading branch information
westonruter authored Oct 10, 2020
2 parents b37b1ee + ac94637 commit c3aeec5
Show file tree
Hide file tree
Showing 20 changed files with 338 additions and 218 deletions.
4 changes: 2 additions & 2 deletions includes/admin/class-amp-post-meta-box.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public function enqueue_admin_assets() {
'ampPostMetaBox.boot( %s );',
wp_json_encode(
[
'previewLink' => esc_url_raw( add_query_arg( amp_get_slug(), '', get_preview_post_link( $post ) ) ),
'previewLink' => esc_url_raw( amp_add_paired_endpoint( get_preview_post_link( $post ) ) ),
'canonical' => amp_is_canonical(),
'enabled' => empty( $support_errors ),
'canSupport' => 0 === count( array_diff( $support_errors, [ 'post-status-disabled' ] ) ),
Expand Down Expand Up @@ -447,7 +447,7 @@ public function preview_post_link( $link ) {
);

if ( $is_amp ) {
$link = add_query_arg( amp_get_slug(), true, $link );
$link = amp_add_paired_endpoint( $link );
}

return $link;
Expand Down
156 changes: 97 additions & 59 deletions includes/amp-helper-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ function amp_redirect_old_slug_to_new_url( $link ) {

if ( amp_is_request() && ! amp_is_canonical() ) {
if ( ! amp_is_legacy() ) {
$link = add_query_arg( amp_get_slug(), '', $link );
$link = amp_add_paired_endpoint( $link );
} else {
$link = trailingslashit( trailingslashit( $link ) . amp_get_slug() );
}
Expand Down Expand Up @@ -699,16 +699,6 @@ function amp_get_current_url() {
* @return string AMP permalink.
*/
function amp_get_permalink( $post_id ) {

// When theme support is present (i.e. not using legacy Reader post templates), the plain query var should always be used.
if ( ! amp_is_legacy() ) {
$permalink = get_permalink( $post_id );
if ( ! amp_is_canonical() ) {
$permalink = add_query_arg( amp_get_slug(), '', $permalink );
}
return $permalink;
}

/**
* Filters the AMP permalink to short-circuit normal generation.
*
Expand All @@ -727,35 +717,7 @@ function amp_get_permalink( $post_id ) {
}

$permalink = get_permalink( $post_id );

if ( amp_is_canonical() ) {
$amp_url = $permalink;
} else {
$parsed_url = wp_parse_url( get_permalink( $post_id ) );
$structure = get_option( 'permalink_structure' );
$use_query_var = (
// If pretty permalinks aren't available, then query var must be used.
empty( $structure )
||
// If there are existing query vars, then always use the amp query var as well.
! empty( $parsed_url['query'] )
||
// If the post type is hierarchical then the /amp/ endpoint isn't available.
is_post_type_hierarchical( get_post_type( $post_id ) )
||
// Attachment pages don't accept the /amp/ endpoint.
'attachment' === get_post_type( $post_id )
);
if ( $use_query_var ) {
$amp_url = add_query_arg( amp_get_slug(), '', $permalink );
} else {
$amp_url = preg_replace( '/#.*/', '', $permalink );
$amp_url = trailingslashit( $amp_url ) . user_trailingslashit( amp_get_slug(), 'single_amp' );
if ( ! empty( $parsed_url['fragment'] ) ) {
$amp_url .= '#' . $parsed_url['fragment'];
}
}
}
$amp_url = amp_is_canonical() ? $permalink : amp_add_paired_endpoint( $permalink );

/**
* Filters AMP permalink.
Expand All @@ -773,19 +735,14 @@ function amp_get_permalink( $post_id ) {
* Remove the AMP endpoint (and query var) from a given URL.
*
* @since 0.7
* @since 2.1 Deprecated.
* @deprecated Use amp_remove_paired_endpoint() instead.
*
* @param string $url URL.
* @return string URL with AMP stripped.
*/
function amp_remove_endpoint( $url ) {

// Strip endpoint.
$url = preg_replace( ':/' . preg_quote( amp_get_slug(), ':' ) . '(?=/?(\?|#|$)):', '', $url );

// Strip query var.
$url = remove_query_arg( amp_get_slug(), $url );

return $url;
return amp_remove_paired_endpoint( $url );
}

/**
Expand Down Expand Up @@ -836,7 +793,7 @@ function amp_add_amphtml_link() {
}

if ( AMP_Theme_Support::is_paired_available() ) {
$amp_url = add_query_arg( amp_get_slug(), '', amp_get_current_url() );
$amp_url = amp_add_paired_endpoint( amp_get_current_url() );
} else {
$amp_url = amp_get_permalink( get_queried_object_id() );
}
Expand Down Expand Up @@ -899,13 +856,7 @@ function amp_is_request() {
$is_amp_url = (
amp_is_canonical()
||
isset( $_GET[ amp_get_slug() ] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
||
(
$wp_query instanceof WP_Query
&&
false !== $wp_query->get( amp_get_slug(), false )
)
amp_has_paired_endpoint()
);

// If AMP is not available, then it's definitely not an AMP endpoint.
Expand Down Expand Up @@ -1910,11 +1861,11 @@ function amp_add_admin_bar_view_link( $wp_admin_bar ) {
$is_amp_request = amp_is_request();

if ( $is_amp_request ) {
$href = amp_remove_endpoint( amp_get_current_url() );
$href = amp_remove_paired_endpoint( amp_get_current_url() );
} elseif ( is_singular() ) {
$href = amp_get_permalink( get_queried_object_id() ); // For sake of Reader mode.
} else {
$href = add_query_arg( amp_get_slug(), '', amp_get_current_url() );
$href = amp_add_paired_endpoint( amp_get_current_url() );
}

$href = remove_query_arg( QueryVar::NOAMP, $href );
Expand Down Expand Up @@ -1949,7 +1900,7 @@ function amp_add_admin_bar_view_link( $wp_admin_bar ) {
if ( amp_is_legacy() ) {
$args['href'] = add_query_arg( 'autofocus[panel]', AMP_Template_Customizer::PANEL_ID, $args['href'] );
} else {
$args['href'] = add_query_arg( amp_get_slug(), '1', $args['href'] );
$args['href'] = amp_add_paired_endpoint( $args['href'] );
}
$wp_admin_bar->add_node( $args );
}
Expand Down Expand Up @@ -1983,3 +1934,90 @@ function amp_generate_script_hash( $script ) {
);
return 'sha384-' . $hash;
}

/**
* Turn a given URL into a paired AMP URL.
*
* @since 2.1
*
* @param string $url URL.
* @return string AMP URL.
*/
function amp_add_paired_endpoint( $url ) {
return add_query_arg( amp_get_slug(), '1', $url );
}

/**
* Determine a given URL is for a paired AMP request.
*
* @since 2.1
*
* @param string $url URL to examine. If empty, will use the current URL.
* @return bool True if the AMP query parameter is set with the required value, false if not.
* @global WP_Query $wp_query
*/
function amp_has_paired_endpoint( $url = '' ) {
$slug = amp_get_slug();

// If the URL was not provided, then use the environment which is already parsed.
if ( empty( $url ) ) {
global $wp_query;
return (
isset( $_GET[ $slug ] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
||
(
$wp_query instanceof WP_Query
&&
false !== $wp_query->get( $slug, false )
)
);
}

$parsed_url = wp_parse_url( $url );
if ( ! empty( $parsed_url['query'] ) ) {
$query_vars = [];
wp_parse_str( $parsed_url['query'], $query_vars );
if ( isset( $query_vars[ $slug ] ) ) {
return true;
}
}

if ( ! empty( $parsed_url['path'] ) ) {
$pattern = sprintf(
'#/%s(/[^/^])?/?$#',
preg_quote( $slug, '#' )
);
if ( preg_match( $pattern, $parsed_url['path'] ) ) {
return true;
}
}

return false;
}

/**
* Remove the paired AMP endpoint from a given URL.
*
* @since 2.1
*
* @param string $url URL.
* @return string URL with AMP stripped.
*/
function amp_remove_paired_endpoint( $url ) {
$slug = amp_get_slug();

// Strip endpoint, including /amp/, /amp/amp/, /amp/foo/.
$url = preg_replace(
sprintf(
':(/%s(/[^/?#]+)?)+(?=/?(\?|#|$)):',
preg_quote( $slug, ':' )
),
'',
$url
);

// Strip query var, including ?amp, ?amp=1, etc.
$url = remove_query_arg( $slug, $url );

return $url;
}
55 changes: 18 additions & 37 deletions includes/class-amp-theme-support.php
Original file line number Diff line number Diff line change
Expand Up @@ -327,20 +327,14 @@ public static function finish_init() {
add_filter( 'template_include', [ __CLASS__, 'serve_paired_browsing_experience' ], PHP_INT_MAX );
}

$has_query_var = (
isset( $_GET[ amp_get_slug() ] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
||
false !== get_query_var( amp_get_slug(), false )
);

if ( ! amp_is_request() ) {
/*
* Redirect to AMP-less URL if AMP is not available for this URL and yet the query var is present.
* Temporary redirect is used for admin users because implied transitional mode and template support can be
* enabled by user ay any time, so they will be able to make AMP available for this URL and see the change
* without wrestling with the redirect cache.
*/
if ( $has_query_var ) {
if ( amp_has_paired_endpoint() ) {
self::redirect_non_amp_url( current_user_can( 'manage_options' ) ? 302 : 301 );
}

Expand Down Expand Up @@ -390,13 +384,11 @@ static function() {
*
* @since 1.0
* @since 2.0 Removed $exit param.
* @since 2.1 Remove obsolete redirection from /amp/ to ?amp when on non-legacy Reader mode.
*
* @return bool Whether redirection should have been done.
*/
public static function ensure_proper_amp_location() {
$has_query_var = false !== get_query_var( amp_get_slug(), false ); // May come from URL param or endpoint slug.
$has_url_param = isset( $_GET[ amp_get_slug() ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended

if ( amp_is_canonical() ) {
/*
* When AMP-first/canonical, then when there is an /amp/ endpoint or ?amp URL param,
Expand All @@ -405,34 +397,23 @@ public static function ensure_proper_amp_location() {
* should happen infrequently. For admin users, this is kept temporary to allow them
* to not be hampered by browser remembering permanent redirects and preventing test.
*/
if ( $has_query_var || $has_url_param ) {
if ( amp_has_paired_endpoint() ) {
return self::redirect_non_amp_url( current_user_can( 'manage_options' ) ? 302 : 301 );
}
} elseif ( amp_is_legacy() && is_singular() ) {
// Prevent infinite URL space under /amp/ endpoint.
} elseif ( amp_has_paired_endpoint() ) {
/*
* Prevent infinite URL space under /amp/ endpoint. Note that WordPress allows endpoints to have a value,
* such as the case of /feed/ where /feed/atom/ is the same as saying ?feed=atom. In this case, we need to
* check for /amp/x/ to protect against links like `<a href="./amp/">AMP!</a>`.
* See https://github.com/ampproject/amp-wp/pull/1846.
*/
global $wp;
$path_args = [];
wp_parse_str( $wp->matched_query, $path_args );
if ( isset( $path_args[ amp_get_slug() ] ) && '' !== $path_args[ amp_get_slug() ] ) {
if ( wp_safe_redirect( amp_get_permalink( get_queried_object_id() ), 301 ) ) {
// @codeCoverageIgnoreStart
exit;
// @codeCoverageIgnoreEnd
}
return true;
}
} elseif ( $has_query_var && ! $has_url_param ) {
/*
* When in AMP transitional mode *with* theme support, then the proper AMP URL has the 'amp' URL param
* and not the /amp/ endpoint. The URL param is now the exclusive way to mark AMP in transitional mode
* when amp theme support present. This is important for plugins to be able to reliably call
* amp_is_request() before the parse_query action.
*/
$old_url = amp_get_current_url();
$new_url = add_query_arg( amp_get_slug(), '', amp_remove_endpoint( $old_url ) );
if ( $old_url !== $new_url ) {
// A temporary redirect is used for admin users to allow them to see changes between reader mode and transitional modes.
if ( wp_safe_redirect( $new_url, current_user_can( 'manage_options' ) ? 302 : 301 ) ) {
$current_url = amp_get_current_url();
$redirect_url = amp_add_paired_endpoint( amp_remove_paired_endpoint( $current_url ) );
if ( $current_url !== $redirect_url && wp_safe_redirect( $redirect_url, 301 ) ) {
// @codeCoverageIgnoreStart
exit;
// @codeCoverageIgnoreEnd
Expand All @@ -458,7 +439,7 @@ public static function ensure_proper_amp_location() {
*/
public static function redirect_non_amp_url( $status = 302 ) {
$current_url = amp_get_current_url();
$non_amp_url = amp_remove_endpoint( $current_url );
$non_amp_url = amp_remove_paired_endpoint( $current_url );
if ( $non_amp_url === $current_url ) {
return false;
}
Expand Down Expand Up @@ -1132,7 +1113,7 @@ public static function amend_comment_form() {
}

/**
* Amend the comments/redpond links to go to non-AMP page when in legacy Reader mode.
* Amend the comments/respond links to go to non-AMP page when in legacy Reader mode.
*
* @see get_comments_link()
* @see comments_popup_link()
Expand Down Expand Up @@ -1208,7 +1189,7 @@ public static function get_current_canonical_url() {
$url = add_query_arg( $added_query_vars, $url );
}

return amp_remove_endpoint( $url );
return amp_remove_paired_endpoint( $url );
}

/**
Expand Down Expand Up @@ -1853,7 +1834,7 @@ public static function finish_output_buffering( $response ) {

// Add link to non-AMP version if not canonical.
if ( ! amp_is_canonical() ) {
$non_amp_url = amp_remove_endpoint( amp_get_current_url() );
$non_amp_url = amp_remove_paired_endpoint( amp_get_current_url() );

// Prevent user from being redirected back to AMP version.
if ( true === AMP_Options_Manager::get_option( Option::MOBILE_REDIRECT ) ) {
Expand Down Expand Up @@ -2208,7 +2189,7 @@ static function( Optimizer\Error $error ) {

// Redirect to the non-AMP version if not on an AMP-first site.
if ( ! $can_serve && ! amp_is_canonical() ) {
$non_amp_url = amp_remove_endpoint( amp_get_current_url() );
$non_amp_url = amp_remove_paired_endpoint( amp_get_current_url() );

// Redirect to include query var to preventing AMP from even being considered available.
$non_amp_url = add_query_arg( QueryVar::NOAMP, QueryVar::NOAMP_AVAILABLE, $non_amp_url );
Expand Down
2 changes: 1 addition & 1 deletion includes/embeds/class-amp-core-block-handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ private function process_archives_widgets( Document $dom, $args = [] ) {
*
* @var DOMElement $option
*/
$option->setAttribute( 'value', add_query_arg( amp_get_slug(), '', $option->getAttribute( 'value' ) ) );
$option->setAttribute( 'value', amp_add_paired_endpoint( $option->getAttribute( 'value' ) ) );
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion includes/options/class-amp-options-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ static function ( $supported ) {
&&
get_stylesheet() === $options[ Option::READER_THEME ]
&&
! isset( $_GET[ amp_get_slug() ] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
! amp_has_paired_endpoint()
) {
/*
* When Reader mode is selected and a Reader theme has been chosen, if the active theme switches to be the
Expand Down
2 changes: 1 addition & 1 deletion includes/sanitizers/class-amp-form-sanitizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function sanitize() {
// Record that action was converted to action-xhr.
$action_url = add_query_arg( AMP_HTTP::ACTION_XHR_CONVERTED_QUERY_VAR, 1, $action_url );
if ( ! amp_is_canonical() ) {
$action_url = add_query_arg( amp_get_slug(), '', $action_url );
$action_url = amp_add_paired_endpoint( $action_url );
}
$node->setAttribute( 'action-xhr', $action_url );
// Append success/error handlers if not found.
Expand Down
Loading

0 comments on commit c3aeec5

Please sign in to comment.