Skip to content

Commit d9b724b

Browse files
committed
Prevent appending /amp/ endpoint to URLs which already have rewrite endpoint(s)
1 parent a07a6d4 commit d9b724b

File tree

1 file changed

+46
-3
lines changed

1 file changed

+46
-3
lines changed

src/PairedAmpRouting.php

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use AmpProject\AmpWP\Infrastructure\Service;
1616
use AmpProject\AmpWP\Admin\ReaderThemes;
1717
use WP_Query;
18-
use WP_Post;
18+
use WP_Rewrite;
1919

2020
/**
2121
* Service for routing users to and from paired AMP URLs.
@@ -41,6 +41,13 @@ final class PairedAmpRouting implements Service, Registerable, Activateable, Dea
4141
Option::PAIRED_URL_STRUCTURE_CUSTOM,
4242
];
4343

44+
/**
45+
* Regular expression pattern matching any added endpoints in a URL.
46+
*
47+
* @var string
48+
*/
49+
protected $added_rewrite_endpoints_pattern;
50+
4451
/**
4552
* Activate.
4653
*
@@ -256,6 +263,36 @@ public function get_query_var_paired_amp_url( $url ) {
256263
return add_query_arg( amp_get_slug(), '1', $url );
257264
}
258265

266+
/**
267+
* Determine whether a given URL path contains a registered rewrite endpoint.
268+
*
269+
* This is needed to prevent adding the `/amp/` rewrite endpoint to a URL which already has an existing rewrite
270+
* endpoint, as in this case it will fail to match.
271+
*
272+
* @param string $path URL Path.
273+
* @return bool Whether the supplied path contains a registered rewrite endpoint.
274+
* @global WP_Rewrite
275+
*/
276+
private function is_added_rewrite_endpoint_in_path( $path ) {
277+
global $wp_rewrite;
278+
if ( null === $this->added_rewrite_endpoints_pattern && $wp_rewrite instanceof WP_Rewrite ) {
279+
$endpoint_patterns = [];
280+
foreach ( $wp_rewrite->endpoints as $endpoint ) {
281+
$endpoint_patterns[] = preg_quote( $endpoint[1], '#' );
282+
}
283+
if ( empty( $endpoint_patterns ) ) {
284+
return false;
285+
}
286+
$this->added_rewrite_endpoints_pattern = '#/' . implode( '|', $endpoint_patterns ) . '(/|$)#';
287+
}
288+
289+
if ( empty( $this->added_rewrite_endpoints_pattern ) ) {
290+
return false;
291+
}
292+
293+
return (bool) preg_match( $this->added_rewrite_endpoints_pattern, $path );
294+
}
295+
259296
/**
260297
* Get paired AMP URL using a rewrite endpoint.
261298
*
@@ -278,8 +315,11 @@ public function get_rewrite_endpoint_paired_amp_url( $url ) {
278315
$parsed_url['host'] = isset( $_SERVER['HTTP_HOST'] ) ? wp_unslash( $_SERVER['HTTP_HOST'] ) : 'localhost';
279316
}
280317

281-
$parsed_url['path'] = trailingslashit( $parsed_url['path'] );
282-
$parsed_url['path'] .= user_trailingslashit( amp_get_slug(), 'amp' );
318+
$has_existing_rewrite_endpoint = $this->is_added_rewrite_endpoint_in_path( $parsed_url['path'] );
319+
if ( ! $has_existing_rewrite_endpoint ) {
320+
$parsed_url['path'] = trailingslashit( $parsed_url['path'] );
321+
$parsed_url['path'] .= user_trailingslashit( amp_get_slug(), 'amp' );
322+
}
283323

284324
$amp_url = $parsed_url['scheme'] . '://';
285325
if ( isset( $parsed_url['user'] ) ) {
@@ -297,6 +337,9 @@ public function get_rewrite_endpoint_paired_amp_url( $url ) {
297337
if ( isset( $parsed_url['query'] ) ) {
298338
$amp_url .= '?' . $parsed_url['query'];
299339
}
340+
if ( $has_existing_rewrite_endpoint ) {
341+
$amp_url = $this->get_query_var_paired_amp_url( $amp_url );
342+
}
300343
if ( isset( $parsed_url['fragment'] ) ) {
301344
$amp_url .= '#' . $parsed_url['fragment'];
302345
}

0 commit comments

Comments
 (0)